MigrationGenerator almost ported

This commit is contained in:
Tobe O 2018-03-25 13:19:10 -04:00
parent 23f776c2f9
commit b57067cae4
5 changed files with 157 additions and 146 deletions

View file

@ -0,0 +1,5 @@
import 'package:code_builder/code_builder.dart';
final TypeReference $void = new TypeReference((b) => b.symbol = 'void');
final Expression override = new CodeExpression(new Code('override'));

View file

@ -2,17 +2,19 @@ import 'dart:async';
import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element.dart';
import 'package:angel_orm/angel_orm.dart'; import 'package:angel_orm/angel_orm.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:code_builder/dart/core.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:source_gen/source_gen.dart' hide LibraryBuilder; import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
import 'build_context.dart'; import 'build_context.dart';
import 'postgres_build_context.dart'; import 'postgres_build_context.dart';
import 'lib_core.dart' as lib$core;
class MigrationGenerator extends GeneratorForAnnotation<ORM> { class MigrationGenerator extends GeneratorForAnnotation<ORM> {
static final ParameterBuilder _schemaParam = parameter('schema', [ static final Parameter _schemaParam = new Parameter((b) {
new TypeBuilder('Schema'), b
]); ..name = 'schema'
static final ReferenceBuilder _schema = reference('schema'); ..type = new TypeReference((b) => b.symbol = 'Schema');
});
static final Expression _schema = new CodeExpression(new Code('schema'));
/// If `true` (default), then field names will automatically be (de)serialized as snake_case. /// If `true` (default), then field names will automatically be (de)serialized as snake_case.
final bool autoSnakeCaseNames; final bool autoSnakeCaseNames;
@ -37,27 +39,36 @@ class MigrationGenerator extends GeneratorForAnnotation<ORM> {
resolver, autoSnakeCaseNames != false, autoIdAndDateFields != false); resolver, autoSnakeCaseNames != false, autoIdAndDateFields != false);
var lib = generateMigrationLibrary(ctx, element, resolver, buildStep); var lib = generateMigrationLibrary(ctx, element, resolver, buildStep);
if (lib == null) return null; if (lib == null) return null;
return prettyToSource(lib.buildAst()); var emitter = new DartEmitter();
return lib.accept(emitter).toString();
} }
LibraryBuilder generateMigrationLibrary(PostgresBuildContext ctx, Library generateMigrationLibrary(PostgresBuildContext ctx,
ClassElement element, Resolver resolver, BuildStep buildStep) { ClassElement element, Resolver resolver, BuildStep buildStep) {
var lib = new LibraryBuilder() return new Library((lib) {
..addDirective( lib.directives.add([
new ImportBuilder('package:angel_migration/angel_migration.dart')); new Directive.import('package:angel_migration/angel_migration.dart'),
]);
var clazz = new ClassBuilder('${ctx.modelClassName}Migration', lib.body.add(new Class((b) {
asExtends: new TypeBuilder('Migration')); b.name = '${ctx.modelClassName}Migration';
clazz..addMethod(buildUpMigration(ctx, lib))..addMethod(buildDownMigration(ctx)); b.extend = new Reference('Migration');
}));
return lib..addMember(clazz); lib.methods.add(buildUpMigration(ctx, lib));
lib.methods.add(buildDownMigration(ctx));
});
} }
MethodBuilder buildUpMigration(PostgresBuildContext ctx, LibraryBuilder lib) { Method buildUpMigration(PostgresBuildContext ctx, LibraryBuilder lib) {
var meth = new MethodBuilder('up')..addPositional(_schemaParam); return new Method((meth) {
var closure = new MethodBuilder.closure() meth.name = 'up';
..addPositional(parameter('table')); meth.annotations.add(lib$core.override);
var table = reference('table'); meth.requiredParameters.add(_schemaParam);
var closure = new Method((closure) {
closure.requiredParameters.add(new Parameter((b) => b.name = 'table'));
var table = new Reference('table');
List<String> dup = []; List<String> dup = [];
bool hasOrmImport = false; bool hasOrmImport = false;
@ -79,8 +90,8 @@ class MigrationGenerator extends GeneratorForAnnotation<ORM> {
} }
String methodName; String methodName;
List<ExpressionBuilder> positional = [literal(key)]; List<Expression> positional = [literal(key)];
Map<String, ExpressionBuilder> named = {}; Map<String, Expression> named = {};
if (autoIdAndDateFields != false && name == 'id') methodName = 'serial'; if (autoIdAndDateFields != false && name == 'id') methodName = 'serial';
@ -117,26 +128,17 @@ class MigrationGenerator extends GeneratorForAnnotation<ORM> {
default: default:
if (!hasOrmImport) { if (!hasOrmImport) {
hasOrmImport = true; hasOrmImport = true;
lib.addDirective(new ImportBuilder('package:angel_orm/angel_orm.dart')); lib.directives.add(new Directive.import('package:angel_orm/angel_orm.dart'));
} }
ExpressionBuilder provColumn; Expression provColumn;
var colType = new TypeBuilder('Column');
var columnTypeType = new TypeBuilder('ColumnType');
if (col.length == null) { if (col.length == null) {
methodName = 'declare'; methodName = 'declare';
provColumn = columnTypeType.newInstance([ provColumn = new CodeExpression(new Code("new ColumnType('${col.type.name}')"));
literal(col.type.name),
]);
} else { } else {
methodName = 'declareColumn'; methodName = 'declareColumn';
provColumn = colType.newInstance([], named: { provColumn = new CodeExpression(new Code("new Column({type: new Column('${col.type.name}'), length: ${col.length})"));
'type': columnTypeType.newInstance([
literal(col.type.name),
]),
'length': literal(col.length),
});
} }
positional.add(provColumn); positional.add(provColumn);
@ -144,20 +146,21 @@ class MigrationGenerator extends GeneratorForAnnotation<ORM> {
} }
} }
var field = table.invoke(methodName, positional, namedArguments: named); var field = table.property(methodName).call(positional, named);
var cascade = <ExpressionBuilder Function(ExpressionBuilder)>[]; var cascade = <Expression Function(Expression)>[];
if (col.defaultValue != null) { if (col.defaultValue != null) {
cascade.add((e) => e.invoke('defaultsTo', [literal(col.defaultValue)])); cascade
.add((e) => e.property('defaultsTo').call([literal(col.defaultValue)]));
} }
if (col.index == IndexType.PRIMARY_KEY || if (col.index == IndexType.PRIMARY_KEY ||
(autoIdAndDateFields != false && name == 'id')) (autoIdAndDateFields != false && name == 'id'))
cascade.add((e) => e.invoke('primaryKey', [])); cascade.add((e) => e.property('primaryKey').call([]));
else if (col.index == IndexType.UNIQUE) else if (col.index == IndexType.UNIQUE)
cascade.add((e) => e.invoke('unique', [])); cascade.add((e) => e.property('unique').call([]));
if (col.nullable != true) cascade.add((e) => e.invoke('notNull', [])); if (col.nullable != true) cascade.add((e) => e.property('notNull').call([]));
field = cascade.isEmpty field = cascade.isEmpty
? field ? field
@ -171,31 +174,33 @@ class MigrationGenerator extends GeneratorForAnnotation<ORM> {
if (relationship.isBelongsTo) { if (relationship.isBelongsTo) {
var key = relationship.localKey; var key = relationship.localKey;
var field = table.invoke('integer', [literal(key)]); var field = table.property('integer').call([literal(key)]);
// .references('user', 'id').onDeleteCascade() // .references('user', 'id').onDeleteCascade()
var ref = field.invoke('references', [ var ref = field.property('references').call([
literal(relationship.foreignTable), literal(relationship.foreignTable),
literal(relationship.foreignKey), literal(relationship.foreignKey),
]); ]);
if (relationship.cascadeOnDelete != false && relationship.isSingular) if (relationship.cascadeOnDelete != false && relationship.isSingular)
ref = ref.invoke('onDeleteCascade', []); ref = ref.property('onDeleteCascade').call([]);
return closure.addStatement(ref); return closure.addStatement(ref);
} }
}); });
meth.addStatement(_schema.invoke('create', [ meth.addStatement(_schema.property('create').call([
literal(ctx.tableName), literal(ctx.tableName),
closure, closure,
])); ]));
return meth..addAnnotation(lib$core.override); });
});
} }
MethodBuilder buildDownMigration(PostgresBuildContext ctx) { Method buildDownMigration(PostgresBuildContext ctx) {
return method('down', [ return new Method((b) {
_schemaParam, b.name = 'down';
_schema.invoke('drop', [literal(ctx.tableName)]), b.requiredParameters.add(_schemaParam);
]) b.annotations.add(lib$core.override);
..addAnnotation(lib$core.override); b.body.add(new Code("schema.drop('${ctx.tableName}')"));
});
} }
} }

