From 453f0f9d0ed4c46fc4a653cb51c6a1d8afd6b86b Mon Sep 17 00:00:00 2001 From: Tobe O Date: Fri, 24 Aug 2018 09:17:04 -0400 Subject: [PATCH] Added ORM context builder --- .../lib/src/orm_build_context.dart | 121 ++++++++++++++++++ angel_orm_generator/lib/src/readers.dart | 2 + 2 files changed, 123 insertions(+) create mode 100644 angel_orm_generator/lib/src/orm_build_context.dart diff --git a/angel_orm_generator/lib/src/orm_build_context.dart b/angel_orm_generator/lib/src/orm_build_context.dart new file mode 100644 index 00000000..f87b0f2d --- /dev/null +++ b/angel_orm_generator/lib/src/orm_build_context.dart @@ -0,0 +1,121 @@ +import 'dart:async'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/type.dart'; +import 'package:angel_orm/angel_orm.dart'; +import 'package:angel_serialize_generator/build_context.dart'; +import 'package:angel_serialize_generator/context.dart'; +import 'package:build/build.dart'; +import 'package:source_gen/source_gen.dart'; + +import 'readers.dart'; + +Future buildOrmContext( + ClassElement clazz, + ConstantReader annotation, + BuildStep buildStep, + Resolver resolver, + bool autoSnakeCaseNames, + bool autoIdAndDateFields, + {bool heedExclude: true}) async { + var buildCtx = await buildContext(clazz, annotation, buildStep, resolver, + autoSnakeCaseNames, autoIdAndDateFields); + var ormAnnotation = reviveORMAnnotation(annotation); + var ctx = new OrmBuildContext(buildCtx, ormAnnotation); + + // Read all fields + for (var field in buildCtx.fields) { + // Check for column annotation... + Column column; + var columnAnnotation = columnTypeChecker.firstAnnotationOf(field); + + if (columnAnnotation != null) { + column = reviveColumn(new ConstantReader(columnAnnotation)); + } + + if (column == null && field.name == 'id' && autoIdAndDateFields == true) { + // TODO: This is only for PostgreSQL!!! + column = const Column(type: ColumnType.serial); + } + + if (column == null) { + // Guess what kind of column this is... + column = new Column( + type: inferColumnType( + field.type, + ), + ); + } + + if (column != null && column.type == null) { + column = new Column( + isNullable: column.isNullable, + length: column.length, + indexType: column.indexType, + defaultValue: column.defaultValue, + type: inferColumnType(field.type), + ); + } + + if (column?.type == null) + throw 'Cannot infer SQL column type for field "${field.name}" with type "${field.type.name}".'; + ctx.columns[field.name] = column; + } + + return ctx; +} + +ColumnType inferColumnType(DartType type) { + if (const TypeChecker.fromRuntime(String).isAssignableFromType(type)) + return ColumnType.varChar; + if (const TypeChecker.fromRuntime(int).isAssignableFromType(type)) + return ColumnType.int; + if (const TypeChecker.fromRuntime(double).isAssignableFromType(type)) + return ColumnType.decimal; + if (const TypeChecker.fromRuntime(num).isAssignableFromType(type)) + return ColumnType.numeric; + if (const TypeChecker.fromRuntime(bool).isAssignableFromType(type)) + return ColumnType.boolean; + if (const TypeChecker.fromRuntime(DateTime).isAssignableFromType(type)) + return ColumnType.timeStamp; + return null; +} + +Column reviveColumn(ConstantReader cr) { + var args = cr.revive().namedArguments; + IndexType indexType = IndexType.none; + ColumnType columnType; + + if (args.containsKey('index')) { + indexType = + IndexType.values[args['indexType'].getField('index').toIntValue()]; + } + + if (args.containsKey('type')) { + columnType = new _ColumnType(args['type'].getField('name').toStringValue()); + } + + return new Column( + isNullable: cr.peek('isNullable')?.boolValue, + length: cr.peek('length')?.intValue, + defaultValue: cr.peek('defaultValue')?.literalValue, + type: columnType, + indexType: indexType, + ); +} + +class OrmBuildContext { + final BuildContext buildContext; + final ORM ormAnnotation; + + final Map columns = {}; + + OrmBuildContext(this.buildContext, this.ormAnnotation); +} + +class _ColumnType implements ColumnType { + @override + final String name; + + _ColumnType(this.name); +} diff --git a/angel_orm_generator/lib/src/readers.dart b/angel_orm_generator/lib/src/readers.dart index bba74bd4..6544c0aa 100644 --- a/angel_orm_generator/lib/src/readers.dart +++ b/angel_orm_generator/lib/src/readers.dart @@ -2,6 +2,8 @@ import 'package:analyzer/dart/constant/value.dart'; import 'package:angel_orm/angel_orm.dart'; import 'package:source_gen/source_gen.dart'; +const TypeChecker columnTypeChecker = const TypeChecker.fromRuntime(Column); + ORM reviveORMAnnotation(ConstantReader reader) { return ORM(reader.peek('tableName')?.stringValue); }