Migrated angel_orm_generator
This commit is contained in:
parent
d2af68779e
commit
af36c3b339
8 changed files with 214 additions and 209 deletions
|
@ -31,8 +31,8 @@
|
|||
* Created basic-sdk-2.12.x_nnbd template (1/1 test passed) <= Milestone 1
|
||||
* Migrated angel_serialize to 4.0.0 (0/0 test passed)
|
||||
* Migrated angel_serialize_generator to 4.0.0 (33/33 tests passed)
|
||||
* Updated angel_orm to 3.0.0 (0/0 tests passed)
|
||||
* Updated angel_migration to 3.0.0 (0/0 tests passed)
|
||||
* Migrated angel_orm to 3.0.0 (0/0 tests passed)
|
||||
* Migrated angel_migration to 3.0.0 (0/0 tests passed)
|
||||
* Added inflection2 and migrated to 1.0.0 (28/32 tests passed)
|
||||
* Updated angel_orm_generator to 3.0.0 (in progress)
|
||||
* Updated angel_migration_runner to 3.0.0 (in progress)
|
||||
|
|
|
@ -8,12 +8,12 @@ part 'main.g.dart';
|
|||
|
||||
main() async {
|
||||
var query = EmployeeQuery()
|
||||
..where.firstName.equals('Rich')
|
||||
..where.lastName.equals('Person')
|
||||
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000))
|
||||
..where!.firstName.equals('Rich')
|
||||
..where!.lastName.equals('Person')
|
||||
..orWhere((w) => w!.salary.greaterThanOrEqualTo(75000))
|
||||
..join('companies', 'company_id', 'id');
|
||||
|
||||
var richPerson = await query.getOne(_FakeExecutor());
|
||||
var richPerson = await (query.getOne(_FakeExecutor()) as FutureOr<Employee>);
|
||||
print(richPerson.toJson());
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ class _FakeExecutor extends QueryExecutor {
|
|||
|
||||
@override
|
||||
Future<List<List>> query(
|
||||
String tableName, String query, Map<String, dynamic> substitutionValues,
|
||||
String tableName, String? query, Map<String, dynamic> substitutionValues,
|
||||
[returningFields]) async {
|
||||
var now = DateTime.now();
|
||||
print(
|
||||
|
@ -41,12 +41,12 @@ class _FakeExecutor extends QueryExecutor {
|
|||
@orm
|
||||
@serializable
|
||||
abstract class _Employee extends Model {
|
||||
String get firstName;
|
||||
String? get firstName;
|
||||
|
||||
String get lastName;
|
||||
String? get lastName;
|
||||
|
||||
@Column(indexType: IndexType.unique)
|
||||
String uniqueId;
|
||||
String? uniqueId;
|
||||
|
||||
double get salary;
|
||||
double? get salary;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ part of 'main.dart';
|
|||
|
||||
class EmployeeMigration extends Migration {
|
||||
@override
|
||||
up(Schema schema) {
|
||||
void up(Schema schema) {
|
||||
schema.create('employees', (table) {
|
||||
table.serial('id')..primaryKey();
|
||||
table.serial('id').primaryKey();
|
||||
table.timeStamp('created_at');
|
||||
table.timeStamp('updated_at');
|
||||
table.varChar('unique_id');
|
||||
|
@ -21,7 +21,7 @@ class EmployeeMigration extends Migration {
|
|||
}
|
||||
|
||||
@override
|
||||
down(Schema schema) {
|
||||
void down(Schema schema) {
|
||||
schema.drop('employees');
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ class EmployeeMigration extends Migration {
|
|||
// OrmGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
||||
EmployeeQuery({Set<String> trampoline}) {
|
||||
class EmployeeQuery extends Query<Employee?, EmployeeQueryWhere?> {
|
||||
EmployeeQuery({Set<String>? trampoline}) {
|
||||
trampoline ??= Set();
|
||||
trampoline.add(tableName);
|
||||
_where = EmployeeQueryWhere(this);
|
||||
|
@ -40,7 +40,7 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
|||
@override
|
||||
final EmployeeQueryValues values = EmployeeQueryValues();
|
||||
|
||||
EmployeeQueryWhere _where;
|
||||
EmployeeQueryWhere? _where;
|
||||
|
||||
@override
|
||||
get casts {
|
||||
|
@ -66,7 +66,7 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
|||
}
|
||||
|
||||
@override
|
||||
EmployeeQueryWhere get where {
|
||||
EmployeeQueryWhere? get where {
|
||||
return _where;
|
||||
}
|
||||
|
||||
|
@ -75,15 +75,15 @@ class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> {
|
|||
return EmployeeQueryWhere(this);
|
||||
}
|
||||
|
||||
static Employee parseRow(List row) {
|
||||
static Employee? parseRow(List row) {
|
||||
if (row.every((x) => x == null)) return null;
|
||||
var model = Employee(
|
||||
id: (row[0] as String),
|
||||
createdAt: (row[1] as DateTime),
|
||||
updatedAt: (row[2] as DateTime),
|
||||
uniqueId: (row[3] as String),
|
||||
firstName: (row[4] as String),
|
||||
lastName: (row[5] as String),
|
||||
id: (row[0] as String?),
|
||||
createdAt: (row[1] as DateTime?),
|
||||
updatedAt: (row[2] as DateTime?),
|
||||
uniqueId: (row[3] as String?),
|
||||
firstName: (row[4] as String?),
|
||||
lastName: (row[5] as String?),
|
||||
salary: double.tryParse(row[6].toString()));
|
||||
return model;
|
||||
}
|
||||
|
@ -130,41 +130,41 @@ class EmployeeQueryValues extends MapQueryValues {
|
|||
return {'salary': 'decimal'};
|
||||
}
|
||||
|
||||
String get id {
|
||||
return (values['id'] as String);
|
||||
String? get id {
|
||||
return (values['id'] as String?);
|
||||
}
|
||||
|
||||
set id(String value) => values['id'] = value;
|
||||
DateTime get createdAt {
|
||||
return (values['created_at'] as DateTime);
|
||||
set id(String? value) => values['id'] = value;
|
||||
DateTime? get createdAt {
|
||||
return (values['created_at'] as DateTime?);
|
||||
}
|
||||
|
||||
set createdAt(DateTime value) => values['created_at'] = value;
|
||||
DateTime get updatedAt {
|
||||
return (values['updated_at'] as DateTime);
|
||||
set createdAt(DateTime? value) => values['created_at'] = value;
|
||||
DateTime? get updatedAt {
|
||||
return (values['updated_at'] as DateTime?);
|
||||
}
|
||||
|
||||
set updatedAt(DateTime value) => values['updated_at'] = value;
|
||||
String get uniqueId {
|
||||
return (values['unique_id'] as String);
|
||||
set updatedAt(DateTime? value) => values['updated_at'] = value;
|
||||
String? get uniqueId {
|
||||
return (values['unique_id'] as String?);
|
||||
}
|
||||
|
||||
set uniqueId(String value) => values['unique_id'] = value;
|
||||
String get firstName {
|
||||
return (values['first_name'] as String);
|
||||
set uniqueId(String? value) => values['unique_id'] = value;
|
||||
String? get firstName {
|
||||
return (values['first_name'] as String?);
|
||||
}
|
||||
|
||||
set firstName(String value) => values['first_name'] = value;
|
||||
String get lastName {
|
||||
return (values['last_name'] as String);
|
||||
set firstName(String? value) => values['first_name'] = value;
|
||||
String? get lastName {
|
||||
return (values['last_name'] as String?);
|
||||
}
|
||||
|
||||
set lastName(String value) => values['last_name'] = value;
|
||||
double get salary {
|
||||
set lastName(String? value) => values['last_name'] = value;
|
||||
double? get salary {
|
||||
return double.tryParse((values['salary'] as String));
|
||||
}
|
||||
|
||||
set salary(double value) => values['salary'] = value.toString();
|
||||
set salary(double? value) => values['salary'] = value.toString();
|
||||
void copyFrom(Employee model) {
|
||||
id = model.id;
|
||||
createdAt = model.createdAt;
|
||||
|
@ -193,36 +193,36 @@ class Employee extends _Employee {
|
|||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
String id;
|
||||
String? id;
|
||||
|
||||
/// The time at which this item was created.
|
||||
@override
|
||||
DateTime createdAt;
|
||||
DateTime? createdAt;
|
||||
|
||||
/// The last time at which this item was updated.
|
||||
@override
|
||||
DateTime updatedAt;
|
||||
DateTime? updatedAt;
|
||||
|
||||
@override
|
||||
String uniqueId;
|
||||
String? uniqueId;
|
||||
|
||||
@override
|
||||
final String firstName;
|
||||
final String? firstName;
|
||||
|
||||
@override
|
||||
final String lastName;
|
||||
final String? lastName;
|
||||
|
||||
@override
|
||||
final double salary;
|
||||
final double? salary;
|
||||
|
||||
Employee copyWith(
|
||||
{String id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
String uniqueId,
|
||||
String firstName,
|
||||
String lastName,
|
||||
double salary}) {
|
||||
{String? id,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
String? uniqueId,
|
||||
String? firstName,
|
||||
String? lastName,
|
||||
double? salary}) {
|
||||
return Employee(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
|
@ -284,32 +284,29 @@ class EmployeeSerializer extends Codec<Employee, Map> {
|
|||
const EmployeeSerializer();
|
||||
|
||||
@override
|
||||
get encoder => const EmployeeEncoder();
|
||||
EmployeeEncoder get encoder => const EmployeeEncoder();
|
||||
@override
|
||||
get decoder => const EmployeeDecoder();
|
||||
EmployeeDecoder get decoder => const EmployeeDecoder();
|
||||
static Employee fromMap(Map map) {
|
||||
return Employee(
|
||||
id: map['id'] as String,
|
||||
id: map['id'] as String?,
|
||||
createdAt: map['created_at'] != null
|
||||
? (map['created_at'] is DateTime
|
||||
? (map['created_at'] as DateTime)
|
||||
? (map['created_at'] as DateTime?)
|
||||
: DateTime.parse(map['created_at'].toString()))
|
||||
: null,
|
||||
updatedAt: map['updated_at'] != null
|
||||
? (map['updated_at'] is DateTime
|
||||
? (map['updated_at'] as DateTime)
|
||||
? (map['updated_at'] as DateTime?)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null,
|
||||
uniqueId: map['unique_id'] as String,
|
||||
firstName: map['first_name'] as String,
|
||||
lastName: map['last_name'] as String,
|
||||
salary: map['salary'] as double);
|
||||
uniqueId: map['unique_id'] as String?,
|
||||
firstName: map['first_name'] as String?,
|
||||
lastName: map['last_name'] as String?,
|
||||
salary: map['salary'] as double?);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Employee model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
'id': model.id,
|
||||
'created_at': model.createdAt?.toIso8601String(),
|
||||
|
|
|
@ -29,7 +29,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
const MigrationGenerator({this.autoSnakeCaseNames = true});
|
||||
|
||||
@override
|
||||
Future<String> generateForAnnotatedElement(
|
||||
Future<String?> generateForAnnotatedElement(
|
||||
Element element, ConstantReader annotation, BuildStep buildStep) async {
|
||||
if (element is! ClassElement) {
|
||||
throw 'Only classes can be annotated with @ORM().';
|
||||
|
@ -43,20 +43,19 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
|
||||
var resolver = await buildStep.resolver;
|
||||
var ctx = await buildOrmContext({}, element as ClassElement, annotation,
|
||||
buildStep, resolver, autoSnakeCaseNames != false);
|
||||
var lib = generateMigrationLibrary(
|
||||
ctx, element as ClassElement, resolver, buildStep);
|
||||
var ctx = await buildOrmContext({}, element, annotation, buildStep,
|
||||
resolver, autoSnakeCaseNames != false);
|
||||
var lib = generateMigrationLibrary(ctx, element, resolver, buildStep);
|
||||
if (lib == null) return null;
|
||||
return DartFormatter().format(lib.accept(DartEmitter()).toString());
|
||||
}
|
||||
|
||||
Library generateMigrationLibrary(OrmBuildContext ctx, ClassElement element,
|
||||
Library generateMigrationLibrary(OrmBuildContext? ctx, ClassElement element,
|
||||
Resolver resolver, BuildStep buildStep) {
|
||||
return Library((lib) {
|
||||
lib.body.add(Class((clazz) {
|
||||
clazz
|
||||
..name = '${ctx.buildContext.modelClassName}Migration'
|
||||
..name = '${ctx!.buildContext.modelClassName}Migration'
|
||||
..extend = refer('Migration')
|
||||
..methods
|
||||
.addAll([buildUpMigration(ctx, lib), buildDownMigration(ctx)]);
|
||||
|
@ -64,10 +63,10 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
Method buildUpMigration(OrmBuildContext ctx, LibraryBuilder lib) {
|
||||
Method buildUpMigration(OrmBuildContext? ctx, LibraryBuilder lib) {
|
||||
return Method((meth) {
|
||||
var autoIdAndDateFields = const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(ctx.buildContext.clazz.thisType);
|
||||
.isAssignableFromType(ctx!.buildContext.clazz.thisType);
|
||||
meth
|
||||
..name = 'up'
|
||||
..annotations.add(refer('override'))
|
||||
|
@ -80,7 +79,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..body = Block((closureBody) {
|
||||
var table = refer('table');
|
||||
|
||||
List<String> dup = [];
|
||||
List<String?> dup = [];
|
||||
ctx.columns.forEach((name, col) {
|
||||
// Skip custom-expression columns.
|
||||
if (col.hasExpression) return;
|
||||
|
@ -103,7 +102,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
(autoIdAndDateFields != false && name == 'id'))) {
|
||||
// Check for relationships that might duplicate
|
||||
for (var rName in ctx.relations.keys) {
|
||||
var relationship = ctx.relations[rName];
|
||||
var relationship = ctx.relations[rName]!;
|
||||
if (relationship.localKey == key) return;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
dup.add(key);
|
||||
}
|
||||
|
||||
String methodName;
|
||||
String? methodName;
|
||||
List<Expression> positional = [literal(key)];
|
||||
Map<String, Expression> named = {};
|
||||
|
||||
|
@ -159,13 +158,13 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
if (col.length == null) {
|
||||
methodName = 'declare';
|
||||
provColumn = columnTypeType.newInstance([
|
||||
literal(col.type.name),
|
||||
literal(col.type!.name),
|
||||
]);
|
||||
} else {
|
||||
methodName = 'declareColumn';
|
||||
provColumn = colType.newInstance([], {
|
||||
'type': columnTypeType.newInstance([
|
||||
literal(col.type.name),
|
||||
literal(col.type!.name),
|
||||
]),
|
||||
'length': literal(col.length),
|
||||
});
|
||||
|
@ -183,10 +182,10 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
if (defaultValue != null && !defaultValue.isNull) {
|
||||
var type = defaultValue.type;
|
||||
Expression defaultExpr;
|
||||
Expression? defaultExpr;
|
||||
|
||||
if (const TypeChecker.fromRuntime(RawSql)
|
||||
.isAssignableFromType(defaultValue.type)) {
|
||||
.isAssignableFromType(defaultValue.type!)) {
|
||||
var value =
|
||||
ConstantReader(defaultValue).read('value').stringValue;
|
||||
defaultExpr =
|
||||
|
@ -195,7 +194,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// Default to enum index.
|
||||
try {
|
||||
var index =
|
||||
ConstantReader(defaultValue).read('index')?.intValue;
|
||||
ConstantReader(defaultValue).read('index').intValue;
|
||||
if (index != null) defaultExpr = literalNum(index);
|
||||
} catch (_) {
|
||||
// Extremely weird error occurs here: `Not an instance of int`.
|
||||
|
@ -203,7 +202,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
} else {
|
||||
defaultExpr = CodeExpression(
|
||||
Code(dartObjectToString(defaultValue)),
|
||||
Code(dartObjectToString(defaultValue)!),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -250,7 +249,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
var columnTypeType = refer('ColumnType');
|
||||
var key = relationship.localKey;
|
||||
var keyType = relationship
|
||||
.foreign.columns[relationship.foreignKey].type.name;
|
||||
.foreign!.columns[relationship.foreignKey!]!.type!.name;
|
||||
|
||||
var field = table.property('declare').call([
|
||||
literal(key),
|
||||
|
@ -284,7 +283,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
Method buildDownMigration(OrmBuildContext ctx) {
|
||||
Method buildDownMigration(OrmBuildContext? ctx) {
|
||||
return Method((b) {
|
||||
b
|
||||
..name = 'down'
|
||||
|
@ -293,7 +292,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..body = Block((b) {
|
||||
var named = <String, Expression>{};
|
||||
|
||||
if (ctx.relations.values.any((r) =>
|
||||
if (ctx!.relations.values.any((r) =>
|
||||
r.type == RelationshipType.hasOne ||
|
||||
r.type == RelationshipType.hasMany ||
|
||||
r.isManyToMany)) {
|
||||
|
@ -302,7 +301,7 @@ class MigrationGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
b.addExpression(_schema
|
||||
.property('drop')
|
||||
.call([literalString(ctx.tableName)], named));
|
||||
.call([literalString(ctx.tableName!)], named));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:angel_serialize_generator/angel_serialize_generator.dart';
|
|||
import 'package:angel_serialize_generator/build_context.dart';
|
||||
import 'package:angel_serialize_generator/context.dart';
|
||||
import 'package:build/build.dart';
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:inflection2/inflection2.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
@ -19,21 +20,21 @@ import 'readers.dart';
|
|||
bool isHasRelation(Relationship r) =>
|
||||
r.type == RelationshipType.hasOne || r.type == RelationshipType.hasMany;
|
||||
|
||||
bool isSpecialId(OrmBuildContext ctx, FieldElement field) {
|
||||
bool isSpecialId(OrmBuildContext? ctx, FieldElement field) {
|
||||
return
|
||||
// field is ShimFieldImpl &&
|
||||
field is! RelationFieldImpl &&
|
||||
(field.name == 'id' &&
|
||||
const TypeChecker.fromRuntime(Model)
|
||||
.isAssignableFromType(ctx.buildContext.clazz.thisType));
|
||||
.isAssignableFromType(ctx!.buildContext.clazz.thisType));
|
||||
}
|
||||
|
||||
Element _findElement(FieldElement field) {
|
||||
return (field.setter == null ? field.getter : field) ?? field;
|
||||
}
|
||||
|
||||
FieldElement findPrimaryFieldInList(
|
||||
OrmBuildContext ctx, Iterable<FieldElement> fields) {
|
||||
FieldElement? findPrimaryFieldInList(
|
||||
OrmBuildContext? ctx, Iterable<FieldElement> fields) {
|
||||
for (var field_ in fields) {
|
||||
var field = field_ is RelationFieldImpl ? field_.originalField : field_;
|
||||
var element = _findElement(field);
|
||||
|
@ -51,39 +52,38 @@ FieldElement findPrimaryFieldInList(
|
|||
}
|
||||
}
|
||||
|
||||
var specialId =
|
||||
fields.firstWhere((f) => isSpecialId(ctx, f), orElse: () => null);
|
||||
var specialId = fields.firstWhereOrNull((f) => isSpecialId(ctx, f));
|
||||
// print(
|
||||
// 'Special ID on ${ctx.buildContext.originalClassName} => ${specialId?.name}');
|
||||
return specialId;
|
||||
}
|
||||
|
||||
Future<OrmBuildContext> buildOrmContext(
|
||||
Future<OrmBuildContext?> buildOrmContext(
|
||||
Map<String, OrmBuildContext> cache,
|
||||
ClassElement clazz,
|
||||
ConstantReader annotation,
|
||||
BuildStep buildStep,
|
||||
Resolver resolver,
|
||||
bool autoSnakeCaseNames,
|
||||
bool? autoSnakeCaseNames,
|
||||
{bool heedExclude = true}) async {
|
||||
// Check for @generatedSerializable
|
||||
// ignore: unused_local_variable
|
||||
DartObject generatedSerializable;
|
||||
DartObject? generatedSerializable;
|
||||
|
||||
while ((generatedSerializable =
|
||||
const TypeChecker.fromRuntime(GeneratedSerializable)
|
||||
.firstAnnotationOf(clazz)) !=
|
||||
null) {
|
||||
clazz = clazz.supertype.element;
|
||||
clazz = clazz.supertype!.element;
|
||||
}
|
||||
|
||||
var id = clazz.location.components.join('-');
|
||||
var id = clazz.location!.components.join('-');
|
||||
if (cache.containsKey(id)) {
|
||||
return cache[id];
|
||||
}
|
||||
var buildCtx = await buildContext(
|
||||
clazz, annotation, buildStep, resolver, autoSnakeCaseNames,
|
||||
heedExclude: heedExclude);
|
||||
var buildCtx = await (buildContext(
|
||||
clazz, annotation, buildStep, resolver, autoSnakeCaseNames!,
|
||||
heedExclude: heedExclude) as FutureOr<BuildContext>);
|
||||
var ormAnnotation = reviveORMAnnotation(annotation);
|
||||
// print(
|
||||
// 'tableName (${annotation.objectValue.type.name}) => ${ormAnnotation.tableName} from ${clazz.name} (${annotation.revive().namedArguments})');
|
||||
|
@ -98,7 +98,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
// Read all fields
|
||||
for (var field in buildCtx.fields) {
|
||||
// Check for column annotation...
|
||||
Column column;
|
||||
Column? column;
|
||||
var element = _findElement(field);
|
||||
var columnAnnotation = columnTypeChecker.firstAnnotationOf(element);
|
||||
// print('${element.name} => $columnAnnotation');
|
||||
|
@ -134,7 +134,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
|
||||
// Try to find a relationship
|
||||
var el = _findElement(field);
|
||||
el ??= field;
|
||||
//el ??= field;
|
||||
var ann = relationshipTypeChecker.firstAnnotationOf(el);
|
||||
|
||||
if (ann != null) {
|
||||
|
@ -146,7 +146,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
var foreignTable = cr.peek('foreignTable')?.stringValue;
|
||||
var cascadeOnDelete = cr.peek('cascadeOnDelete')?.boolValue == true;
|
||||
var through = cr.peek('through')?.typeValue;
|
||||
OrmBuildContext foreign, throughContext;
|
||||
OrmBuildContext? foreign, throughContext;
|
||||
|
||||
if (foreignTable == null) {
|
||||
// if (!isModelClass(field.type) &&
|
||||
|
@ -166,7 +166,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
const TypeChecker.fromRuntime(List)
|
||||
.isAssignableFromType(refType) &&
|
||||
refType.typeArguments.length == 1) {
|
||||
refType = (refType as InterfaceType).typeArguments[0];
|
||||
refType = refType.typeArguments[0];
|
||||
}
|
||||
|
||||
var modelType = firstModelAncestor(refType) ?? refType;
|
||||
|
@ -175,7 +175,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
cache,
|
||||
modelType.element as ClassElement,
|
||||
ConstantReader(const TypeChecker.fromRuntime(Orm)
|
||||
.firstAnnotationOf(modelType.element)),
|
||||
.firstAnnotationOf(modelType.element!)),
|
||||
buildStep,
|
||||
resolver,
|
||||
autoSnakeCaseNames);
|
||||
|
@ -186,14 +186,14 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
cache,
|
||||
through.element,
|
||||
ConstantReader(const TypeChecker.fromRuntime(Serializable)
|
||||
.firstAnnotationOf(modelType.element)),
|
||||
.firstAnnotationOf(modelType.element!)),
|
||||
buildStep,
|
||||
resolver,
|
||||
autoSnakeCaseNames);
|
||||
}
|
||||
|
||||
var ormAnn = const TypeChecker.fromRuntime(Orm)
|
||||
.firstAnnotationOf(modelType.element);
|
||||
.firstAnnotationOf(modelType.element!);
|
||||
|
||||
if (ormAnn != null) {
|
||||
foreignTable =
|
||||
|
@ -201,7 +201,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
}
|
||||
|
||||
foreignTable ??=
|
||||
pluralize(foreign.buildContext.modelClassNameRecase.snakeCase);
|
||||
pluralize(foreign!.buildContext.modelClassNameRecase.snakeCase);
|
||||
} on StackOverflowError {
|
||||
throw UnsupportedError(
|
||||
'There is an infinite cycle between ${clazz.name} and ${field.type.name}. This triggered a stack overflow.');
|
||||
|
@ -233,7 +233,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
foreignKey ??= '${rc.snakeCase}_$localKey';
|
||||
} else if (type == RelationshipType.belongsTo) {
|
||||
foreignKey ??=
|
||||
ctx.buildContext.resolveFieldName(keyName(foreign, 'foreign key'));
|
||||
ctx.buildContext.resolveFieldName(keyName(foreign!, 'foreign key'));
|
||||
localKey ??= '${rcc.snakeCase}_$foreignKey';
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
// 'foreignKey=$foreignKey, localKey=$localKey');
|
||||
|
||||
if (relation.type == RelationshipType.belongsTo) {
|
||||
var name = ReCase(relation.localKey).camelCase;
|
||||
var name = ReCase(relation.localKey!).camelCase;
|
||||
ctx.buildContext.aliases[name] = relation.localKey;
|
||||
|
||||
if (!ctx.effectiveFields.any((f) => f.name == field.name)) {
|
||||
|
@ -290,7 +290,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
|
||||
ctx.relations[field.name] = relation;
|
||||
} 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}".';
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ Future<OrmBuildContext> buildOrmContext(
|
|||
return ctx;
|
||||
}
|
||||
|
||||
ColumnType inferColumnType(DartType type) {
|
||||
ColumnType? inferColumnType(DartType type) {
|
||||
if (const TypeChecker.fromRuntime(String).isAssignableFromType(type)) {
|
||||
return ColumnType.varChar;
|
||||
}
|
||||
|
@ -345,18 +345,18 @@ ColumnType inferColumnType(DartType type) {
|
|||
}
|
||||
|
||||
Column reviveColumn(ConstantReader cr) {
|
||||
ColumnType columnType;
|
||||
ColumnType? columnType;
|
||||
|
||||
var indexTypeObj = cr.peek('indexType')?.objectValue;
|
||||
indexTypeObj ??= cr.revive().namedArguments['indexType'];
|
||||
|
||||
var columnObj =
|
||||
cr.peek('type')?.objectValue?.getField('name')?.toStringValue();
|
||||
cr.peek('type')?.objectValue.getField('name')?.toStringValue();
|
||||
var indexType = IndexType.values[
|
||||
indexTypeObj?.getField('index')?.toIntValue() ?? IndexType.none.index];
|
||||
|
||||
if (const TypeChecker.fromRuntime(PrimaryKey)
|
||||
.isAssignableFromType(cr.objectValue.type)) {
|
||||
.isAssignableFromType(cr.objectValue.type!)) {
|
||||
indexType = IndexType.primaryKey;
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,7 @@ Column reviveColumn(ConstantReader cr) {
|
|||
}
|
||||
|
||||
return Column(
|
||||
isNullable: cr.peek('isNullable')?.boolValue,
|
||||
isNullable: cr.peek('isNullable')?.boolValue ?? false,
|
||||
length: cr.peek('length')?.intValue,
|
||||
type: columnType,
|
||||
indexType: indexType,
|
||||
|
@ -378,7 +378,7 @@ const TypeChecker relationshipTypeChecker =
|
|||
class OrmBuildContext {
|
||||
final BuildContext buildContext;
|
||||
final Orm ormAnnotation;
|
||||
final String tableName;
|
||||
final String? tableName;
|
||||
|
||||
final Map<String, Column> columns = {};
|
||||
final List<FieldElement> effectiveFields = [];
|
||||
|
@ -411,13 +411,13 @@ class RelationFieldImpl extends ShimFieldImpl {
|
|||
|
||||
String get originalFieldName => originalField.name;
|
||||
|
||||
PropertyAccessorElement get getter => originalField.getter;
|
||||
PropertyAccessorElement? get getter => originalField.getter;
|
||||
}
|
||||
|
||||
InterfaceType firstModelAncestor(DartType type) {
|
||||
InterfaceType? firstModelAncestor(DartType? type) {
|
||||
if (type is InterfaceType) {
|
||||
if (type.superclass != null &&
|
||||
const TypeChecker.fromRuntime(Model).isExactlyType(type.superclass)) {
|
||||
const TypeChecker.fromRuntime(Model).isExactlyType(type.superclass!)) {
|
||||
return type;
|
||||
} else {
|
||||
return type.superclass == null
|
||||
|
|
|
@ -31,7 +31,7 @@ TypeReference futureOf(String type) {
|
|||
|
||||
/// Builder that generates `.orm.g.dart`, with an abstract `FooOrm` class.
|
||||
class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
||||
final bool autoSnakeCaseNames;
|
||||
final bool? autoSnakeCaseNames;
|
||||
|
||||
OrmGenerator({this.autoSnakeCaseNames});
|
||||
|
||||
|
@ -48,7 +48,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
}
|
||||
|
||||
Library buildOrmLibrary(AssetId inputId, OrmBuildContext ctx) {
|
||||
Library buildOrmLibrary(AssetId inputId, OrmBuildContext? ctx) {
|
||||
return Library((lib) {
|
||||
// Create `FooQuery` class
|
||||
// Create `FooQueryWhere` class
|
||||
|
@ -58,9 +58,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
Class buildQueryClass(OrmBuildContext ctx) {
|
||||
Class buildQueryClass(OrmBuildContext? ctx) {
|
||||
return Class((clazz) {
|
||||
var rc = ctx.buildContext.modelClassNameRecase;
|
||||
var rc = ctx!.buildContext.modelClassNameRecase;
|
||||
var queryWhereType = refer('${rc.pascalCase}QueryWhere');
|
||||
clazz
|
||||
..name = '${rc.pascalCase}Query'
|
||||
|
@ -80,7 +80,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..annotations.add(refer('override'))
|
||||
..type = MethodType.getter
|
||||
..body = Block((b) {
|
||||
var args = <String, Expression>{};
|
||||
var args = <String?, Expression>{};
|
||||
|
||||
for (var field in ctx.effectiveFields) {
|
||||
var name = ctx.buildContext.resolveFieldName(field.name);
|
||||
|
@ -113,7 +113,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..annotations.add(refer('override'))
|
||||
..type = MethodType.getter
|
||||
..body = Block((b) {
|
||||
b.addExpression(literalString(ctx.tableName).returned);
|
||||
b.addExpression(literalString(ctx.tableName!).returned);
|
||||
});
|
||||
}));
|
||||
|
||||
|
@ -126,7 +126,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..body = Block((b) {
|
||||
var names = ctx.effectiveFields
|
||||
.map((f) =>
|
||||
literalString(ctx.buildContext.resolveFieldName(f.name)))
|
||||
literalString(ctx.buildContext.resolveFieldName(f.name)!))
|
||||
.toList();
|
||||
b.addExpression(literalConstList(names).returned);
|
||||
});
|
||||
|
@ -168,7 +168,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..name = 'row'
|
||||
..type = refer('List')))
|
||||
..body = Block((b) {
|
||||
int i = 0;
|
||||
var i = 0;
|
||||
var args = <String, Expression>{};
|
||||
|
||||
for (var field in ctx.effectiveFields) {
|
||||
|
@ -211,12 +211,12 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
RelationshipType.belongsTo,
|
||||
RelationshipType.hasMany
|
||||
].contains(relation.type)) return;
|
||||
var foreign = relation.foreign;
|
||||
var foreign = relation.foreign!;
|
||||
var skipToList = refer('row')
|
||||
.property('skip')
|
||||
.call([literalNum(i)])
|
||||
.property('take')
|
||||
.call([literalNum(relation.foreign.effectiveFields.length)])
|
||||
.call([literalNum(relation.foreign!.effectiveFields.length)])
|
||||
.property('toList')
|
||||
.call([]);
|
||||
var parsed = refer(
|
||||
|
@ -236,7 +236,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
var blockStr = block.accept(DartEmitter());
|
||||
var ifStr = 'if (row.length > $i) { $blockStr }';
|
||||
b.statements.add(Code(ifStr));
|
||||
i += relation.foreign.effectiveFields.length;
|
||||
i += relation.foreign!.effectiveFields.length;
|
||||
});
|
||||
|
||||
b.addExpression(refer('model').returned);
|
||||
|
@ -277,10 +277,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
// Add any manual SQL expressions.
|
||||
ctx.columns.forEach((name, col) {
|
||||
if (col != null && col.hasExpression) {
|
||||
if (col.hasExpression) {
|
||||
var lhs = refer('expressions').index(
|
||||
literalString(ctx.buildContext.resolveFieldName(name)));
|
||||
var rhs = literalString(col.expression);
|
||||
literalString(ctx.buildContext.resolveFieldName(name)!));
|
||||
var rhs = literalString(col.expression!);
|
||||
b.addExpression(lhs.assign(rhs));
|
||||
}
|
||||
});
|
||||
|
@ -301,13 +301,15 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
// If this is a many-to-many, add the fields from the other object.
|
||||
|
||||
var additionalStrs = relation.foreign.effectiveFields.map((f) =>
|
||||
relation.foreign.buildContext.resolveFieldName(f.name));
|
||||
var additionalFields = additionalStrs.map(literalString);
|
||||
var additionalStrs = relation.foreign!.effectiveFields.map(
|
||||
(f) => relation.foreign!.buildContext
|
||||
.resolveFieldName(f.name));
|
||||
var additionalFields = additionalStrs
|
||||
.map(literalString as Expression Function(String?));
|
||||
|
||||
var joinArgs = [relation.localKey, relation.foreignKey]
|
||||
.map(literalString)
|
||||
.toList();
|
||||
.map(literalString as Function(String?))
|
||||
.toList() as List<Expression>;
|
||||
|
||||
// In the case of a many-to-many, we don't generate a subquery field,
|
||||
// as it easily leads to stack overflows.
|
||||
|
@ -318,10 +320,10 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// FROM users
|
||||
// LEFT JOIN role_users ON role_users.user_id=users.id)
|
||||
var foreignFields = additionalStrs
|
||||
.map((f) => '${relation.foreign.tableName}.$f');
|
||||
.map((f) => '${relation.foreign!.tableName}.$f');
|
||||
var b = StringBuffer('(SELECT ');
|
||||
// role_users.role_id
|
||||
b.write('${relation.throughContext.tableName}');
|
||||
b.write('${relation.throughContext!.tableName}');
|
||||
b.write('.${relation.foreignKey}');
|
||||
// , <user_fields>
|
||||
b.write(foreignFields.isEmpty
|
||||
|
@ -329,39 +331,39 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
: ', ' + foreignFields.join(', '));
|
||||
// FROM users
|
||||
b.write(' FROM ');
|
||||
b.write(relation.foreign.tableName);
|
||||
b.write(relation.foreign!.tableName);
|
||||
// LEFT JOIN role_users
|
||||
b.write(' LEFT JOIN ${relation.throughContext.tableName}');
|
||||
b.write(' LEFT JOIN ${relation.throughContext!.tableName}');
|
||||
// Figure out which field on the "through" table points to users (foreign).
|
||||
var throughRelation =
|
||||
relation.throughContext.relations.values.firstWhere((e) {
|
||||
return e.foreignTable == relation.foreign.tableName;
|
||||
relation.throughContext!.relations.values.firstWhere((e) {
|
||||
return e.foreignTable == relation.foreign!.tableName;
|
||||
}, orElse: () {
|
||||
// _Role has a many-to-many to _User through _RoleUser, but
|
||||
// _RoleUser has no relation pointing to _User.
|
||||
var b = StringBuffer();
|
||||
b.write(ctx.buildContext.modelClassName);
|
||||
b.write('has a many-to-many relationship to ');
|
||||
b.write(relation.foreign.buildContext.modelClassName);
|
||||
b.write(relation.foreign!.buildContext.modelClassName);
|
||||
b.write(' through ');
|
||||
b.write(
|
||||
relation.throughContext.buildContext.modelClassName);
|
||||
relation.throughContext!.buildContext.modelClassName);
|
||||
b.write(', but ');
|
||||
b.write(
|
||||
relation.throughContext.buildContext.modelClassName);
|
||||
relation.throughContext!.buildContext.modelClassName);
|
||||
b.write('has no relation pointing to ');
|
||||
b.write(relation.foreign.buildContext.modelClassName);
|
||||
b.write(relation.foreign!.buildContext.modelClassName);
|
||||
b.write('.');
|
||||
throw b.toString();
|
||||
});
|
||||
|
||||
// ON role_users.user_id=users.id)
|
||||
b.write(' ON ');
|
||||
b.write('${relation.throughContext.tableName}');
|
||||
b.write('${relation.throughContext!.tableName}');
|
||||
b.write('.');
|
||||
b.write(throughRelation.localKey);
|
||||
b.write('=');
|
||||
b.write(relation.foreign.tableName);
|
||||
b.write(relation.foreign!.tableName);
|
||||
b.write('.');
|
||||
b.write(throughRelation.foreignKey);
|
||||
b.write(')');
|
||||
|
@ -377,7 +379,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
// There'll be a private `_field`, and then a getter, named `field`,
|
||||
// that returns the subquery object.
|
||||
var foreignQueryType = refer(
|
||||
foreign.buildContext.modelClassNameRecase.pascalCase +
|
||||
foreign!.buildContext.modelClassNameRecase.pascalCase +
|
||||
'Query');
|
||||
clazz
|
||||
..fields.add(Field((b) => b
|
||||
|
@ -415,7 +417,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
if (manyToMany.isNotEmpty) {
|
||||
var outExprs = manyToMany.map<Expression>((e) {
|
||||
var foreignTableName = e.value.throughContext.tableName;
|
||||
var foreignTableName = e.value.throughContext!.tableName;
|
||||
return CodeExpression(Code('''
|
||||
(!(
|
||||
trampoline.contains('${ctx.tableName}')
|
||||
|
@ -495,9 +497,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
Class buildWhereClass(OrmBuildContext ctx) {
|
||||
Class buildWhereClass(OrmBuildContext? ctx) {
|
||||
return Class((clazz) {
|
||||
var rc = ctx.buildContext.modelClassNameRecase;
|
||||
var rc = ctx!.buildContext.modelClassNameRecase;
|
||||
clazz
|
||||
..name = '${rc.pascalCase}QueryWhere'
|
||||
..extend = refer('QueryWhere');
|
||||
|
@ -519,7 +521,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
|
||||
// Add builders for each field
|
||||
for (var field in ctx.effectiveNormalFields) {
|
||||
var name = field.name;
|
||||
String? name = field.name;
|
||||
var args = <Expression>[];
|
||||
DartType type;
|
||||
Reference builderType;
|
||||
|
@ -535,7 +537,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
isSpecialId(ctx, field)) {
|
||||
builderType = TypeReference((b) => b
|
||||
..symbol = 'NumericSqlExpressionBuilder'
|
||||
..types.add(refer(isSpecialId(ctx, field) ? 'int' : type.name)));
|
||||
..types.add(refer(isSpecialId(ctx, field)
|
||||
? 'int'
|
||||
: type.getDisplayString(withNullability: true))));
|
||||
} else if (type is InterfaceType && type.element.isEnum) {
|
||||
builderType = TypeReference((b) => b
|
||||
..symbol = 'EnumSqlExpressionBuilder'
|
||||
|
@ -555,7 +559,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
.isAssignableFromType(type)) {
|
||||
builderType = refer('ListSqlExpressionBuilder');
|
||||
} else if (ctx.relations.containsKey(field.name)) {
|
||||
var relation = ctx.relations[field.name];
|
||||
var relation = ctx.relations[field.name]!;
|
||||
if (relation.type != RelationshipType.belongsTo) {
|
||||
continue;
|
||||
} else {
|
||||
|
@ -566,7 +570,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
}
|
||||
} else {
|
||||
throw UnsupportedError(
|
||||
'Cannot generate ORM code for field of type ${field.type.name}.');
|
||||
'Cannot generate ORM code for field of type ${field.type.getDisplayString(withNullability: false)}.');
|
||||
}
|
||||
|
||||
clazz.fields.add(Field((b) {
|
||||
|
@ -579,7 +583,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
refer(field.name)
|
||||
.assign(builderType.newInstance([
|
||||
refer('query'),
|
||||
literalString(ctx.buildContext.resolveFieldName(field.name))
|
||||
literalString(ctx.buildContext.resolveFieldName(field.name)!)
|
||||
].followedBy(args)))
|
||||
.code,
|
||||
);
|
||||
|
@ -597,9 +601,9 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
});
|
||||
}
|
||||
|
||||
Class buildValuesClass(OrmBuildContext ctx) {
|
||||
Class buildValuesClass(OrmBuildContext? ctx) {
|
||||
return Class((clazz) {
|
||||
var rc = ctx.buildContext.modelClassNameRecase;
|
||||
var rc = ctx!.buildContext.modelClassNameRecase;
|
||||
clazz
|
||||
..name = '${rc.pascalCase}QueryValues'
|
||||
..extend = refer('MapQueryValues');
|
||||
|
@ -611,7 +615,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..annotations.add(refer('override'))
|
||||
..type = MethodType.getter
|
||||
..body = Block((b) {
|
||||
var args = <String, Expression>{};
|
||||
var args = <String?, Expression>{};
|
||||
|
||||
for (var field in ctx.effectiveFields) {
|
||||
var fType = field.type;
|
||||
|
@ -637,7 +641,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
var type = convertTypeReference(field.type);
|
||||
|
||||
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) {
|
||||
var asInt = value.asA(refer('int'));
|
||||
|
@ -682,7 +686,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
..name = 'value'
|
||||
..type = type))
|
||||
..body =
|
||||
refer('values').index(literalString(name)).assign(value).code;
|
||||
refer('values').index(literalString(name!)).assign(value).code;
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -709,7 +713,7 @@ class OrmGenerator extends GeneratorForAnnotation<Orm> {
|
|||
var prop = refer('model').property(original);
|
||||
// Add only if present
|
||||
var target = refer('values').index(literalString(
|
||||
ctx.buildContext.resolveFieldName(field.name)));
|
||||
ctx.buildContext.resolveFieldName(field.name)!));
|
||||
var foreign = field.relationship.throughContext ??
|
||||
field.relationship.foreign;
|
||||
var foreignField = field.relationship.findForeignField(ctx);
|
||||
|
|
|
@ -20,21 +20,21 @@ class ColumnReader {
|
|||
|
||||
bool get isNullable => reader.peek('isNullable')?.boolValue ?? true;
|
||||
|
||||
int get length => reader.peek('length')?.intValue;
|
||||
int? get length => reader.peek('length')?.intValue;
|
||||
|
||||
DartObject get defaultValue => reader.peek('defaultValue')?.objectValue;
|
||||
DartObject? get defaultValue => reader.peek('defaultValue')?.objectValue;
|
||||
}
|
||||
|
||||
class RelationshipReader {
|
||||
final int type;
|
||||
final String localKey;
|
||||
final String foreignKey;
|
||||
final String foreignTable;
|
||||
final bool cascadeOnDelete;
|
||||
final DartType through;
|
||||
final OrmBuildContext foreign;
|
||||
final OrmBuildContext throughContext;
|
||||
final JoinType joinType;
|
||||
final String? localKey;
|
||||
final String? foreignKey;
|
||||
final String? foreignTable;
|
||||
final bool? cascadeOnDelete;
|
||||
final DartType? through;
|
||||
final OrmBuildContext? foreign;
|
||||
final OrmBuildContext? throughContext;
|
||||
final JoinType? joinType;
|
||||
|
||||
const RelationshipReader(this.type,
|
||||
{this.localKey,
|
||||
|
@ -72,16 +72,16 @@ class RelationshipReader {
|
|||
orElse: () {
|
||||
throw '${ctx.buildContext.clazz.name} has no field that maps to the name "$localKey", '
|
||||
'but it has a @HasMany() relation that expects such a field.';
|
||||
});
|
||||
} as FieldElement Function()?);
|
||||
}
|
||||
|
||||
FieldElement findForeignField(OrmBuildContext ctx) {
|
||||
var foreign = throughContext ?? this.foreign;
|
||||
FieldElement findForeignField(OrmBuildContext? ctx) {
|
||||
var foreign = throughContext ?? this.foreign!;
|
||||
return foreign.effectiveFields.firstWhere(
|
||||
(f) => foreign.buildContext.resolveFieldName(f.name) == foreignKey,
|
||||
orElse: () {
|
||||
throw '${foreign.buildContext.clazz.name} has no field that maps to the name "$foreignKey", '
|
||||
'but ${ctx.buildContext.clazz.name} has a @HasMany() relation that expects such a field.';
|
||||
});
|
||||
'but ${ctx!.buildContext.clazz.name} has a @HasMany() relation that expects such a field.';
|
||||
} as FieldElement Function()?);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,54 +4,59 @@ description: Code generators for Angel's ORM. Generates query builder classes.
|
|||
homepage: https://github.com/dukefirehawk/angel
|
||||
publish_to: none
|
||||
environment:
|
||||
sdk: '>=2.10.0 <3.0.0'
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
dependencies:
|
||||
analyzer: ">=0.35.0 <2.0.0"
|
||||
analyzer: ^1.5.0
|
||||
angel_model:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/model
|
||||
angel_serialize:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/serialize/angel_serialize
|
||||
angel_orm:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/orm/angel_orm
|
||||
angel_serialize_generator:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/serialize/angel_serialize_generator
|
||||
build: ^1.0.0
|
||||
build_config: ^0.4.0
|
||||
code_builder: ^3.0.0
|
||||
dart_style: ^1.0.0
|
||||
inflection2: ^0.4.2
|
||||
meta: ^1.0.0
|
||||
path: ^1.0.0
|
||||
recase: ^3.0.1
|
||||
source_gen: ^0.9.0
|
||||
inflection2:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/inflection2
|
||||
build: ^2.0.1
|
||||
build_config: ^1.0.0
|
||||
code_builder: ^4.0.0
|
||||
dart_style: ^2.0.1
|
||||
meta: ^1.3.0
|
||||
path: ^1.8.0
|
||||
recase: ^4.0.0
|
||||
source_gen: ^1.0.0
|
||||
collection: ^1.15.0-nullsafety.4
|
||||
dev_dependencies:
|
||||
angel_framework:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/framework
|
||||
angel_migration:
|
||||
git:
|
||||
url: https://github.com/dukefirehawk/angel.git
|
||||
ref: sdk-2.12.x
|
||||
ref: sdk-2.12.x_nnbd
|
||||
path: packages/orm/angel_migration
|
||||
#angel_test: ^1.0.0
|
||||
build_runner: ^1.11.5
|
||||
collection: ^1.0.0
|
||||
build_runner: ^2.0.1
|
||||
collection: ^1.15.0
|
||||
pedantic: ^1.11.0
|
||||
postgres: ^2.2.0
|
||||
postgres: ^2.3.2
|
||||
# git:
|
||||
# url: https://github.com/dukefirehawk/postgresql-dart
|
||||
test: ^1.16.5
|
||||
test: ^1.17.3
|
||||
|
|
Loading…
Reference in a new issue