Merge branch 'develop' into fix-tests

This commit is contained in:
Simon Binder 2022-06-28 23:05:22 +02:00
commit 1b06fcfc77
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
16 changed files with 208 additions and 115 deletions

View File

@ -114,6 +114,24 @@ abstract class NullAwareTypeConverter<D, S extends Object>
/// Map a non-null value from an object in Dart into something that will be
/// understood by the database.
S requireToSql(D value);
/// Invokes a non-nullable [inner] type converter for a single conversion from
/// SQL to Dart.
///
/// Returns `null` if [sqlValue] is `null`, [TypeConverter.fromSql] otherwise.
/// This method is mostly intended to be used for code generated by drift-dev.
static D? wrapFromSql<D, S>(TypeConverter<D, S> inner, S? sqlValue) {
return sqlValue == null ? null : inner.fromSql(sqlValue);
}
/// Invokes a non-nullable [inner] type converter for a single conversion from
/// Dart to SQL.
///
/// Returns `null` if [dartValue] is `null`, [TypeConverter.toSql] otherwise.
/// This method is mostly intended to be used for code generated by drift-dev.
static S? wrapToSql<D, S>(TypeConverter<D, S> inner, D? dartValue) {
return dartValue == null ? null : inner.toSql(dartValue);
}
}
class _NullWrappingTypeConverter<D, S extends Object>

View File

