buildValuesClass method
Generate
Implementation
Class buildValuesClass(OrmBuildContext ctx) {
return Class((clazz) {
var rc = ctx.buildContext.modelClassNameRecase;
log.info('Generating ${rc.pascalCase}QueryValues');
clazz
..name = '${rc.pascalCase}QueryValues'
..extend = refer('MapQueryValues');
// Override casts so that we can cast Lists
clazz.methods.add(Method((b) {
b
..name = 'casts'
..returns = refer('Map<String, String>')
..annotations.add(refer('override'))
..type = MethodType.getter
..body = Block((b) {
var args = <String?, Expression>{};
for (var field in ctx.effectiveFields) {
var fType = field.type;
var name = ctx.buildContext.resolveFieldName(field.name);
var type = ctx.columns[field.name]?.type;
if (type == null) continue;
if (const TypeChecker.fromRuntime(List)
.isAssignableFromType(fType)) {
args[name] = literalString(type.name);
}
/* else if (floatTypes.contains(type)) {
args[name] = literalString(type.name);
} */
}
b.addExpression(literalMap(args).returned);
});
}));
// Each field generates a getter and setter
for (var field in ctx.effectiveNormalFields) {
var fType = field.type;
var name = ctx.buildContext.resolveFieldName(field.name);
var type = convertTypeReference(field.type);
clazz.methods.add(Method((b) {
var value = refer('values').index(literalString(name!));
if (fType is InterfaceType && fType.element is EnumElement) {
value = _deserializeEnumExpression(field, value);
} else if (const TypeChecker.fromRuntime(List)
.isAssignableFromType(fType)) {
value = refer('json')
.property('decode')
.call([value.asA(refer('String'))])
.property('cast')
.call([]);
} else if (floatTypes.contains(ctx.columns[field.name]?.type)) {
// Skip using casts on double
value = value
.asA(refer('double?'))
.ifNullThen(CodeExpression(Code('0.0')));
//value = refer('double')
// .property('tryParse')
// .call([value.asA(refer('String'))]).ifNullThen(
// CodeExpression(Code('0.0')));
} else {
value = value.asA(type);
}
b
..name = field.name
..type = MethodType.getter
..returns = type
..body = Block((b) => b.addExpression(value.returned));
}));
clazz.methods.add(Method((b) {
Expression value = refer('value');
if (fType is InterfaceType && fType.element is EnumElement) {
value = _serializeEnumExpression(field, value);
} else if (const TypeChecker.fromRuntime(List)
.isAssignableFromType(fType)) {
value = refer('json').property('encode').call([value]);
}
/* else if (floatTypes.contains(ctx.columns[field.name]?.type)) {
value = value.property('toString').call([]);
} */
b
..name = field.name
..type = MethodType.setter
..requiredParameters.add(Parameter((b) => b
..name = 'value'
..type = type))
..body =
refer('values').index(literalString(name!)).assign(value).code;
}));
}
// Add an copyFrom(model)
clazz.methods.add(Method((b) {
b
..name = 'copyFrom'
..returns = refer('void')
..requiredParameters.add(Parameter((b) => b
..name = 'model'
..type = ctx.buildContext.modelClassType))
..body = Block((b) {
for (var field in ctx.effectiveNormalFields) {
if (isSpecialId(ctx, field) || field is RelationFieldImpl) {
continue;
}
b.addExpression(refer(field.name)
.assign(refer('model').property(field.name)));
}
for (var field in ctx.effectiveNormalFields) {
if (field is RelationFieldImpl) {
var original = field.originalFieldName;
var prop = refer('model').property(original);
// Add only if present
var target = refer('values').index(literalString(
ctx.buildContext.resolveFieldName(field.name)!));
var foreign = field.relationship.throughContext ??
field.relationship.foreign;
var foreignField = field.relationship.findForeignField(ctx);
// Added null safety check
var parsedId = prop.property(foreignField.name);
//log.fine('Foreign field => ${foreignField.name}');
if (foreignField.type.nullabilitySuffix ==
NullabilitySuffix.question) {
parsedId = prop.nullSafeProperty(foreignField.name);
}
if (foreign != null) {
if (isSpecialId(foreign, field)) {
parsedId =
(refer('int').property('tryParse').call([parsedId]));
}
}
var cond = prop.notEqualTo(literalNull);
var condStr =
cond.accept(DartEmitter(useNullSafetySyntax: true));
var blkStr =
Block((b) => b.addExpression(target.assign(parsedId)))
.accept(DartEmitter(useNullSafetySyntax: true));
var ifStmt = Code('if ($condStr) { $blkStr }');
b.statements.add(ifStmt);
}
}
});
}));
});
}