buildWhereClass method
Generate
Implementation
Class buildWhereClass(OrmBuildContext ctx) {
return Class((clazz) {
var rc = ctx.buildContext.modelClassNameRecase;
log.info('Generating ${rc.pascalCase}QueryWhere');
clazz
..name = '${rc.pascalCase}QueryWhere'
..extend = refer('QueryWhere');
// Build expressionBuilders getter
clazz.methods.add(Method((m) {
m
..name = 'expressionBuilders'
..returns = refer('List<SqlExpressionBuilder>')
..annotations.add(refer('override'))
..type = MethodType.getter
..body = Block((b) {
var references =
ctx.effectiveNormalFields.map((f) => refer(f.name));
b.addExpression(literalList(references).returned);
});
}));
var initializers = <Code>[];
// Add builders for each field
for (var field in ctx.effectiveNormalFields) {
String? name = field.name;
var args = <Expression>[];
DartType type;
Reference builderType;
try {
type = ctx.buildContext.resolveSerializedFieldType(field.name);
} on StateError {
type = field.type;
}
if (const TypeChecker.fromRuntime(int).isExactlyType(type) ||
const TypeChecker.fromRuntime(double).isExactlyType(type) ||
isSpecialId(ctx, field)) {
var typeName = type.getDisplayString(withNullability: false);
if (isSpecialId(ctx, field)) {
typeName = 'int';
}
//log.fine('$name type = [$typeName]');
builderType = TypeReference((b) => b
..symbol = 'NumericSqlExpressionBuilder'
..types.add(refer(typeName)));
} else if (type is InterfaceType && type.element is EnumElement) {
builderType = TypeReference((b) => b
..symbol = 'EnumSqlExpressionBuilder'
..types.add(convertTypeReference(type)));
var question =
type.nullabilitySuffix == NullabilitySuffix.question ? '?' : '';
args.add(CodeExpression(Code('(v) => v$question.index as int')));
} else if (const TypeChecker.fromRuntime(String).isExactlyType(type)) {
builderType = refer('StringSqlExpressionBuilder');
} else if (const TypeChecker.fromRuntime(bool).isExactlyType(type)) {
builderType = refer('BooleanSqlExpressionBuilder');
} else if (const TypeChecker.fromRuntime(DateTime)
.isExactlyType(type)) {
builderType = refer('DateTimeSqlExpressionBuilder');
} else if (const TypeChecker.fromRuntime(Map)
.isAssignableFromType(type)) {
builderType = refer('MapSqlExpressionBuilder');
} else if (const TypeChecker.fromRuntime(List)
.isAssignableFromType(type)) {
builderType = refer('ListSqlExpressionBuilder');
// Detect relationship
} else if (name.endsWith('Id')) {
log.fine('Foreign Relationship detected = $name');
var relation = ctx.relations[name.replaceAll('Id', '')];
if (relation != null) {
//if (relation?.type != RelationshipType.belongsTo) {
// continue;
//} else {
builderType = TypeReference((b) => b
..symbol = 'NumericSqlExpressionBuilder'
..types.add(refer('int')));
//name = relation?.localKey;
//}
} else {
log.warning(
'Cannot generate ORM code for field ${field.name} of type ${field.type}');
continue;
}
} else {
log.warning(
'Cannot generate ORM code for field ${field.name} of type ${field.type}');
//ctx.relations.forEach((key, value) {
// log.fine('key: $key, value: $value');
//});
//throw UnsupportedError(
// 'Cannot generate ORM code for field of type ${field.type.getDisplayString(withNullability: false)}.');
continue;
}
clazz.fields.add(Field((b) {
//log.fine('Field: $name, BuilderType: $builderType');
b
..name = name
..modifier = FieldModifier.final$
..type = builderType;
var literal = ctx.buildContext.resolveFieldName(field.name);
if (literal != null) {
//log.fine('Literal = ${field.name} $literal');
initializers.add(
refer(field.name)
.assign(builderType.newInstance([
refer('query'),
literalString(literal)
].followedBy(args)))
.code,
);
} else {
log.warning('Literal ${field.name} is null');
}
}));
}
// Now, just add a constructor that initializes each builder.
clazz.constructors.add(Constructor((b) {
b
..requiredParameters.add(Parameter((b) => b
..name = 'query'
..type = refer('${rc.pascalCase}Query')))
..initializers.addAll(initializers);
}));
});
}