@ -24,7 +24,7 @@ class Config extends DataClass implements Insertable<Config> {
.mapFromDatabaseResponse(data['${effectivePrefix}config_key'])!,
configValue: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0.fromSql(const IntType()
syncState: ConfigTable.$converter0n.fromSql(const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(const IntType()
.mapFromDatabaseResponse(
@ -39,7 +39,7 @@ class Config extends DataClass implements Insertable<Config> {
map['config_value'] = Variable<String?>(configValue);
}
if (!nullToAbsent || syncState != null) {
final converter = ConfigTable.$converter0;
final converter = ConfigTable.$converter0n;
map['sync_state'] = Variable<int?>(converter.toSql(syncState));
}
if (!nullToAbsent || syncStateImplicit != null) {
@ -182,7 +182,7 @@ class ConfigCompanion extends UpdateCompanion<Config> {
map['config_value'] = Variable<String?>(configValue.value);
}
if (syncState.present) {
final converter = ConfigTable.$converter0;
final converter = ConfigTable.$converter0n;
map['sync_state'] = Variable<int?>(converter.toSql(syncState.value));
}
if (syncStateImplicit.present) {
@ -229,7 +229,7 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
type: const IntType(),
requiredDuringInsert: false,
$customConstraints: '')
.withConverter<SyncType?>(ConfigTable.$converter0);
.withConverter<SyncType?>(ConfigTable.$converter0n);
final VerificationMeta _syncStateImplicitMeta =
const VerificationMeta('syncStateImplicit');
late final GeneratedColumnWithTypeConverter<SyncType?, int?>
@ -281,11 +281,12 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
return ConfigTable(attachedDatabase, alias);
}
static TypeConverter<SyncType?, int?> $converter0 =
NullAwareTypeConverter.wrap(const SyncTypeConverter());
static TypeConverter<SyncType, int> $converter0 = const SyncTypeConverter();
static TypeConverter<SyncType?, int?> $converter1 =
const NullAwareTypeConverter.wrap(
EnumIndexConverter<SyncType>(SyncType.values));
static TypeConverter<SyncType?, int?> $converter0n =
NullAwareTypeConverter.wrap($converter0);
@override
bool get isStrict => true;
@override
@ -1476,7 +1477,7 @@ class MyViewData extends DataClass {
.mapFromDatabaseResponse(data['${effectivePrefix}config_key'])!,
configValue: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0.fromSql(const IntType()
syncState: ConfigTable.$converter0n.fromSql(const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(const IntType()
.mapFromDatabaseResponse(
@ -1579,7 +1580,7 @@ class MyView extends ViewInfo<MyView, MyViewData> implements HasResultSet {
late final GeneratedColumnWithTypeConverter<SyncType?, int?> syncState =
GeneratedColumn<int?>('sync_state', aliasedName, true,
type: const IntType())
.withConverter<SyncType?>(ConfigTable.$converter0);
.withConverter<SyncType?>(ConfigTable.$converter0n);
late final GeneratedColumnWithTypeConverter<SyncType?, int?>
syncStateImplicit = GeneratedColumn<int?>(
'sync_state_implicit', aliasedName, true,
@ -1677,7 +1678,8 @@ 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?>(ConfigTable.$converter0.toSql(var1)),
Variable<int?>(
NullAwareTypeConverter.wrapToSql(ConfigTable.$converter0, var1)),
...generatedpred.introducedVariables,
for (var $ in var2) Variable<int?>(ConfigTable.$converter1.toSql($))
],
@ -1775,8 +1777,8 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
rowid: row.read<int>('rowid'),
configKey: row.read<String>('config_key'),
configValue: row.read<String?>('config_value'),
syncState:
ConfigTable.$converter0.fromSql(row.read<int?>('sync_state')),
syncState: NullAwareTypeConverter.wrapFromSql(
ConfigTable.$converter0, row.read<int?>('sync_state')),
syncStateImplicit: ConfigTable.$converter1
.fromSql(row.read<int?>('sync_state_implicit')),
);

View File

@ -1246,7 +1246,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
factory PureDefault.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return PureDefault(
txt: $PureDefaultsTable.$converter0.fromSql(const StringType()
txt: $PureDefaultsTable.$converter0n.fromSql(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}insert'])),
);
}
@ -1254,7 +1254,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (!nullToAbsent || txt != null) {
final converter = $PureDefaultsTable.$converter0;
final converter = $PureDefaultsTable.$converter0n;
map['insert'] = Variable<String?>(converter.toSql(txt));
}
return map;
@ -1270,7 +1270,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return PureDefault(
txt: $PureDefaultsTable.$converter0
txt: $PureDefaultsTable.$converter0n
.fromJson(serializer.fromJson<String?>(json['txt'])),
);
}
@ -1284,7 +1284,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'txt': serializer
.toJson<String?>($PureDefaultsTable.$converter0.toJson(txt)),
.toJson<String?>($PureDefaultsTable.$converter0n.toJson(txt)),
};
}
@ -1333,7 +1333,7 @@ class PureDefaultsCompanion extends UpdateCompanion<PureDefault> {
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (txt.present) {
final converter = $PureDefaultsTable.$converter0;
final converter = $PureDefaultsTable.$converter0n;
map['insert'] = Variable<String?>(converter.toSql(txt.value));
}
return map;
@ -1359,7 +1359,7 @@ class $PureDefaultsTable extends PureDefaults
late final GeneratedColumnWithTypeConverter<MyCustomObject?, String?> txt =
GeneratedColumn<String?>('insert', aliasedName, true,
type: const StringType(), requiredDuringInsert: false)
.withConverter<MyCustomObject?>($PureDefaultsTable.$converter0);
.withConverter<MyCustomObject?>($PureDefaultsTable.$converter0n);
@override
List<GeneratedColumn> get $columns => [txt];
@override
@ -1388,8 +1388,10 @@ class $PureDefaultsTable extends PureDefaults
return $PureDefaultsTable(attachedDatabase, alias);
}
static JsonTypeConverter<MyCustomObject?, String?> $converter0 =
JsonTypeConverter.asNullable(const CustomJsonConverter());
static JsonTypeConverter<MyCustomObject, String> $converter0 =
const CustomJsonConverter();
static JsonTypeConverter<MyCustomObject?, String?> $converter0n =
JsonTypeConverter.asNullable($converter0);
}
class CategoryTodoCountViewData extends DataClass {

View File

@ -135,16 +135,15 @@ UsedTypeConverter? readTypeConverter(
final appliesToJsonToo = helper.isJsonAwareTypeConverter(staticType, library);
// Make the type converter support nulls by just mapping null to null if this
// converter is otherwise non-nullable in both directions but applied on a
// nullable column
final skipForNull = !dartTypeNullable && !sqlTypeNullable && columnIsNullable;
// converter is otherwise non-nullable in both directions.
final canBeSkippedForNulls = !dartTypeNullable && !sqlTypeNullable;
if (sqlTypeNullable != columnIsNullable) {
if (!columnIsNullable) {
reportError('This column is non-nullable in the database, but has a '
'type converter with a nullable SQL type, meaning that it may '
"potentially map to `null` which can't be stored in the database.");
} else if (!skipForNull) {
} else if (!canBeSkippedForNulls) {
final alternative = appliesToJsonToo
? 'JsonTypeConverter.asNullable'
: 'NullAwareTypeConverter.wrap';
@ -156,7 +155,7 @@ UsedTypeConverter? readTypeConverter(
}
}
_checkType(columnType, null, sqlType, library.typeProvider,
_checkType(columnType, columnIsNullable, null, sqlType, library.typeProvider,
library.typeSystem, reportError);
return UsedTypeConverter(
@ -166,7 +165,7 @@ UsedTypeConverter? readTypeConverter(
dartTypeIsNullable: dartTypeNullable,
sqlTypeIsNullable: sqlTypeNullable,
alsoAppliesToJsonConversion: appliesToJsonToo,
skipForNulls: skipForNull,
canBeSkippedForNulls: canBeSkippedForNulls,
);
}
@ -184,7 +183,7 @@ void _checkParameterType(
}
final nullableDartType = column.typeConverter != null
? column.typeConverter!.mapsToNullableDart
? column.typeConverter!.mapsToNullableDart(column.nullable)
: column.nullableInDart;
if (library.isNonNullableByDefault &&
@ -197,6 +196,7 @@ void _checkParameterType(
_checkType(
column.type,
column.nullable,
column.typeConverter,
element.type,
library.typeProvider,
@ -207,6 +207,7 @@ void _checkParameterType(
void _checkType(
ColumnType columnType,
bool columnIsNullable,
UsedTypeConverter? typeConverter,
DartType typeToCheck,
TypeProvider typeProvider,
@ -216,7 +217,7 @@ void _checkType(
DriftDartType expectedDartType;
if (typeConverter != null) {
expectedDartType = typeConverter.dartType;
if (typeConverter.skipForNulls) {
if (typeConverter.canBeSkippedForNulls && columnIsNullable) {
typeToCheck = typeSystem.promoteToNonNull(typeToCheck);
}
} else {

View File

@ -75,7 +75,8 @@ class DriftDartType {
extension OperationOnTypes on HasType {
/// Whether this type is nullable in Dart
bool get nullableInDart {
return (nullable && !isArray) || typeConverter?.mapsToNullableDart == true;
return (nullable && !isArray) ||
typeConverter?.mapsToNullableDart(nullable) == true;
}
/// the Dart type of this column that can be handled by moors type mapping.
@ -111,7 +112,7 @@ extension OperationOnTypes on HasType {
final converter = typeConverter;
if (converter != null) {
var inner = converter.dartType.codeString(options);
if (converter.skipForNulls) inner += '?';
if (converter.canBeSkippedForNulls && nullable) inner += '?';
return isArray ? 'List<$inner>' : inner;
}

View File

@ -46,22 +46,36 @@ class UsedTypeConverter {
/// serialization.
final bool alsoAppliesToJsonConversion;
/// Whether this type converter should be skipped for `null` values.
/// Whether this type converter can be skipped for `null` values.
///
/// This applies to type converters with a non-nullable Dart and SQL type if
/// the column is nullable. For those converters, drift maps `null` to `null`
/// without calling the type converter at all.
///
/// This is implemented by wrapping it in a `NullAwareTypeConverter` in the
/// generated code.
final bool skipForNulls;
/// For nullable columns, this is implemented by wrapping it in a
/// `NullAwareTypeConverter` in the generated code for table classes. For
/// nullable references to non-nullable columns (e.g. from outer joins), this
/// is done with static helper methods on `NullAwareTypeConverter`.
final bool canBeSkippedForNulls;
/// Type converters are stored as static fields in the table that created
/// them. This will be the field name for this converter.
String get fieldName => '\$converter$index';
/// If this converter [canBeSkippedForNulls] and is applied to a nullable
/// column, drift generates a new wrapped type converter which will deal with
/// `null` values.
/// That converter is stored in this field.
String get nullableFieldName => '${fieldName}n';
/// A Dart expression resolving to this converter.
String get tableAndField => '${table!.entityInfoName}.$fieldName';
String tableAndField({bool forNullableColumn = false}) {
final field = canBeSkippedForNulls && forNullableColumn
? nullableFieldName
: fieldName;
return '${table!.entityInfoName}.$field';
}
UsedTypeConverter({
required this.expression,
@ -70,7 +84,7 @@ class UsedTypeConverter {
required this.dartTypeIsNullable,
required this.sqlTypeIsNullable,
this.alsoAppliesToJsonConversion = false,
this.skipForNulls = false,
this.canBeSkippedForNulls = false,
});
factory UsedTypeConverter.forEnumColumn(
@ -114,24 +128,27 @@ class UsedTypeConverter {
);
}
bool get mapsToNullableDart => dartTypeIsNullable || skipForNulls;
bool mapsToNullableDart(bool nullableInSql) {
return dartTypeIsNullable || (canBeSkippedForNulls && nullableInSql);
}
String dartTypeCode(GenerationOptions options) {
String dartTypeCode(GenerationOptions options, bool nullableInSql) {
var type = dartType.codeString(options);
if (options.nnbd && skipForNulls) type += '?';
if (options.nnbd && (canBeSkippedForNulls && nullableInSql)) type += '?';
return type;
}
/// A suitable typename to store an instance of the type converter used here.
String converterNameInCode(GenerationOptions options) {
String converterNameInCode(GenerationOptions options,
{bool makeNullable = false}) {
var sqlDartType = sqlType.getDisplayString(withNullability: options.nnbd);
if (options.nnbd && skipForNulls) sqlDartType += '?';
if (makeNullable) sqlDartType += '?';
final className =
alsoAppliesToJsonConversion ? 'JsonTypeConverter' : 'TypeConverter';
return '$className<${dartTypeCode(options)}, $sqlDartType>';
return '$className<${dartTypeCode(options, makeNullable)}, $sqlDartType>';
}
}

View File

@ -182,9 +182,18 @@ class QueryWriter {
final dartLiteral = asDartLiteral(specialName ?? column.name);
var code = 'row.read<$rawDartType>($dartLiteral)';
if (column.typeConverter != null) {
final converter = column.typeConverter;
code = '${_converter(converter!)}.fromSql($code)';
final converter = column.typeConverter;
if (converter != null) {
if (converter.canBeSkippedForNulls && column.nullable) {
// The type converter maps non-nullable types, but the column may be
// nullable in SQL => just map null to null and only invoke the type
// converter for non-null values.
code = 'NullAwareTypeConverter.wrapFromSql(${_converter(converter)}, '
'$code)';
} else {
// Just apply the type converter directly.
code = '${_converter(converter)}.fromSql($code)';
}
}
return code;
}
@ -861,9 +870,16 @@ class _ExpandedVariableWriter {
final buffer = StringBuffer('Variable<$type>(');
final capture = element.forCaptured;
if (element.typeConverter != null) {
// Apply the converter
buffer.write('${_converter(element.typeConverter!)}.toSql($dartExpr)');
final converter = element.typeConverter;
if (converter != null) {
// Apply the converter.
if (element.nullable && converter.canBeSkippedForNulls) {
buffer.write('NullAwareTypeConverter.wrapToSql('
'${_converter(element.typeConverter!)}, $dartExpr)');
} else {
buffer
.write('${_converter(element.typeConverter!)}.toSql($dartExpr)');
}
final needsNullAssertion =
!element.nullable && scope.generationOptions.nnbd;

View File

@ -59,7 +59,7 @@ class DataClassWriter {
..write('({')
..write(columns.map((column) {
final nullableDartType = column.typeConverter != null
? column.typeConverter!.mapsToNullableDart
? column.typeConverter!.mapsToNullableDart(column.nullable)
: column.nullable;
if (nullableDartType) {
@ -143,10 +143,11 @@ class DataClassWriter {
if (typeConverter != null && typeConverter.alsoAppliesToJsonConversion) {
final type = column.innerColumnType(scope.generationOptions);
final fromConverter = "serializer.fromJson<$type>(json['$jsonKey'])";
final converterField =
typeConverter.tableAndField(forNullableColumn: column.nullable);
final notNull =
!column.nullable && scope.generationOptions.nnbd ? '!' : '';
deserialized =
'${typeConverter.tableAndField}.fromJson($fromConverter)$notNull';
deserialized = '$converterField.fromJson($fromConverter)$notNull';
} else {
final type = column.dartTypeCode(scope.generationOptions);
@ -183,7 +184,9 @@ class DataClassWriter {
final typeConverter = column.typeConverter;
if (typeConverter != null && typeConverter.alsoAppliesToJsonConversion) {
value = '${typeConverter.tableAndField}.toJson($value)';
final converterField =
typeConverter.tableAndField(forNullableColumn: column.nullable);
value = '$converterField.toJson($value)';
dartType = '${column.innerColumnType(scope.generationOptions)}';
}
@ -268,15 +271,13 @@ class DataClassWriter {
if (column.typeConverter != null) {
// apply type converter before writing the variable
final converter = column.typeConverter;
final fieldName = converter!.tableAndField;
final assertNotNull = !column.nullable &&
converter.sqlTypeIsNullable &&
scope.generationOptions.nnbd;
final fieldName =
converter!.tableAndField(forNullableColumn: column.nullable);
_buffer
..write('final converter = $fieldName;\n')
..write(mapSetter)
..write('(converter.toSql(${column.dartGetterName})');
if (assertNotNull) _buffer.write('!');
_buffer.write(');');
} else {
// no type converter. Write variable directly
@ -376,9 +377,8 @@ class RowMappingWriter {
// result.
if (column.typeConverter != null) {
// stored as a static field
final converter = column.typeConverter!;
final loaded =
'${converter.table!.entityInfoName}.${converter.fieldName}';
final loaded = column.typeConverter!
.tableAndField(forNullableColumn: column.nullable);
loadType = '$loaded.fromSql($loadType)';
}

View File

@ -100,14 +100,17 @@ abstract class TableOrViewWriter {
if (converter != null) {
// Generate a GeneratedColumnWithTypeConverter instance, as it has
// additional methods to check for equality against a mapped value.
final mappedType = converter.dartTypeCode(options);
final mappedType = converter.dartTypeCode(options, column.nullable);
final converterCode =
converter.tableAndField(forNullableColumn: column.nullable);
type = 'GeneratedColumnWithTypeConverter<$mappedType, $innerType>';
expressionBuffer
..write('.withConverter<')
..write(mappedType)
..write('>(')
..write(converter.tableAndField)
..write(converterCode)
..write(')');
}
@ -311,18 +314,32 @@ class TableWriter extends TableOrViewWriter {
void _writeConvertersAsStaticFields() {
for (final converter in table.converters) {
final typeName = converter.converterNameInCode(scope.generationOptions);
var code = converter.expression;
if (converter.skipForNulls) {
if (converter.alsoAppliesToJsonConversion) {
code = 'JsonTypeConverter.asNullable($code)';
} else {
code = 'NullAwareTypeConverter.wrap($code)';
}
}
final code = converter.expression;
buffer.write('static $typeName ${converter.fieldName} = $code;');
}
// Generate wrappers for non-nullable type converters that are applied to
// nullable converters.
for (final column in table.columns) {
final converter = column.typeConverter;
if (converter != null &&
converter.canBeSkippedForNulls &&
column.nullable) {
final nullableTypeName = converter
.converterNameInCode(scope.generationOptions, makeNullable: true);
final wrap = converter.alsoAppliesToJsonConversion
? 'JsonTypeConverter.asNullable'
: 'NullAwareTypeConverter.wrap';
final code = '$wrap(${converter.fieldName})';
buffer
.write('static $nullableTypeName ${converter.nullableFieldName} = '
'$code;');
}
}
}
void _writeColumnVerificationMeta(MoorColumn column) {

View File

@ -188,18 +188,13 @@ class UpdateCompanionWriter {
final converter = column.typeConverter;
if (converter != null) {
// apply type converter before writing the variable
final fieldName = '${table.entityInfoName}.${converter.fieldName}';
final fieldName =
converter.tableAndField(forNullableColumn: column.nullable);
_buffer
..write('final converter = $fieldName;\n')
..write(mapSetter)
..write('(converter.toSql($getterName.value)');
if (!column.nullable &&
converter.sqlTypeIsNullable &&
scope.generationOptions.nnbd) {
_buffer.write('!');
}
_buffer.write(');');
..write('(converter.toSql($getterName.value)')
..write(');');
} else {
// no type converter. Write variable directly
_buffer

View File

@ -94,7 +94,7 @@ CREATE TABLE users (
);
final implicitlyNullAware = table.columns[3];
expect(implicitlyNullAware.typeConverter?.skipForNulls, isTrue);
expect(implicitlyNullAware.typeConverter?.canBeSkippedForNulls, isTrue);
});
test('json converters in drift files', () {

View File

@ -10,8 +10,8 @@ part of 'database.dart';
class Category extends DataClass implements Insertable<Category> {
final int id;
final String name;
final Color? color;
Category({required this.id, required this.name, this.color});
final Color color;
Category({required this.id, required this.name, required this.color});
factory Category.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return Category(
@ -30,7 +30,7 @@ class Category extends DataClass implements Insertable<Category> {
map['name'] = Variable<String>(name);
{
final converter = $CategoriesTable.$converter0;
map['color'] = Variable<int>(converter.toSql(color)!);
map['color'] = Variable<int>(converter.toSql(color));
}
return map;
}
@ -49,7 +49,7 @@ class Category extends DataClass implements Insertable<Category> {
return Category(
id: serializer.fromJson<int>(json['id']),
name: serializer.fromJson<String>(json['name']),
color: serializer.fromJson<Color?>(json['color']),
color: serializer.fromJson<Color>(json['color']),
);
}
@override
@ -58,18 +58,14 @@ class Category extends DataClass implements Insertable<Category> {
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'name': serializer.toJson<String>(name),
'color': serializer.toJson<Color?>(color),
'color': serializer.toJson<Color>(color),
};
}
Category copyWith(
{int? id,
String? name,
Value<Color?> color = const Value.absent()}) =>
Category(
Category copyWith({int? id, String? name, Color? color}) => Category(
id: id ?? this.id,
name: name ?? this.name,
color: color.present ? color.value : this.color,
color: color ?? this.color,
);
@override
String toString() {
@ -95,7 +91,7 @@ class Category extends DataClass implements Insertable<Category> {
class CategoriesCompanion extends UpdateCompanion<Category> {
final Value<int> id;
final Value<String> name;
final Value<Color?> color;
final Value<Color> color;
const CategoriesCompanion({
this.id = const Value.absent(),
this.name = const Value.absent(),
@ -104,13 +100,13 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
CategoriesCompanion.insert({
this.id = const Value.absent(),
required String name,
required Color? color,
required Color color,
}) : name = Value(name),
color = Value(color);
static Insertable<Category> custom({
Expression<int>? id,
Expression<String>? name,
Expression<Color?>? color,
Expression<Color>? color,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -120,7 +116,7 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
}
CategoriesCompanion copyWith(
{Value<int>? id, Value<String>? name, Value<Color?>? color}) {
{Value<int>? id, Value<String>? name, Value<Color>? color}) {
return CategoriesCompanion(
id: id ?? this.id,
name: name ?? this.name,
@ -139,7 +135,7 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
}
if (color.present) {
final converter = $CategoriesTable.$converter0;
map['color'] = Variable<int>(converter.toSql(color.value)!);
map['color'] = Variable<int>(converter.toSql(color.value));
}
return map;
}
@ -175,10 +171,10 @@ class $CategoriesTable extends Categories
type: const StringType(), requiredDuringInsert: true);
final VerificationMeta _colorMeta = const VerificationMeta('color');
@override
late final GeneratedColumnWithTypeConverter<Color?, int?> color =
late final GeneratedColumnWithTypeConverter<Color, int?> color =
GeneratedColumn<int?>('color', aliasedName, false,
type: const IntType(), requiredDuringInsert: true)
.withConverter<Color?>($CategoriesTable.$converter0);
.withConverter<Color>($CategoriesTable.$converter0);
@override
List<GeneratedColumn> get $columns => [id, name, color];
@override
@ -216,7 +212,7 @@ class $CategoriesTable extends Categories
return $CategoriesTable(attachedDatabase, alias);
}
static TypeConverter<Color?, int?> $converter0 = const ColorConverter();
static TypeConverter<Color, int> $converter0 = const ColorConverter();
}
class TodoEntry extends DataClass implements Insertable<TodoEntry> {
@ -650,7 +646,8 @@ abstract class _$AppDatabase extends GeneratedDatabase {
return CategoriesWithCountResult(
id: row.read<int?>('id'),
name: row.read<String?>('name'),
color: $CategoriesTable.$converter0.fromSql(row.read<int?>('color')),
color: NullAwareTypeConverter.wrapFromSql(
$CategoriesTable.$converter0, row.read<int?>('color')),
amount: row.read<int>('amount'),
);
});

View File

@ -35,12 +35,12 @@ mixin AutoIncrementingPrimaryKey on Table {
IntColumn get id => integer().autoIncrement()();
}
class ColorConverter extends NullAwareTypeConverter<Color, int> {
class ColorConverter extends TypeConverter<Color, int> {
const ColorConverter();
@override
Color requireFromSql(int fromDb) => Color(fromDb);
Color fromSql(int fromDb) => Color(fromDb);
@override
int requireToSql(Color value) => value.value;
int toSql(Color value) => value.value;
}

View File

@ -1,4 +1,32 @@
targets:
# This setup exists so that the main entrypoint (web/main.dart) gets compiled
# with dartdevc for debug builds while the worker is compiled with dart2js
# (since workers don't support the JS moduled emitted by dartdevc).
# In release builds (`--release` on the CLI), both entrypoints are compiled
# with dart2js.
#
# If you're ok with compiling everything with dart2js, just use
# `compiler: dartj2s` on the options of the default target and ignore the two
# additional targets here.
dart2js_archives:
auto_apply_builders: false
dependencies: [":$default", ":worker"]
builders:
build_web_compilers:dart2js_archive_extractor:
enabled: true
worker:
auto_apply_builders: false
dependencies: [":$default"]
builders:
build_web_compilers:entrypoint:
enabled: true
generate_for:
- web/worker.dart
options:
compiler: dart2js
build_web_compilers:dart2js_archive_extractor:
enabled: false
$default:
builders:
drift_dev:
@ -9,9 +37,11 @@ targets:
generate_values_in_copy_with: true
named_parameters: true
new_sql_code_generation: true
build_web_compilers|entrypoint:
enabled: true
build_web_compilers:entrypoint:
generate_for:
- web/worker.dart
options:
compiler: dart2js
# This one is compiled in the other target
exclude:
- "web/worker.dart"
# We have a designated target for this step.
build_web_compilers:dart2js_archive_extractor:
enabled: false

View File

@ -4,13 +4,12 @@ set -e
function generate() {
echo "------------- Generate: $1 -------------"
pushd $1 > /dev/null
rm -rf .dart_tool
dart pub get
dart pub upgrade
dart run build_runner build --delete-conflicting-outputs
popd > /dev/null
}
cd ..
cd "$(dirname "$0")/.."
generate 'drift'
generate 'drift_dev'
generate 'docs'

View File

@ -4,8 +4,7 @@ set -e
function run_test() {
echo "------------- Running test: $1 -------------"
pushd $1 > /dev/null
rm -rf .dart_tool
dart pub get
dart pub upgrade
dart format -o none --set-exit-if-changed .
dart analyze --fatal-infos --fatal-warnings
if [[ "$2" == 'vm+web' ]]; then
@ -22,8 +21,7 @@ function run_test() {
function run_test_flutter() {
echo "------------- Running flutter test: $1 -------------"
pushd $1 > /dev/null
rm -rf .dart_tool
flutter pub get
flutter pub upgrade
flutter clean
dart format -o none --set-exit-if-changed .
flutter analyze --fatal-infos --fatal-warnings