Add writeToColumnsMixin

This commit is contained in:
Alexander Wilde 2022-12-29 13:48:40 +00:00
parent a98890b1c9
commit 459ec0cf4b
3 changed files with 92 additions and 1 deletions

View File

@ -94,6 +94,9 @@ class DriftOptions {
@JsonKey(name: 'case_from_dart_to_sql', defaultValue: CaseFromDartToSql.snake)
final CaseFromDartToSql caseFromDartToSql;
@JsonKey(name: 'write_to_columns_mixins', defaultValue: false)
final bool writeToColumnsMixins;
@internal
const DriftOptions.defaults({
this.generateFromJsonStringConstructor = false,
@ -115,6 +118,7 @@ class DriftOptions {
this.storeDateTimeValuesAsText = false,
this.dialect = const DialectOptions(SqlDialect.sqlite, null),
this.caseFromDartToSql = CaseFromDartToSql.snake,
this.writeToColumnsMixins = false,
});
DriftOptions({
@ -136,6 +140,7 @@ class DriftOptions {
required this.sqliteAnalysisOptions,
required this.storeDateTimeValuesAsText,
required this.caseFromDartToSql,
required this.writeToColumnsMixins,
this.dialect,
}) {
// ignore: deprecated_member_use_from_same_package

View File

@ -31,7 +31,8 @@ DriftOptions _$DriftOptionsFromJson(Map json) => $checkedCreate(
'named_parameters_always_required',
'scoped_dart_components',
'store_date_time_values_as_text',
'case_from_dart_to_sql'
'case_from_dart_to_sql',
'write_to_columns_mixins'
],
);
final val = DriftOptions(
@ -83,6 +84,8 @@ DriftOptions _$DriftOptionsFromJson(Map json) => $checkedCreate(
(v) =>
$enumDecodeNullable(_$CaseFromDartToSqlEnumMap, v) ??
CaseFromDartToSql.snake),
writeToColumnsMixins: $checkedConvert(
'write_to_columns_mixins', (v) => v as bool? ?? false),
dialect: $checkedConvert('sql',
(v) => v == null ? null : DialectOptions.fromJson(v as Map)),
);
@ -110,6 +113,7 @@ DriftOptions _$DriftOptionsFromJson(Map json) => $checkedCreate(
'sqliteAnalysisOptions': 'sqlite',
'storeDateTimeValuesAsText': 'store_date_time_values_as_text',
'caseFromDartToSql': 'case_from_dart_to_sql',
'writeToColumnsMixins': 'write_to_columns_mixins',
'dialect': 'sql'
},
);
@ -142,6 +146,7 @@ Map<String, dynamic> _$DriftOptionsToJson(DriftOptions instance) =>
'store_date_time_values_as_text': instance.storeDateTimeValuesAsText,
'case_from_dart_to_sql':
_$CaseFromDartToSqlEnumMap[instance.caseFromDartToSql]!,
'write_to_columns_mixins': instance.writeToColumnsMixins,
};
const _$SqlModuleEnumMap = {

View File

@ -46,6 +46,9 @@ class UpdateCompanionWriter {
if (table.existingRowClass?.generateInsertable ?? false) {
_writeToCompanionExtension();
}
if (scope.options.writeToColumnsMixins) {
_writeToColumnsMixin();
}
}
void _writeFields() {
@ -263,4 +266,82 @@ class UpdateCompanionWriter {
..write('return $insertableClass(this);\n')
..write('}\n}\n');
}
void _writeToColumnsMixin() {
final info = table.existingRowClass;
if (info == null) return;
_buffer.write('mixin ${table.nameOfRowClass}Columns ');
final type = _emitter.dartCode(_emitter.writer.rowType(table));
_buffer.writeln('implements ${_emitter.drift('Insertable')}<$type> {');
for (final column in columns) {
if (column.documentationComment != null) {
_buffer.write('${column.documentationComment}\n');
}
final typeName = _emitter.dartCode(_emitter.dartType(column));
_buffer.writeln('$typeName get ${column.nameInDart};');
}
_writeTableToColumnsOverride();
_buffer.write('}');
}
void _writeTableToColumnsOverride() {
final expression = _emitter.drift('Expression');
final variable = _emitter.drift('Variable');
_buffer
..write('@override\nMap<String, $expression> toColumns'
'(bool nullToAbsent) {\n')
..write('final map = <String, $expression> {};');
for (final column in columns) {
// Generated column - cannot be used for inserts or updates
if (column.isGenerated) continue;
// We include all columns that are not null. If nullToAbsent is false, we
// also include null columns. When generating NNBD code, we can include
// non-nullable columns without an additional null check since we know
// the values aren't going to be null.
final needsNullCheck = column.nullableInDart;
final needsScope = needsNullCheck || column.typeConverter != null;
if (needsNullCheck) {
_buffer.write('if (!nullToAbsent || ${column.nameInDart} != null)');
}
if (needsScope) _buffer.write('{');
final typeName =
_emitter.dartCode(_emitter.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!;
_emitter
..write('final converter = ')
..writeDart(_emitter.writer
.readConverter(converter, forNullable: column.nullable))
..writeln(';')
..write(mapSetter)
..write('(converter.toSql(${column.nameInDart})');
_buffer.write(');');
} else {
// no type converter. Write variable directly
_buffer
..write(mapSetter)
..write('(')
..write(column.nameInDart)
..write(');');
}
// This one closes the optional if from before.
if (needsScope) _buffer.write('}');
}
_buffer.write('return map; \n}\n');
}
}