mirror of https://github.com/AMT-Cheif/drift.git
Fix generating variables with custom types
This commit is contained in:
parent
5115bc1525
commit
417d1f59d9
|
@ -167,7 +167,7 @@ class WithDefault extends DataClass implements Insertable<WithDefault> {
|
|||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (!nullToAbsent || a != null) {
|
||||
map['a'] = Variable<String>(a);
|
||||
map['a'] = Variable<String>(a, const CustomTextType());
|
||||
}
|
||||
if (!nullToAbsent || b != null) {
|
||||
map['b'] = Variable<int>(b);
|
||||
|
@ -645,13 +645,12 @@ class Config extends DataClass implements Insertable<Config> {
|
|||
map['config_value'] = Variable<DriftAny>(configValue);
|
||||
}
|
||||
if (!nullToAbsent || syncState != null) {
|
||||
final converter = ConfigTable.$convertersyncStaten;
|
||||
map['sync_state'] = Variable<int>(converter.toSql(syncState));
|
||||
map['sync_state'] =
|
||||
Variable<int>(ConfigTable.$convertersyncStaten.toSql(syncState));
|
||||
}
|
||||
if (!nullToAbsent || syncStateImplicit != null) {
|
||||
final converter = ConfigTable.$convertersyncStateImplicitn;
|
||||
map['sync_state_implicit'] =
|
||||
Variable<int>(converter.toSql(syncStateImplicit));
|
||||
map['sync_state_implicit'] = Variable<int>(
|
||||
ConfigTable.$convertersyncStateImplicitn.toSql(syncStateImplicit));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -796,15 +795,13 @@ class ConfigCompanion extends UpdateCompanion<Config> {
|
|||
map['config_value'] = Variable<DriftAny>(configValue.value);
|
||||
}
|
||||
if (syncState.present) {
|
||||
final converter = ConfigTable.$convertersyncStaten;
|
||||
|
||||
map['sync_state'] = Variable<int>(converter.toSql(syncState.value));
|
||||
map['sync_state'] = Variable<int>(
|
||||
ConfigTable.$convertersyncStaten.toSql(syncState.value));
|
||||
}
|
||||
if (syncStateImplicit.present) {
|
||||
final converter = ConfigTable.$convertersyncStateImplicitn;
|
||||
|
||||
map['sync_state_implicit'] =
|
||||
Variable<int>(converter.toSql(syncStateImplicit.value));
|
||||
map['sync_state_implicit'] = Variable<int>(ConfigTable
|
||||
.$convertersyncStateImplicitn
|
||||
.toSql(syncStateImplicit.value));
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
|
@ -1747,12 +1744,10 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
return customSelect(
|
||||
'SELECT config_key FROM config WHERE ${generatedpred.sql} AND(sync_state = ?1 OR sync_state_implicit IN ($expandedvar2))',
|
||||
variables: [
|
||||
Variable<int>(NullAwareTypeConverter.wrapToSql(
|
||||
ConfigTable.$convertersyncState, var1)),
|
||||
Variable<int>(ConfigTable.$convertersyncStaten.toSql(var1)),
|
||||
...generatedpred.introducedVariables,
|
||||
for (var $ in var2)
|
||||
Variable<int>(NullAwareTypeConverter.wrapToSql(
|
||||
ConfigTable.$convertersyncStateImplicit, $))
|
||||
Variable<int>(ConfigTable.$convertersyncStateImplicitn.toSql($))
|
||||
],
|
||||
readsFrom: {
|
||||
config,
|
||||
|
@ -1893,7 +1888,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
return customSelect(
|
||||
'SELECT"defaults"."a" AS "nested_0.a", "defaults"."b" AS "nested_0.b", defaults.b AS "\$n_0" FROM with_defaults AS defaults WHERE a = ?1',
|
||||
variables: [
|
||||
Variable<String>(var1)
|
||||
Variable<String>(var1, const CustomTextType())
|
||||
],
|
||||
readsFrom: {
|
||||
withConstraints,
|
||||
|
|
|
@ -119,8 +119,8 @@ class Category extends DataClass implements Insertable<Category> {
|
|||
map['id'] = Variable<int>(id);
|
||||
map['desc'] = Variable<String>(description);
|
||||
{
|
||||
final converter = $CategoriesTable.$converterpriority;
|
||||
map['priority'] = Variable<int>(converter.toSql(priority));
|
||||
map['priority'] =
|
||||
Variable<int>($CategoriesTable.$converterpriority.toSql(priority));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -246,9 +246,8 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
|
|||
map['desc'] = Variable<String>(description.value);
|
||||
}
|
||||
if (priority.present) {
|
||||
final converter = $CategoriesTable.$converterpriority;
|
||||
|
||||
map['priority'] = Variable<int>(converter.toSql(priority.value));
|
||||
map['priority'] = Variable<int>(
|
||||
$CategoriesTable.$converterpriority.toSql(priority.value));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -423,8 +422,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
|
|||
map['category'] = Variable<int>(category);
|
||||
}
|
||||
if (!nullToAbsent || status != null) {
|
||||
final converter = $TodosTableTable.$converterstatusn;
|
||||
map['status'] = Variable<String>(converter.toSql(status));
|
||||
map['status'] =
|
||||
Variable<String>($TodosTableTable.$converterstatusn.toSql(status));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -598,9 +597,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
|
|||
map['category'] = Variable<int>(category.value);
|
||||
}
|
||||
if (status.present) {
|
||||
final converter = $TodosTableTable.$converterstatusn;
|
||||
|
||||
map['status'] = Variable<String>(converter.toSql(status.value));
|
||||
map['status'] = Variable<String>(
|
||||
$TodosTableTable.$converterstatusn.toSql(status.value));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -1270,9 +1268,8 @@ class TableWithoutPKCompanion extends UpdateCompanion<CustomRowClass> {
|
|||
map['web_safe_int'] = Variable<BigInt>(webSafeInt.value);
|
||||
}
|
||||
if (custom.present) {
|
||||
final converter = $TableWithoutPKTable.$convertercustom;
|
||||
|
||||
map['custom'] = Variable<String>(converter.toSql(custom.value));
|
||||
map['custom'] = Variable<String>(
|
||||
$TableWithoutPKTable.$convertercustom.toSql(custom.value));
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
|
@ -1371,8 +1368,8 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
|
|||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (!nullToAbsent || txt != null) {
|
||||
final converter = $PureDefaultsTable.$convertertxtn;
|
||||
map['insert'] = Variable<String>(converter.toSql(txt));
|
||||
map['insert'] =
|
||||
Variable<String>($PureDefaultsTable.$convertertxtn.toSql(txt));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -1457,9 +1454,8 @@ class PureDefaultsCompanion extends UpdateCompanion<PureDefault> {
|
|||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (txt.present) {
|
||||
final converter = $PureDefaultsTable.$convertertxtn;
|
||||
|
||||
map['insert'] = Variable<String>(converter.toSql(txt.value));
|
||||
map['insert'] =
|
||||
Variable<String>($PureDefaultsTable.$convertertxtn.toSql(txt.value));
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
|
@ -1532,7 +1528,7 @@ class WithCustomTypeData extends DataClass
|
|||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<UuidValue>(id);
|
||||
map['id'] = Variable<UuidValue>(id, const UuidType());
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
|
@ -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('}');
|
||||
|
|
|
@ -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)';
|
||||
}
|
||||
_emitter.writeDart(
|
||||
_emitter.wrapInVariable(column, AnnotatedDartCode.text(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));
|
||||
}
|
||||
|
||||
_buffer.writeln(');}');
|
||||
_buffer.writeln(';}');
|
||||
}
|
||||
|
||||
_buffer.write('return map; \n}\n');
|
||||
|
|
|
@ -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([
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => const {};
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
User map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
|
@ -70,7 +70,7 @@ class User extends DataClass implements Insertable<User> {
|
|||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<UuidValue>(id);
|
||||
map['id'] = Variable<UuidValue>(id, PgTypes.uuid);
|
||||
map['name'] = Variable<String>(name);
|
||||
return map;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue