Skip to content

Commit

Permalink
Fix generating variables with custom types
Browse files Browse the repository at this point in the history
  • Loading branch information
simolus3 committed Dec 10, 2023
1 parent 5115bc1 commit 417d1f5
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 118 deletions.
31 changes: 13 additions & 18 deletions drift/test/generated/custom_tables.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 15 additions & 19 deletions drift/test/generated/todos.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions drift_dev/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.14.1

- Fix inconsistencies when generating `Variable` instances for columns with
custom types.

## 2.14.0

- __Breaking change__: The name of the generated row class derived from the name
Expand Down
2 changes: 2 additions & 0 deletions drift_dev/lib/src/analysis/results/dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class AnnotatedDartCode {
AnnotatedDartCode(this.elements)
: assert(elements.every((e) => e is String || e is DartTopLevelSymbol));

AnnotatedDartCode.text(String e) : elements = [e];

factory AnnotatedDartCode.ast(AstNode node) {
return AnnotatedDartCode.build(((builder) => builder.addAstNode(node)));
}
Expand Down
39 changes: 12 additions & 27 deletions drift_dev/lib/src/writer/queries/query_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -843,37 +843,22 @@ class _ExpandedVariableWriter {
// Variables without type converters are written as:
// `Variable<int>(x)`. When there's a type converter, we instead use
// `Variable<int>(typeConverter.toSql(x))`.
// Finally, if we're dealing with a list, we use a collection for to
// write all the variables sequentially.
// Finally, if we're dealing with a list, we use a collection for to write
// all the variables sequentially.
String constructVar(String dartExpr) {
// No longer an array here, we apply a for loop if necessary
final type = _emitter
.dartCode(_emitter.innerColumnType(element.sqlType, nullable: false));

final varType = _emitter.drift('Variable');
final buffer = StringBuffer('$varType<$type>(');
final capture = element.forCaptured;

final converter = element.typeConverter;
if (converter != null) {
// Apply the converter.
if (element.nullable && converter.canBeSkippedForNulls) {
final nullAware = _emitter.drift('NullAwareTypeConverter');

buffer.write('$nullAware.wrapToSql('
'${readConverter(_emitter, element.typeConverter!)}, $dartExpr)');
} else {
buffer.write(
'${readConverter(_emitter, element.typeConverter!)}.toSql($dartExpr)');
}
} else if (capture != null) {
buffer.write('row.read(${asDartLiteral(capture.helperColumn)})');
} else {
buffer.write(dartExpr);
if (capture != null) {
dartExpr = ('row.read(${asDartLiteral(capture.helperColumn)})');
}

buffer.write(')');
return buffer.toString();
final code = _emitter.wrapInVariable(
element,
AnnotatedDartCode.text(dartExpr),
// No longer an array here, we apply a for loop below and run this on
// individual values only.
ignoreArray: true,
);
return _emitter.dartCode(code);
}

final name = element.dartParameterName;
Expand Down
27 changes: 4 additions & 23 deletions drift_dev/lib/src/writer/tables/data_class_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,6 @@ class RowMappingWriter {
extension WriteToColumns on TextEmitter {
void writeToColumnsOverride(Iterable<DriftColumn> columns) {
final expression = drift('Expression');
final variable = drift('Variable');

this
..write('@override\nMap<String, $expression> toColumns'
Expand All @@ -409,28 +408,10 @@ extension WriteToColumns on TextEmitter {
}
if (needsScope) write('{');

final typeName = dartCode(variableTypeCode(column, nullable: false));
final mapSetter = 'map[${asDartLiteral(column.nameInSql)}] = '
'$variable<$typeName>';

if (column.typeConverter != null) {
// apply type converter before writing the variable
final converter = column.typeConverter!;

this
..write('final converter = ')
..writeDart(readConverter(converter, forNullable: column.nullable))
..writeln(';')
..write(mapSetter)
..write('(converter.toSql(${column.nameInDart}));');
} else {
// no type converter. Write variable directly
this
..write(mapSetter)
..write('(')
..write(column.nameInDart)
..write(');');
}
write('map[${asDartLiteral(column.nameInSql)}] = ');
writeDart(
wrapInVariable(column, AnnotatedDartCode.text(column.nameInDart)));
writeln(';');

// This one closes the optional if from before.
if (needsScope) write('}');
Expand Down
29 changes: 4 additions & 25 deletions drift_dev/lib/src/writer/tables/update_companion_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,34 +192,13 @@ class UpdateCompanionWriter {
final getterName = thisIfNeeded(column.nameInDart, locals);

_buffer.writeln('if ($getterName.present) {');
final typeName =
_emitter.dartCode(_emitter.variableTypeCode(column, nullable: false));
final mapSetter = 'map[${asDartLiteral(column.nameInSql)}] = '
'${_emitter.drift('Variable')}<$typeName>';
_buffer.write('map[${asDartLiteral(column.nameInSql)}] = ');
var value = '$getterName.value';

final converter = column.typeConverter;
if (converter != null) {
// apply type converter before writing the variable
final fieldName = _emitter.dartCode(
_emitter.readConverter(converter, forNullable: column.nullable));
_buffer.writeln('final converter = $fieldName;\n');
value = 'converter.toSql($value)';
}

_buffer
..write(mapSetter)
..write('($value');

if (column.sqlType.isCustom) {
// Also specify the custom type since it can't be inferred from the
// value passed to the variable.
_buffer
..write(', ')
..write(_emitter.dartCode(column.sqlType.custom!.expression));
}
_emitter.writeDart(
_emitter.wrapInVariable(column, AnnotatedDartCode.text(value)));

_buffer.writeln(');}');
_buffer.writeln(';}');
}

_buffer.write('return map; \n}\n');
Expand Down
41 changes: 38 additions & 3 deletions drift_dev/lib/src/writer/writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,10 @@ abstract class _NodeOrWriter {
/// The Dart type that matches the type of this column, ignoring type
/// converters.
///
/// This is the same as [dartType] but without custom types.
AnnotatedDartCode variableTypeCode(HasType type, {bool? nullable}) {
if (type.isArray) {
/// This is the same as [dartType] but without type converters.
AnnotatedDartCode variableTypeCode(HasType type,
{bool? nullable, bool ignoreArray = false}) {
if (type.isArray && !ignoreArray) {
final inner =
innerColumnType(type.sqlType, nullable: nullable ?? type.nullable);
return AnnotatedDartCode([
Expand Down Expand Up @@ -217,6 +218,40 @@ abstract class _NodeOrWriter {
});
}

AnnotatedDartCode wrapInVariable(HasType column, AnnotatedDartCode expression,
{bool ignoreArray = false}) {
return AnnotatedDartCode.build((b) {
b
..addTopLevel(DartTopLevelSymbol.drift('Variable'))
..addText('<')
..addCode(
variableTypeCode(column, nullable: false, ignoreArray: ignoreArray))
..addText('>(');

final converter = column.typeConverter;
if (converter != null) {
// apply type converter before writing the variable
b
..addCode(readConverter(converter, forNullable: column.nullable))
..addText('.toSql(')
..addCode(expression)
..addText(')');
} else {
b.addCode(expression);
}

if (column.sqlType.isCustom) {
// Also specify the custom type since it can't be inferred from the
// value passed to the variable.
b
..addText(', ')
..addCode(column.sqlType.custom!.expression);
}

b.addText(')');
});
}

String refUri(Uri definition, String element) {
final prefix =
writer.generationOptions.imports.prefixFor(definition, element);
Expand Down
2 changes: 1 addition & 1 deletion drift_dev/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: drift_dev
description: Dev-dependency for users of drift. Contains the generator and development tools.
version: 2.14.0
version: 2.14.1
repository: https://github.com/simolus3/drift
homepage: https://drift.simonbinder.eu/
issue_tracker: https://github.com/simolus3/drift/issues
Expand Down
5 changes: 5 additions & 0 deletions extras/drift_postgres/example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ part 'main.g.dart';
class Users extends Table {
UuidColumn get id => customType(PgTypes.uuid).withDefault(genRandomUuid())();
TextColumn get name => text()();

@override
Set<Column<Object>>? get primaryKey => {id};
}

@DriftDatabase(tables: [Users])
Expand Down Expand Up @@ -38,5 +41,7 @@ void main() async {
UsersCompanion.insert(name: 'Simon', id: Value(Uuid().v4obj())));
print(user);

await database.users.deleteOne(user);

await database.close();
}
Loading

0 comments on commit 417d1f5

Please sign in to comment.