Apply pedantic lints
This commit is contained in:
parent
9f22b0e3b4
commit
30914cc767
5 changed files with 159 additions and 142 deletions
|
@ -7,13 +7,13 @@ import 'package:angel_serialize/angel_serialize.dart';
|
||||||
part 'main.g.dart';
|
part 'main.g.dart';
|
||||||
|
|
||||||
main() async {
|
main() async {
|
||||||
var query = new EmployeeQuery()
|
var query = EmployeeQuery()
|
||||||
..where.firstName.equals('Rich')
|
..where.firstName.equals('Rich')
|
||||||
..where.lastName.equals('Person')
|
..where.lastName.equals('Person')
|
||||||
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
|
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
|
||||||
..join('companies', 'company_id', 'id');
|
..join('companies', 'company_id', 'id');
|
||||||
|
|
||||||
var richPerson = await query.getOne(new _FakeExecutor());
|
var richPerson = await query.getOne(_FakeExecutor());
|
||||||
print(richPerson.toJson());
|
print(richPerson.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class _FakeExecutor extends QueryExecutor {
|
||||||
Future<List<List>> query(
|
Future<List<List>> query(
|
||||||
String tableName, String query, Map<String, dynamic> substitutionValues,
|
String tableName, String query, Map<String, dynamic> substitutionValues,
|
||||||
[returningFields]) async {
|
[returningFields]) async {
|
||||||
var now = new DateTime.now();
|
var now = DateTime.now();
|
||||||
print(
|
print(
|
||||||
'_FakeExecutor received query: $query and values: $substitutionValues');
|
'_FakeExecutor received query: $query and values: $substitutionValues');
|
||||||
return [
|
return [
|
||||||
|
@ -34,7 +34,7 @@ class _FakeExecutor extends QueryExecutor {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) {
|
Future<T> transaction<T>(FutureOr<T> Function(QueryExecutor) f) {
|
||||||
throw new UnsupportedError('Transactions are not supported.');
|
throw UnsupportedError('Transactions are not supported.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,14 @@ import 'package:source_gen/source_gen.dart' hide LibraryBuilder;
|
||||||
import 'orm_build_context.dart';
|
import 'orm_build_context.dart';
|
||||||
|
|
||||||
Builder migrationBuilder(BuilderOptions options) {
|
Builder migrationBuilder(BuilderOptions options) {
|
||||||
return new SharedPartBuilder([
|
return SharedPartBuilder([
|
||||||
new MigrationGenerator(
|
MigrationGenerator(
|
||||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
||||||
], 'angel_migration');
|
], 'angel_migration');
|
||||||
}
|
}
|
||||||
|
|
||||||
class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
static final Parameter _schemaParam = new Parameter((b) => b
|
static final Parameter _schemaParam = Parameter((b) => b
|
||||||
..name = 'schema'
|
..name = 'schema'
|
||||||
..type = refer('Schema'));
|
..type = refer('Schema'));
|
||||||
static final Reference _schema = refer('schema');
|
static final Reference _schema = refer('schema');
|
||||||
|
@ -26,13 +26,14 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
/// 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;
|
||||||
|
|
||||||
const MigrationGenerator({this.autoSnakeCaseNames: true});
|
const MigrationGenerator({this.autoSnakeCaseNames = true});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String> generateForAnnotatedElement(
|
Future<String> generateForAnnotatedElement(
|
||||||
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
||||||
if (element is! ClassElement)
|
if (element is! ClassElement) {
|
||||||
throw 'Only classes can be annotated with @ORM().';
|
throw 'Only classes can be annotated with @ORM().';
|
||||||
|
}
|
||||||
|
|
||||||
var generateMigrations =
|
var generateMigrations =
|
||||||
annotation.peek('generateMigrations')?.boolValue ?? true;
|
annotation.peek('generateMigrations')?.boolValue ?? true;
|
||||||
|
@ -47,13 +48,13 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var lib = generateMigrationLibrary(
|
var lib = generateMigrationLibrary(
|
||||||
ctx, element as ClassElement, resolver, buildStep);
|
ctx, element as ClassElement, resolver, buildStep);
|
||||||
if (lib == null) return null;
|
if (lib == null) return null;
|
||||||
return new DartFormatter().format(lib.accept(new DartEmitter()).toString());
|
return DartFormatter().format(lib.accept(DartEmitter()).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Library generateMigrationLibrary(OrmBuildContext ctx, ClassElement element,
|
Library generateMigrationLibrary(OrmBuildContext ctx, ClassElement element,
|
||||||
Resolver resolver, BuildStep buildStep) {
|
Resolver resolver, BuildStep buildStep) {
|
||||||
return new Library((lib) {
|
return Library((lib) {
|
||||||
lib.body.add(new Class((clazz) {
|
lib.body.add(Class((clazz) {
|
||||||
clazz
|
clazz
|
||||||
..name = '${ctx.buildContext.modelClassName}Migration'
|
..name = '${ctx.buildContext.modelClassName}Migration'
|
||||||
..extend = refer('Migration')
|
..extend = refer('Migration')
|
||||||
|
@ -64,7 +65,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Method buildUpMigration(OrmBuildContext ctx, LibraryBuilder lib) {
|
Method buildUpMigration(OrmBuildContext ctx, LibraryBuilder lib) {
|
||||||
return new Method((meth) {
|
return Method((meth) {
|
||||||
var autoIdAndDateFields = const TypeChecker.fromRuntime(Model)
|
var autoIdAndDateFields = const TypeChecker.fromRuntime(Model)
|
||||||
.isAssignableFromType(ctx.buildContext.clazz.type);
|
.isAssignableFromType(ctx.buildContext.clazz.type);
|
||||||
meth
|
meth
|
||||||
|
@ -72,20 +73,20 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters.add(_schemaParam);
|
..requiredParameters.add(_schemaParam);
|
||||||
|
|
||||||
//var closure = new Method.closure()..addPositional(parameter('table'));
|
//var closure = Method.closure()..addPositional(parameter('table'));
|
||||||
var closure = new Method((closure) {
|
var closure = Method((closure) {
|
||||||
closure
|
closure
|
||||||
..requiredParameters.add(new Parameter((b) => b..name = 'table'))
|
..requiredParameters.add(Parameter((b) => b..name = 'table'))
|
||||||
..body = new Block((closureBody) {
|
..body = Block((closureBody) {
|
||||||
var table = refer('table');
|
var table = refer('table');
|
||||||
|
|
||||||
List<String> dup = [];
|
List<String> dup = [];
|
||||||
ctx.columns.forEach((name, col) {
|
ctx.columns.forEach((name, col) {
|
||||||
var key = ctx.buildContext.resolveFieldName(name);
|
var key = ctx.buildContext.resolveFieldName(name);
|
||||||
|
|
||||||
if (dup.contains(key))
|
if (dup.contains(key)) {
|
||||||
return;
|
return;
|
||||||
else {
|
} else {
|
||||||
// if (key != 'id' || autoIdAndDateFields == false) {
|
// if (key != 'id' || autoIdAndDateFields == false) {
|
||||||
// // Check for relationships that might duplicate
|
// // Check for relationships that might duplicate
|
||||||
// for (var rName in ctx.relations.keys) {
|
// for (var rName in ctx.relations.keys) {
|
||||||
|
@ -111,15 +112,17 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
List<Expression> positional = [literal(key)];
|
List<Expression> positional = [literal(key)];
|
||||||
Map<String, Expression> named = {};
|
Map<String, Expression> named = {};
|
||||||
|
|
||||||
if (autoIdAndDateFields != false && name == 'id')
|
if (autoIdAndDateFields != false && name == 'id') {
|
||||||
methodName = 'serial';
|
methodName = 'serial';
|
||||||
|
}
|
||||||
|
|
||||||
if (methodName == null) {
|
if (methodName == null) {
|
||||||
switch (col.type) {
|
switch (col.type) {
|
||||||
case ColumnType.varChar:
|
case ColumnType.varChar:
|
||||||
methodName = 'varChar';
|
methodName = 'varChar';
|
||||||
if (col.length != null)
|
if (col.length != null) {
|
||||||
named['length'] = literal(col.length);
|
named['length'] = literal(col.length);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ColumnType.serial:
|
case ColumnType.serial:
|
||||||
methodName = 'serial';
|
methodName = 'serial';
|
||||||
|
@ -196,13 +199,14 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
// Definitely an analyzer issue.
|
// Definitely an analyzer issue.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
defaultExpr = new CodeExpression(
|
defaultExpr = CodeExpression(
|
||||||
new Code(dartObjectToString(defaultValue)),
|
Code(dartObjectToString(defaultValue)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultExpr != null)
|
if (defaultExpr != null) {
|
||||||
cascade.add(refer('defaultsTo').call([defaultExpr]));
|
cascade.add(refer('defaultsTo').call([defaultExpr]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (col.indexType == IndexType.primaryKey ||
|
if (col.indexType == IndexType.primaryKey ||
|
||||||
|
@ -212,20 +216,20 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
cascade.add(refer('unique').call([]));
|
cascade.add(refer('unique').call([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (col.isNullable != true)
|
if (col.isNullable != true) {
|
||||||
cascade.add(refer('notNull').call([]));
|
cascade.add(refer('notNull').call([]));
|
||||||
|
}
|
||||||
|
|
||||||
if (cascade.isNotEmpty) {
|
if (cascade.isNotEmpty) {
|
||||||
var b = new StringBuffer()
|
var b = StringBuffer()..writeln(field.accept(DartEmitter()));
|
||||||
..writeln(field.accept(new DartEmitter()));
|
|
||||||
|
|
||||||
for (var ex in cascade) {
|
for (var ex in cascade) {
|
||||||
b
|
b
|
||||||
..write('..')
|
..write('..')
|
||||||
..writeln(ex.accept(new DartEmitter()));
|
..writeln(ex.accept(DartEmitter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
field = new CodeExpression(new Code(b.toString()));
|
field = CodeExpression(Code(b.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
closureBody.addExpression(field);
|
closureBody.addExpression(field);
|
||||||
|
@ -259,15 +263,16 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
|
|
||||||
if (relationship.cascadeOnDelete != false &&
|
if (relationship.cascadeOnDelete != false &&
|
||||||
const [RelationshipType.hasOne, RelationshipType.belongsTo]
|
const [RelationshipType.hasOne, RelationshipType.belongsTo]
|
||||||
.contains(relationship.type))
|
.contains(relationship.type)) {
|
||||||
ref = ref.property('onDeleteCascade').call([]);
|
ref = ref.property('onDeleteCascade').call([]);
|
||||||
|
}
|
||||||
closureBody.addExpression(ref);
|
closureBody.addExpression(ref);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
meth.body = new Block((b) {
|
meth.body = Block((b) {
|
||||||
b.addExpression(_schema.property('create').call([
|
b.addExpression(_schema.property('create').call([
|
||||||
literal(ctx.tableName),
|
literal(ctx.tableName),
|
||||||
closure.closure,
|
closure.closure,
|
||||||
|
@ -277,12 +282,12 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Method buildDownMigration(OrmBuildContext ctx) {
|
Method buildDownMigration(OrmBuildContext ctx) {
|
||||||
return new Method((b) {
|
return Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'down'
|
..name = 'down'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters.add(_schemaParam)
|
..requiredParameters.add(_schemaParam)
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
var named = <String, Expression>{};
|
var named = <String, Expression>{};
|
||||||
|
|
||||||
if (ctx.relations.values.any((r) =>
|
if (ctx.relations.values.any((r) =>
|
||||||
|
|
|
@ -43,7 +43,7 @@ FieldElement findPrimaryFieldInList(
|
||||||
var columnAnnotation = columnTypeChecker.firstAnnotationOf(element);
|
var columnAnnotation = columnTypeChecker.firstAnnotationOf(element);
|
||||||
|
|
||||||
if (columnAnnotation != null) {
|
if (columnAnnotation != null) {
|
||||||
var column = reviveColumn(new ConstantReader(columnAnnotation));
|
var column = reviveColumn(ConstantReader(columnAnnotation));
|
||||||
// print(
|
// print(
|
||||||
// ' * Found column on ${field.name} with indexType = ${column.indexType}');
|
// ' * Found column on ${field.name} with indexType = ${column.indexType}');
|
||||||
// print(element.metadata);
|
// print(element.metadata);
|
||||||
|
@ -66,7 +66,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
BuildStep buildStep,
|
BuildStep buildStep,
|
||||||
Resolver resolver,
|
Resolver resolver,
|
||||||
bool autoSnakeCaseNames,
|
bool autoSnakeCaseNames,
|
||||||
{bool heedExclude: true}) async {
|
{bool heedExclude = true}) async {
|
||||||
// Check for @generatedSerializable
|
// Check for @generatedSerializable
|
||||||
// ignore: unused_local_variable
|
// ignore: unused_local_variable
|
||||||
DartObject generatedSerializable;
|
DartObject generatedSerializable;
|
||||||
|
@ -88,12 +88,12 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
var ormAnnotation = reviveORMAnnotation(annotation);
|
var ormAnnotation = reviveORMAnnotation(annotation);
|
||||||
// print(
|
// print(
|
||||||
// 'tableName (${annotation.objectValue.type.name}) => ${ormAnnotation.tableName} from ${clazz.name} (${annotation.revive().namedArguments})');
|
// 'tableName (${annotation.objectValue.type.name}) => ${ormAnnotation.tableName} from ${clazz.name} (${annotation.revive().namedArguments})');
|
||||||
var ctx = new OrmBuildContext(
|
var ctx = OrmBuildContext(
|
||||||
buildCtx,
|
buildCtx,
|
||||||
ormAnnotation,
|
ormAnnotation,
|
||||||
(ormAnnotation.tableName?.isNotEmpty == true)
|
(ormAnnotation.tableName?.isNotEmpty == true)
|
||||||
? ormAnnotation.tableName
|
? ormAnnotation.tableName
|
||||||
: pluralize(new ReCase(clazz.name).snakeCase));
|
: pluralize(ReCase(clazz.name).snakeCase));
|
||||||
_cache[id] = ctx;
|
_cache[id] = ctx;
|
||||||
|
|
||||||
// Read all fields
|
// Read all fields
|
||||||
|
@ -105,7 +105,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
// print('${element.name} => $columnAnnotation');
|
// print('${element.name} => $columnAnnotation');
|
||||||
|
|
||||||
if (columnAnnotation != null) {
|
if (columnAnnotation != null) {
|
||||||
column = reviveColumn(new ConstantReader(columnAnnotation));
|
column = reviveColumn(ConstantReader(columnAnnotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column == null && isSpecialId(ctx, field)) {
|
if (column == null && isSpecialId(ctx, field)) {
|
||||||
|
@ -117,7 +117,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
|
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
// Guess what kind of column this is...
|
// Guess what kind of column this is...
|
||||||
column = new Column(
|
column = Column(
|
||||||
type: inferColumnType(
|
type: inferColumnType(
|
||||||
buildCtx.resolveSerializedFieldType(field.name),
|
buildCtx.resolveSerializedFieldType(field.name),
|
||||||
),
|
),
|
||||||
|
@ -125,7 +125,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column != null && column.type == null) {
|
if (column != null && column.type == null) {
|
||||||
column = new Column(
|
column = Column(
|
||||||
isNullable: column.isNullable,
|
isNullable: column.isNullable,
|
||||||
length: column.length,
|
length: column.length,
|
||||||
indexType: column.indexType,
|
indexType: column.indexType,
|
||||||
|
@ -139,7 +139,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
var ann = relationshipTypeChecker.firstAnnotationOf(el);
|
var ann = relationshipTypeChecker.firstAnnotationOf(el);
|
||||||
|
|
||||||
if (ann != null) {
|
if (ann != null) {
|
||||||
var cr = new ConstantReader(ann);
|
var cr = ConstantReader(ann);
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
var type = cr.read('type').intValue;
|
var type = cr.read('type').intValue;
|
||||||
var localKey = cr.peek('localKey')?.stringValue;
|
var localKey = cr.peek('localKey')?.stringValue;
|
||||||
|
@ -157,7 +157,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
isListOfModelType(field.type as InterfaceType)) ||
|
isListOfModelType(field.type as InterfaceType)) ||
|
||||||
isModelClass(field.type);
|
isModelClass(field.type);
|
||||||
if (!canUse) {
|
if (!canUse) {
|
||||||
throw new UnsupportedError(
|
throw UnsupportedError(
|
||||||
'Cannot apply relationship to field "${field.name}" - ${field.type} is not assignable to Model.');
|
'Cannot apply relationship to field "${field.name}" - ${field.type} is not assignable to Model.');
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -174,7 +174,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
|
|
||||||
foreign = await buildOrmContext(
|
foreign = await buildOrmContext(
|
||||||
modelType.element as ClassElement,
|
modelType.element as ClassElement,
|
||||||
new ConstantReader(const TypeChecker.fromRuntime(Orm)
|
ConstantReader(const TypeChecker.fromRuntime(Orm)
|
||||||
.firstAnnotationOf(modelType.element)),
|
.firstAnnotationOf(modelType.element)),
|
||||||
buildStep,
|
buildStep,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -184,7 +184,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
if (through != null && through is InterfaceType) {
|
if (through != null && through is InterfaceType) {
|
||||||
throughContext = await buildOrmContext(
|
throughContext = await buildOrmContext(
|
||||||
through.element,
|
through.element,
|
||||||
new ConstantReader(const TypeChecker.fromRuntime(Serializable)
|
ConstantReader(const TypeChecker.fromRuntime(Serializable)
|
||||||
.firstAnnotationOf(modelType.element)),
|
.firstAnnotationOf(modelType.element)),
|
||||||
buildStep,
|
buildStep,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -196,20 +196,20 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
|
|
||||||
if (ormAnn != null) {
|
if (ormAnn != null) {
|
||||||
foreignTable =
|
foreignTable =
|
||||||
new ConstantReader(ormAnn).peek('tableName')?.stringValue;
|
ConstantReader(ormAnn).peek('tableName')?.stringValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreignTable ??=
|
foreignTable ??=
|
||||||
pluralize(foreign.buildContext.modelClassNameRecase.snakeCase);
|
pluralize(foreign.buildContext.modelClassNameRecase.snakeCase);
|
||||||
} on StackOverflowError {
|
} on StackOverflowError {
|
||||||
throw new UnsupportedError(
|
throw UnsupportedError(
|
||||||
'There is an infinite cycle between ${clazz.name} and ${field.type.name}. This triggered a stack overflow.');
|
'There is an infinite cycle between ${clazz.name} and ${field.type.name}. This triggered a stack overflow.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in missing keys
|
// Fill in missing keys
|
||||||
var rcc = new ReCase(field.name);
|
var rcc = ReCase(field.name);
|
||||||
|
|
||||||
String keyName(OrmBuildContext ctx, String missing) {
|
String keyName(OrmBuildContext ctx, String missing) {
|
||||||
var _keyName =
|
var _keyName =
|
||||||
|
@ -236,7 +236,7 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
localKey ??= '${rcc.snakeCase}_$foreignKey';
|
localKey ??= '${rcc.snakeCase}_$foreignKey';
|
||||||
}
|
}
|
||||||
|
|
||||||
var relation = new RelationshipReader(
|
var relation = RelationshipReader(
|
||||||
type,
|
type,
|
||||||
localKey: localKey,
|
localKey: localKey,
|
||||||
foreignKey: foreignKey,
|
foreignKey: foreignKey,
|
||||||
|
@ -251,28 +251,31 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
// 'foreignKey=$foreignKey, localKey=$localKey');
|
// 'foreignKey=$foreignKey, localKey=$localKey');
|
||||||
|
|
||||||
if (relation.type == RelationshipType.belongsTo) {
|
if (relation.type == RelationshipType.belongsTo) {
|
||||||
var name = new ReCase(relation.localKey).camelCase;
|
var name = ReCase(relation.localKey).camelCase;
|
||||||
ctx.buildContext.aliases[name] = relation.localKey;
|
ctx.buildContext.aliases[name] = relation.localKey;
|
||||||
|
|
||||||
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
||||||
var foreignField = relation.findForeignField(ctx);
|
var foreignField = relation.findForeignField(ctx);
|
||||||
var foreign = relation.throughContext ?? relation.foreign;
|
var foreign = relation.throughContext ?? relation.foreign;
|
||||||
var type = foreignField.type;
|
var type = foreignField.type;
|
||||||
if (isSpecialId(foreign, foreignField))
|
if (isSpecialId(foreign, foreignField)) {
|
||||||
type = field.type.element.context.typeProvider.intType;
|
type = field.type.element.context.typeProvider.intType;
|
||||||
var rf = new RelationFieldImpl(name, relation, type, field);
|
}
|
||||||
|
var rf = RelationFieldImpl(name, relation, type, field);
|
||||||
ctx.effectiveFields.add(rf);
|
ctx.effectiveFields.add(rf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.relations[field.name] = relation;
|
ctx.relations[field.name] = relation;
|
||||||
} else {
|
} else {
|
||||||
if (column?.type == null)
|
if (column?.type == null) {
|
||||||
throw 'Cannot infer SQL column type for field "${ctx.buildContext.originalClassName}.${field.name}" with type "${field.type.displayName}".';
|
throw 'Cannot infer SQL column type for field "${ctx.buildContext.originalClassName}.${field.name}" with type "${field.type.displayName}".';
|
||||||
|
}
|
||||||
ctx.columns[field.name] = column;
|
ctx.columns[field.name] = column;
|
||||||
|
|
||||||
if (!ctx.effectiveFields.any((f) => f.name == field.name))
|
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
||||||
ctx.effectiveFields.add(field);
|
ctx.effectiveFields.add(field);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,22 +283,30 @@ Future<OrmBuildContext> buildOrmContext(
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnType inferColumnType(DartType type) {
|
ColumnType inferColumnType(DartType type) {
|
||||||
if (const TypeChecker.fromRuntime(String).isAssignableFromType(type))
|
if (const TypeChecker.fromRuntime(String).isAssignableFromType(type)) {
|
||||||
return ColumnType.varChar;
|
return ColumnType.varChar;
|
||||||
if (const TypeChecker.fromRuntime(int).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(int).isAssignableFromType(type)) {
|
||||||
return ColumnType.int;
|
return ColumnType.int;
|
||||||
if (const TypeChecker.fromRuntime(double).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(double).isAssignableFromType(type)) {
|
||||||
return ColumnType.decimal;
|
return ColumnType.decimal;
|
||||||
if (const TypeChecker.fromRuntime(num).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(num).isAssignableFromType(type)) {
|
||||||
return ColumnType.numeric;
|
return ColumnType.numeric;
|
||||||
if (const TypeChecker.fromRuntime(bool).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(bool).isAssignableFromType(type)) {
|
||||||
return ColumnType.boolean;
|
return ColumnType.boolean;
|
||||||
if (const TypeChecker.fromRuntime(DateTime).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(DateTime).isAssignableFromType(type)) {
|
||||||
return ColumnType.timeStamp;
|
return ColumnType.timeStamp;
|
||||||
if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(Map).isAssignableFromType(type)) {
|
||||||
return ColumnType.jsonb;
|
return ColumnType.jsonb;
|
||||||
if (const TypeChecker.fromRuntime(List).isAssignableFromType(type))
|
}
|
||||||
|
if (const TypeChecker.fromRuntime(List).isAssignableFromType(type)) {
|
||||||
return ColumnType.jsonb;
|
return ColumnType.jsonb;
|
||||||
|
}
|
||||||
if (type is InterfaceType && type.element.isEnum) return ColumnType.int;
|
if (type is InterfaceType && type.element.isEnum) return ColumnType.int;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -317,10 +328,10 @@ Column reviveColumn(ConstantReader cr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (columnObj != null) {
|
if (columnObj != null) {
|
||||||
columnType = new _ColumnType(columnObj);
|
columnType = _ColumnType(columnObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Column(
|
return Column(
|
||||||
isNullable: cr.peek('isNullable')?.boolValue,
|
isNullable: cr.peek('isNullable')?.boolValue,
|
||||||
length: cr.peek('length')?.intValue,
|
length: cr.peek('length')?.intValue,
|
||||||
type: columnType,
|
type: columnType,
|
||||||
|
@ -329,7 +340,7 @@ Column reviveColumn(ConstantReader cr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const TypeChecker relationshipTypeChecker =
|
const TypeChecker relationshipTypeChecker =
|
||||||
const TypeChecker.fromRuntime(Relationship);
|
TypeChecker.fromRuntime(Relationship);
|
||||||
|
|
||||||
class OrmBuildContext {
|
class OrmBuildContext {
|
||||||
final BuildContext buildContext;
|
final BuildContext buildContext;
|
||||||
|
|
|
@ -17,14 +17,14 @@ var floatTypes = [
|
||||||
];
|
];
|
||||||
|
|
||||||
Builder ormBuilder(BuilderOptions options) {
|
Builder ormBuilder(BuilderOptions options) {
|
||||||
return new SharedPartBuilder([
|
return SharedPartBuilder([
|
||||||
new OrmGenerator(
|
OrmGenerator(
|
||||||
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
autoSnakeCaseNames: options.config['auto_snake_case_names'] != false)
|
||||||
], 'angel_orm');
|
], 'angel_orm');
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeReference futureOf(String type) {
|
TypeReference futureOf(String type) {
|
||||||
return new TypeReference((b) => b
|
return TypeReference((b) => b
|
||||||
..symbol = 'Future'
|
..symbol = 'Future'
|
||||||
..types.add(refer(type)));
|
..types.add(refer(type)));
|
||||||
}
|
}
|
||||||
|
@ -42,14 +42,14 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var ctx = await buildOrmContext(element, annotation, buildStep,
|
var ctx = await buildOrmContext(element, annotation, buildStep,
|
||||||
buildStep.resolver, autoSnakeCaseNames);
|
buildStep.resolver, autoSnakeCaseNames);
|
||||||
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
var lib = buildOrmLibrary(buildStep.inputId, ctx);
|
||||||
return lib.accept(new DartEmitter()).toString();
|
return lib.accept(DartEmitter()).toString();
|
||||||
} else {
|
} else {
|
||||||
throw 'The @Orm() annotation can only be applied to classes.';
|
throw 'The @Orm() annotation can only be applied to classes.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
||||||
return new Library((lib) {
|
return Library((lib) {
|
||||||
// Create `FooQuery` class
|
// Create `FooQuery` class
|
||||||
// Create `FooQueryWhere` class
|
// Create `FooQueryWhere` class
|
||||||
lib.body.add(buildQueryClass(ctx));
|
lib.body.add(buildQueryClass(ctx));
|
||||||
|
@ -59,12 +59,12 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Class buildQueryClass(OrmBuildContext ctx) {
|
Class buildQueryClass(OrmBuildContext ctx) {
|
||||||
return new Class((clazz) {
|
return Class((clazz) {
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
var queryWhereType = refer('${rc.pascalCase}QueryWhere');
|
var queryWhereType = refer('${rc.pascalCase}QueryWhere');
|
||||||
clazz
|
clazz
|
||||||
..name = '${rc.pascalCase}Query'
|
..name = '${rc.pascalCase}Query'
|
||||||
..extend = new TypeReference((b) {
|
..extend = TypeReference((b) {
|
||||||
b
|
b
|
||||||
..symbol = 'Query'
|
..symbol = 'Query'
|
||||||
..types.addAll([
|
..types.addAll([
|
||||||
|
@ -96,7 +96,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add values
|
// Add values
|
||||||
clazz.fields.add(new Field((b) {
|
clazz.fields.add(Field((b) {
|
||||||
var type = refer('${rc.pascalCase}QueryValues');
|
var type = refer('${rc.pascalCase}QueryValues');
|
||||||
b
|
b
|
||||||
..name = 'values'
|
..name = 'values'
|
||||||
|
@ -107,23 +107,23 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add tableName
|
// Add tableName
|
||||||
clazz.methods.add(new Method((m) {
|
clazz.methods.add(Method((m) {
|
||||||
m
|
m
|
||||||
..name = 'tableName'
|
..name = 'tableName'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..type = MethodType.getter
|
..type = MethodType.getter
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
b.addExpression(literalString(ctx.tableName).returned);
|
b.addExpression(literalString(ctx.tableName).returned);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add fields getter
|
// Add fields getter
|
||||||
clazz.methods.add(new Method((m) {
|
clazz.methods.add(Method((m) {
|
||||||
m
|
m
|
||||||
..name = 'fields'
|
..name = 'fields'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..type = MethodType.getter
|
..type = MethodType.getter
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
var names = ctx.effectiveFields
|
var names = ctx.effectiveFields
|
||||||
.map((f) =>
|
.map((f) =>
|
||||||
literalString(ctx.buildContext.resolveFieldName(f.name)))
|
literalString(ctx.buildContext.resolveFieldName(f.name)))
|
||||||
|
@ -133,41 +133,41 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add _where member
|
// Add _where member
|
||||||
clazz.fields.add(new Field((b) {
|
clazz.fields.add(Field((b) {
|
||||||
b
|
b
|
||||||
..name = '_where'
|
..name = '_where'
|
||||||
..type = queryWhereType;
|
..type = queryWhereType;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add where getter
|
// Add where getter
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'where'
|
..name = 'where'
|
||||||
..type = MethodType.getter
|
..type = MethodType.getter
|
||||||
..returns = queryWhereType
|
..returns = queryWhereType
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..body = new Block((b) => b.addExpression(refer('_where').returned));
|
..body = Block((b) => b.addExpression(refer('_where').returned));
|
||||||
}));
|
}));
|
||||||
// newWhereClause()
|
// newWhereClause()
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'newWhereClause'
|
..name = 'newWhereClause'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..returns = queryWhereType
|
..returns = queryWhereType
|
||||||
..body = new Block((b) => b.addExpression(
|
..body = Block((b) => b.addExpression(
|
||||||
queryWhereType.newInstance([refer('this')]).returned));
|
queryWhereType.newInstance([refer('this')]).returned));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add deserialize()
|
// Add deserialize()
|
||||||
clazz.methods.add(new Method((m) {
|
clazz.methods.add(Method((m) {
|
||||||
m
|
m
|
||||||
..name = 'parseRow'
|
..name = 'parseRow'
|
||||||
..static = true
|
..static = true
|
||||||
..returns = ctx.buildContext.modelClassType
|
..returns = ctx.buildContext.modelClassType
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'row'
|
..name = 'row'
|
||||||
..type = refer('List')))
|
..type = refer('List')))
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
var args = <String, Expression>{};
|
var args = <String, Expression>{};
|
||||||
|
|
||||||
|
@ -177,11 +177,11 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
if (isSpecialId(ctx, field)) type = refer('int');
|
if (isSpecialId(ctx, field)) type = refer('int');
|
||||||
|
|
||||||
var expr = (refer('row').index(literalNum(i++)));
|
var expr = (refer('row').index(literalNum(i++)));
|
||||||
if (isSpecialId(ctx, field))
|
if (isSpecialId(ctx, field)) {
|
||||||
expr = expr.property('toString').call([]);
|
expr = expr.property('toString').call([]);
|
||||||
else if (field is RelationFieldImpl)
|
} else if (field is RelationFieldImpl) {
|
||||||
continue;
|
continue;
|
||||||
else if (ctx.columns[field.name]?.type == ColumnType.json) {
|
} else if (ctx.columns[field.name]?.type == ColumnType.json) {
|
||||||
expr = refer('json')
|
expr = refer('json')
|
||||||
.property('decode')
|
.property('decode')
|
||||||
.call([expr.asA(refer('String'))]).asA(type);
|
.call([expr.asA(refer('String'))]).asA(type);
|
||||||
|
@ -193,14 +193,15 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var isNull = expr.equalTo(literalNull);
|
var isNull = expr.equalTo(literalNull);
|
||||||
expr = isNull.conditional(literalNull,
|
expr = isNull.conditional(literalNull,
|
||||||
type.property('values').index(expr.asA(refer('int'))));
|
type.property('values').index(expr.asA(refer('int'))));
|
||||||
} else
|
} else {
|
||||||
expr = expr.asA(type);
|
expr = expr.asA(type);
|
||||||
|
}
|
||||||
|
|
||||||
args[field.name] = expr;
|
args[field.name] = expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.statements
|
b.statements
|
||||||
.add(new Code('if (row.every((x) => x == null)) return null;'));
|
.add(Code('if (row.every((x) => x == null)) return null;'));
|
||||||
b.addExpression(ctx.buildContext.modelClassType
|
b.addExpression(ctx.buildContext.modelClassType
|
||||||
.newInstance([], args).assignVar('model'));
|
.newInstance([], args).assignVar('model'));
|
||||||
|
|
||||||
|
@ -230,11 +231,11 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
var expr =
|
var expr =
|
||||||
refer('model').property('copyWith').call([], {name: parsed});
|
refer('model').property('copyWith').call([], {name: parsed});
|
||||||
var block = new Block(
|
var block =
|
||||||
(b) => b.addExpression(refer('model').assign(expr)));
|
Block((b) => b.addExpression(refer('model').assign(expr)));
|
||||||
var blockStr = block.accept(new DartEmitter());
|
var blockStr = block.accept(DartEmitter());
|
||||||
var ifStr = 'if (row.length > $i) { $blockStr }';
|
var ifStr = 'if (row.length > $i) { $blockStr }';
|
||||||
b.statements.add(new Code(ifStr));
|
b.statements.add(Code(ifStr));
|
||||||
i += relation.foreign.effectiveFields.length;
|
i += relation.foreign.effectiveFields.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -242,20 +243,20 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
clazz.methods.add(new Method((m) {
|
clazz.methods.add(Method((m) {
|
||||||
m
|
m
|
||||||
..name = 'deserialize'
|
..name = 'deserialize'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'row'
|
..name = 'row'
|
||||||
..type = refer('List')))
|
..type = refer('List')))
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
b.addExpression(refer('parseRow').call([refer('row')]).returned);
|
b.addExpression(refer('parseRow').call([refer('row')]).returned);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// If there are any relations, we need some overrides.
|
// If there are any relations, we need some overrides.
|
||||||
clazz.constructors.add(new Constructor((b) {
|
clazz.constructors.add(Constructor((b) {
|
||||||
b
|
b
|
||||||
..optionalParameters.add(Parameter((b) => b
|
..optionalParameters.add(Parameter((b) => b
|
||||||
..named = true
|
..named = true
|
||||||
|
@ -263,7 +264,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
..type = TypeReference((b) => b
|
..type = TypeReference((b) => b
|
||||||
..symbol = 'Set'
|
..symbol = 'Set'
|
||||||
..types.add(refer('String')))))
|
..types.add(refer('String')))))
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
b.statements.addAll([
|
b.statements.addAll([
|
||||||
Code('trampoline ??= Set();'),
|
Code('trampoline ??= Set();'),
|
||||||
Code('trampoline.add(tableName);'),
|
Code('trampoline.add(tableName);'),
|
||||||
|
@ -331,12 +332,11 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
});
|
});
|
||||||
var out = outExprs.reduce((a, b) => a.and(b));
|
var out = outExprs.reduce((a, b) => a.and(b));
|
||||||
|
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'canCompile'
|
..name = 'canCompile'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters
|
..requiredParameters.add(Parameter((b) => b..name = 'trampoline'))
|
||||||
.add(new Parameter((b) => b..name = 'trampoline'))
|
|
||||||
..returns = refer('bool')
|
..returns = refer('bool')
|
||||||
..body = Block((b) {
|
..body = Block((b) {
|
||||||
b.addExpression(out.returned);
|
b.addExpression(out.returned);
|
||||||
|
@ -346,16 +346,16 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
|
|
||||||
// TODO: Ultimately remove the insert override
|
// TODO: Ultimately remove the insert override
|
||||||
if (false && ctx.relations.isNotEmpty) {
|
if (false && ctx.relations.isNotEmpty) {
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'insert'
|
..name = 'insert'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters.add(new Parameter((b) => b..name = 'executor'))
|
..requiredParameters.add(Parameter((b) => b..name = 'executor'))
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
var inTransaction = new Method((b) {
|
var inTransaction = Method((b) {
|
||||||
b
|
b
|
||||||
..modifier = MethodModifier.async
|
..modifier = MethodModifier.async
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
b.addExpression(refer('super')
|
b.addExpression(refer('super')
|
||||||
.property('insert')
|
.property('insert')
|
||||||
.call([refer('executor')])
|
.call([refer('executor')])
|
||||||
|
@ -404,24 +404,24 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
// Create a Future<T> fetchLinked(T model, QueryExecutor), if necessary.
|
// Create a Future<T> fetchLinked(T model, QueryExecutor), if necessary.
|
||||||
if (false &&
|
if (false &&
|
||||||
ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'fetchLinked'
|
..name = 'fetchLinked'
|
||||||
..modifier = MethodModifier.async
|
..modifier = MethodModifier.async
|
||||||
..returns = new TypeReference((b) {
|
..returns = TypeReference((b) {
|
||||||
b
|
b
|
||||||
..symbol = 'Future'
|
..symbol = 'Future'
|
||||||
..types.add(ctx.buildContext.modelClassType);
|
..types.add(ctx.buildContext.modelClassType);
|
||||||
})
|
})
|
||||||
..requiredParameters.addAll([
|
..requiredParameters.addAll([
|
||||||
new Parameter((b) => b
|
Parameter((b) => b
|
||||||
..name = 'model'
|
..name = 'model'
|
||||||
..type = ctx.buildContext.modelClassType),
|
..type = ctx.buildContext.modelClassType),
|
||||||
new Parameter((b) => b
|
Parameter((b) => b
|
||||||
..name = 'executor'
|
..name = 'executor'
|
||||||
..type = refer('QueryExecutor')),
|
..type = refer('QueryExecutor')),
|
||||||
])
|
])
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
var args = <String, Expression>{};
|
var args = <String, Expression>{};
|
||||||
|
|
||||||
ctx.relations.forEach((name, relation) {
|
ctx.relations.forEach((name, relation) {
|
||||||
|
@ -443,9 +443,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
: 'model.${localField.name}';
|
: 'model.${localField.name}';
|
||||||
var cascadeText =
|
var cascadeText =
|
||||||
'..where.${foreignField.name}.equals($queryValue)';
|
'..where.${foreignField.name}.equals($queryValue)';
|
||||||
var queryText = queryInstance.accept(new DartEmitter());
|
var queryText = queryInstance.accept(DartEmitter());
|
||||||
var combinedExpr =
|
var combinedExpr =
|
||||||
new CodeExpression(new Code('($queryText$cascadeText)'));
|
CodeExpression(Code('($queryText$cascadeText)'));
|
||||||
|
|
||||||
// Finally, just call get and await it.
|
// Finally, just call get and await it.
|
||||||
var expr = combinedExpr
|
var expr = combinedExpr
|
||||||
|
@ -466,12 +466,12 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
// execute in a transaction, and invoke fetchLinked.
|
// execute in a transaction, and invoke fetchLinked.
|
||||||
if (ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
if (ctx.relations.values.any((r) => r.type == RelationshipType.hasMany)) {
|
||||||
for (var methodName in const ['get', 'update', 'delete']) {
|
for (var methodName in const ['get', 'update', 'delete']) {
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
var type = ctx.buildContext.modelClassType.accept(DartEmitter());
|
var type = ctx.buildContext.modelClassType.accept(DartEmitter());
|
||||||
b
|
b
|
||||||
..name = methodName
|
..name = methodName
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'executor'
|
..name = 'executor'
|
||||||
..type = refer('QueryExecutor')));
|
..type = refer('QueryExecutor')));
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
'@HasMany and @ManyToMany relations require a primary key to be defined on the model.';
|
'@HasMany and @ManyToMany relations require a primary key to be defined on the model.';
|
||||||
}
|
}
|
||||||
|
|
||||||
b.body = new Code('''
|
b.body = Code('''
|
||||||
return super.$methodName(executor).then((result) {
|
return super.$methodName(executor).then((result) {
|
||||||
return result.fold<List<$type>>([], (out, model) {
|
return result.fold<List<$type>>([], (out, model) {
|
||||||
var idx = out.indexWhere((m) => m.$keyName == model.$keyName);
|
var idx = out.indexWhere((m) => m.$keyName == model.$keyName);
|
||||||
|
@ -521,19 +521,19 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Class buildWhereClass(OrmBuildContext ctx) {
|
Class buildWhereClass(OrmBuildContext ctx) {
|
||||||
return new Class((clazz) {
|
return Class((clazz) {
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
clazz
|
clazz
|
||||||
..name = '${rc.pascalCase}QueryWhere'
|
..name = '${rc.pascalCase}QueryWhere'
|
||||||
..extend = refer('QueryWhere');
|
..extend = refer('QueryWhere');
|
||||||
|
|
||||||
// Build expressionBuilders getter
|
// Build expressionBuilders getter
|
||||||
clazz.methods.add(new Method((m) {
|
clazz.methods.add(Method((m) {
|
||||||
m
|
m
|
||||||
..name = 'expressionBuilders'
|
..name = 'expressionBuilders'
|
||||||
..annotations.add(refer('override'))
|
..annotations.add(refer('override'))
|
||||||
..type = MethodType.getter
|
..type = MethodType.getter
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
var references = ctx.effectiveFields.map((f) => refer(f.name));
|
var references = ctx.effectiveFields.map((f) => refer(f.name));
|
||||||
b.addExpression(literalList(references).returned);
|
b.addExpression(literalList(references).returned);
|
||||||
});
|
});
|
||||||
|
@ -557,11 +557,11 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
if (const TypeChecker.fromRuntime(int).isExactlyType(type) ||
|
if (const TypeChecker.fromRuntime(int).isExactlyType(type) ||
|
||||||
const TypeChecker.fromRuntime(double).isExactlyType(type) ||
|
const TypeChecker.fromRuntime(double).isExactlyType(type) ||
|
||||||
isSpecialId(ctx, field)) {
|
isSpecialId(ctx, field)) {
|
||||||
builderType = new TypeReference((b) => b
|
builderType = TypeReference((b) => b
|
||||||
..symbol = 'NumericSqlExpressionBuilder'
|
..symbol = 'NumericSqlExpressionBuilder'
|
||||||
..types.add(refer(isSpecialId(ctx, field) ? 'int' : type.name)));
|
..types.add(refer(isSpecialId(ctx, field) ? 'int' : type.name)));
|
||||||
} else if (type is InterfaceType && type.element.isEnum) {
|
} else if (type is InterfaceType && type.element.isEnum) {
|
||||||
builderType = new TypeReference((b) => b
|
builderType = TypeReference((b) => b
|
||||||
..symbol = 'EnumSqlExpressionBuilder'
|
..symbol = 'EnumSqlExpressionBuilder'
|
||||||
..types.add(convertTypeReference(type)));
|
..types.add(convertTypeReference(type)));
|
||||||
args.add(CodeExpression(Code('(v) => v.index')));
|
args.add(CodeExpression(Code('(v) => v.index')));
|
||||||
|
@ -580,20 +580,20 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
builderType = refer('ListSqlExpressionBuilder');
|
builderType = refer('ListSqlExpressionBuilder');
|
||||||
} else if (ctx.relations.containsKey(field.name)) {
|
} else if (ctx.relations.containsKey(field.name)) {
|
||||||
var relation = ctx.relations[field.name];
|
var relation = ctx.relations[field.name];
|
||||||
if (relation.type != RelationshipType.belongsTo)
|
if (relation.type != RelationshipType.belongsTo) {
|
||||||
continue;
|
continue;
|
||||||
else {
|
} else {
|
||||||
builderType = new TypeReference((b) => b
|
builderType = TypeReference((b) => b
|
||||||
..symbol = 'NumericSqlExpressionBuilder'
|
..symbol = 'NumericSqlExpressionBuilder'
|
||||||
..types.add(refer('int')));
|
..types.add(refer('int')));
|
||||||
name = relation.localKey;
|
name = relation.localKey;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedError(
|
throw UnsupportedError(
|
||||||
'Cannot generate ORM code for field of type ${field.type.name}.');
|
'Cannot generate ORM code for field of type ${field.type.name}.');
|
||||||
}
|
}
|
||||||
|
|
||||||
clazz.fields.add(new Field((b) {
|
clazz.fields.add(Field((b) {
|
||||||
b
|
b
|
||||||
..name = name
|
..name = name
|
||||||
..modifier = FieldModifier.final$
|
..modifier = FieldModifier.final$
|
||||||
|
@ -611,9 +611,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, just add a constructor that initializes each builder.
|
// Now, just add a constructor that initializes each builder.
|
||||||
clazz.constructors.add(new Constructor((b) {
|
clazz.constructors.add(Constructor((b) {
|
||||||
b
|
b
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'query'
|
..name = 'query'
|
||||||
..type = refer('${rc.pascalCase}Query')))
|
..type = refer('${rc.pascalCase}Query')))
|
||||||
..initializers.addAll(initializers);
|
..initializers.addAll(initializers);
|
||||||
|
@ -622,7 +622,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Class buildValuesClass(OrmBuildContext ctx) {
|
Class buildValuesClass(OrmBuildContext ctx) {
|
||||||
return new Class((clazz) {
|
return Class((clazz) {
|
||||||
var rc = ctx.buildContext.modelClassNameRecase;
|
var rc = ctx.buildContext.modelClassNameRecase;
|
||||||
clazz
|
clazz
|
||||||
..name = '${rc.pascalCase}QueryValues'
|
..name = '${rc.pascalCase}QueryValues'
|
||||||
|
@ -660,7 +660,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
var name = ctx.buildContext.resolveFieldName(field.name);
|
var name = ctx.buildContext.resolveFieldName(field.name);
|
||||||
var type = convertTypeReference(field.type);
|
var type = convertTypeReference(field.type);
|
||||||
|
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
var value = refer('values').index(literalString(name));
|
var value = refer('values').index(literalString(name));
|
||||||
|
|
||||||
if (fType is InterfaceType && fType.element.isEnum) {
|
if (fType is InterfaceType && fType.element.isEnum) {
|
||||||
|
@ -684,10 +684,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
..name = field.name
|
..name = field.name
|
||||||
..type = MethodType.getter
|
..type = MethodType.getter
|
||||||
..returns = type
|
..returns = type
|
||||||
..body = new Block((b) => b.addExpression(value.returned));
|
..body = Block((b) => b.addExpression(value.returned));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
Expression value = refer('value');
|
Expression value = refer('value');
|
||||||
|
|
||||||
if (fType is InterfaceType && fType.element.isEnum) {
|
if (fType is InterfaceType && fType.element.isEnum) {
|
||||||
|
@ -702,7 +702,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
b
|
b
|
||||||
..name = field.name
|
..name = field.name
|
||||||
..type = MethodType.setter
|
..type = MethodType.setter
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'value'
|
..name = 'value'
|
||||||
..type = type))
|
..type = type))
|
||||||
..body =
|
..body =
|
||||||
|
@ -711,17 +711,18 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an copyFrom(model)
|
// Add an copyFrom(model)
|
||||||
clazz.methods.add(new Method((b) {
|
clazz.methods.add(Method((b) {
|
||||||
b
|
b
|
||||||
..name = 'copyFrom'
|
..name = 'copyFrom'
|
||||||
..returns = refer('void')
|
..returns = refer('void')
|
||||||
..requiredParameters.add(new Parameter((b) => b
|
..requiredParameters.add(Parameter((b) => b
|
||||||
..name = 'model'
|
..name = 'model'
|
||||||
..type = ctx.buildContext.modelClassType))
|
..type = ctx.buildContext.modelClassType))
|
||||||
..body = new Block((b) {
|
..body = Block((b) {
|
||||||
for (var field in ctx.effectiveFields) {
|
for (var field in ctx.effectiveFields) {
|
||||||
if (isSpecialId(ctx, field) || field is RelationFieldImpl)
|
if (isSpecialId(ctx, field) || field is RelationFieldImpl) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
b.addExpression(refer(field.name)
|
b.addExpression(refer(field.name)
|
||||||
.assign(refer('model').property(field.name)));
|
.assign(refer('model').property(field.name)));
|
||||||
}
|
}
|
||||||
|
@ -744,11 +745,11 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||||
}
|
}
|
||||||
|
|
||||||
var cond = prop.notEqualTo(literalNull);
|
var cond = prop.notEqualTo(literalNull);
|
||||||
var condStr = cond.accept(new DartEmitter());
|
var condStr = cond.accept(DartEmitter());
|
||||||
var blkStr =
|
var blkStr =
|
||||||
new Block((b) => b.addExpression(target.assign(parsedId)))
|
Block((b) => b.addExpression(target.assign(parsedId)))
|
||||||
.accept(new DartEmitter());
|
.accept(DartEmitter());
|
||||||
var ifStmt = new Code('if ($condStr) { $blkStr }');
|
var ifStmt = Code('if ($condStr) { $blkStr }');
|
||||||
b.statements.add(ifStmt);
|
b.statements.add(ifStmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import 'package:angel_orm/angel_orm.dart';
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
import 'orm_build_context.dart';
|
import 'orm_build_context.dart';
|
||||||
|
|
||||||
const TypeChecker columnTypeChecker = const TypeChecker.fromRuntime(Column);
|
const TypeChecker columnTypeChecker = TypeChecker.fromRuntime(Column);
|
||||||
|
|
||||||
Orm reviveORMAnnotation(ConstantReader reader) {
|
Orm reviveORMAnnotation(ConstantReader reader) {
|
||||||
return Orm(
|
return Orm(
|
||||||
|
|
Loading…
Reference in a new issue