View file

@ -3,14 +3,13 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element.dart';
import 'package:angel_orm/angel_orm.dart'; import 'package:angel_orm/angel_orm.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:code_builder/dart/async.dart';
import 'package:code_builder/dart/core.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:inflection/inflection.dart'; import 'package:inflection/inflection.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';
import 'package:source_gen/source_gen.dart' hide LibraryBuilder; import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
import 'build_context.dart'; import 'build_context.dart';
import 'lib_core.dart' as lib$core;
import 'postgres_build_context.dart'; import 'postgres_build_context.dart';
const List<String> RELATIONS = const ['or']; const List<String> RELATIONS = const ['or'];

View file

@ -3,7 +3,6 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element.dart';
import 'package:angel_orm/angel_orm.dart'; import 'package:angel_orm/angel_orm.dart';
import 'package:build/build.dart'; import 'package:build/build.dart';
import 'package:code_builder/dart/core.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:recase/recase.dart'; import 'package:recase/recase.dart';

View file

@ -7,8 +7,8 @@ environment:
sdk: ">=1.19.0" sdk: ">=1.19.0"
dependencies: dependencies:
angel_orm: ^1.0.0-alpha angel_orm: ^1.0.0-alpha
angel_serialize_generator: ^1.0.0-alpha angel_serialize_generator: ^2.0.0
code_builder: ^1.0.0 code_builder: ^3.0.0
inflection: ^0.4.1 inflection: ^0.4.1
meta: ^1.0.0 meta: ^1.0.0
recase: ^1.0.0 recase: ^1.0.0
@ -17,5 +17,8 @@ dev_dependencies:
angel_framework: ^1.0.0 angel_framework: ^1.0.0
angel_migration: ^1.0.0-alpha angel_migration: ^1.0.0-alpha
angel_test: ^1.0.0 angel_test: ^1.0.0
build_runner: ^0.5.0 build_runner: ^0.7.0
test: ^0.12.0 test: ^0.12.0
dependency_overrides:
angel_orm:
path: ../angel_orm