mirror of https://github.com/AMT-Cheif/drift.git
Simplify generation of enum type converters
This commit is contained in:
parent
25ee06ab36
commit
7b9fa3d9ed
|
@ -69,9 +69,9 @@ Future<void> writeShoppingCart(CartWithItems entry) {
|
|||
.go();
|
||||
|
||||
// And write the new ones
|
||||
await into(shoppingCartEntries).insertAll([
|
||||
for (var item in entry.items) ShoppingCartEntry(shoppingCart: cart.id, item: item.id)
|
||||
]);
|
||||
for (final item in entry.items) {
|
||||
await into(shoppingCartEntries).insert(ShoppingCartEntry(shoppingCart: cart.id, item: item.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
|
|
@ -20,3 +20,23 @@ abstract class TypeConverter<D, S> {
|
|||
/// nullable.
|
||||
D mapToDart(S fromDb);
|
||||
}
|
||||
|
||||
/// Implementation for an enum to int converter that uses the index of the enum
|
||||
/// as the value stored in the database.
|
||||
class EnumIndexConverter<T> extends TypeConverter<T, int> {
|
||||
/// All values of the enum.
|
||||
final List<T> values;
|
||||
|
||||
/// Constant default constructor.
|
||||
const EnumIndexConverter(this.values);
|
||||
|
||||
@override
|
||||
T mapToDart(int fromDb) {
|
||||
return fromDb == null ? null : values[fromDb];
|
||||
}
|
||||
|
||||
@override
|
||||
int mapToSql(T value) {
|
||||
return (value as dynamic)?.index as int;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,6 @@ part of 'todos.dart';
|
|||
// **************************************************************************
|
||||
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this
|
||||
class _$GeneratedConverter$0 extends TypeConverter<CategoryPriority, int> {
|
||||
const _$GeneratedConverter$0();
|
||||
@override
|
||||
CategoryPriority mapToDart(int fromDb) {
|
||||
return fromDb == null ? null : CategoryPriority.values[fromDb];
|
||||
}
|
||||
|
||||
@override
|
||||
int mapToSql(CategoryPriority value) {
|
||||
return value?.index;
|
||||
}
|
||||
}
|
||||
|
||||
class TodoEntry extends DataClass implements Insertable<TodoEntry> {
|
||||
final int id;
|
||||
final String title;
|
||||
|
@ -573,7 +560,7 @@ class $CategoriesTable extends Categories
|
|||
}
|
||||
|
||||
static TypeConverter<CategoryPriority, int> $converter0 =
|
||||
const _$GeneratedConverter$0();
|
||||
const EnumIndexConverter<CategoryPriority>(CategoryPriority.values);
|
||||
}
|
||||
|
||||
class User extends DataClass implements Insertable<User> {
|
||||
|
|
|
@ -20,7 +20,7 @@ class UsedTypeConverter {
|
|||
/// The expression that will construct the type converter at runtime. The
|
||||
/// type converter constructed will map a [mappedType] to the [sqlType] and
|
||||
/// vice-versa.
|
||||
String expression;
|
||||
final String expression;
|
||||
|
||||
/// The type that will be present at runtime.
|
||||
final DartType mappedType;
|
||||
|
@ -54,8 +54,10 @@ class UsedTypeConverter {
|
|||
throw InvalidTypeForEnumConverterException('Not an enum', enumType);
|
||||
}
|
||||
|
||||
final className = creatingClass.name;
|
||||
|
||||
return UsedTypeConverter(
|
||||
expression: 'bogus expression for enum value',
|
||||
expression: 'const EnumIndexConverter<$className>($className.values)',
|
||||
mappedType: enumType,
|
||||
sqlType: ColumnType.integer,
|
||||
isForEnum: true,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:moor/moor.dart';
|
||||
// ignore: implementation_imports
|
||||
import 'package:moor/src/runtime/executor/stream_queries.dart';
|
||||
|
@ -17,44 +16,6 @@ class DatabaseWriter {
|
|||
DatabaseWriter(this.db, this.scope);
|
||||
|
||||
void write() {
|
||||
// Write generated convertesr
|
||||
final enumConverters =
|
||||
db.tables.expand((t) => t.converters).where((c) => c.isForEnum);
|
||||
final generatedConvertersForType = <DartType, String>{};
|
||||
var amountOfGeneratedConverters = 0;
|
||||
|
||||
for (final converter in enumConverters) {
|
||||
String classForConverter;
|
||||
|
||||
if (generatedConvertersForType.containsKey(converter.mappedType)) {
|
||||
classForConverter = generatedConvertersForType[converter.mappedType];
|
||||
} else {
|
||||
final id = amountOfGeneratedConverters++;
|
||||
classForConverter = '_\$GeneratedConverter\$$id';
|
||||
|
||||
final buffer = scope.leaf();
|
||||
final dartType = converter.mappedType.getDisplayString();
|
||||
final superClass = converter.displayNameOfConverter;
|
||||
|
||||
buffer
|
||||
..writeln('class $classForConverter extends $superClass {')
|
||||
..writeln('const $classForConverter();')
|
||||
..writeln('@override')
|
||||
..writeln('$dartType mapToDart(int fromDb) {')
|
||||
..writeln('return fromDb == null ? null : $dartType.values[fromDb];')
|
||||
..writeln('}')
|
||||
..writeln('@override')
|
||||
..writeln('int mapToSql($dartType value) {')
|
||||
..writeln('return value?.index;')
|
||||
..writeln('}')
|
||||
..writeln('}');
|
||||
|
||||
generatedConvertersForType[converter.mappedType] = classForConverter;
|
||||
}
|
||||
|
||||
converter.expression = 'const $classForConverter()';
|
||||
}
|
||||
|
||||
// Write referenced tables
|
||||
for (final table in db.tables) {
|
||||
TableWriter(table, scope.child()).writeInto();
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import 'package:moor_generator/src/analyzer/options.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||
import 'package:moor_generator/src/writer/database_writer.dart';
|
||||
import 'package:moor_generator/src/writer/writer.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../analyzer/utils.dart';
|
||||
|
||||
void main() {
|
||||
test('does not generate multiple converters for the same enum', () async {
|
||||
final state = TestState.withContent({
|
||||
'foo|lib/a.dart': '''
|
||||
import 'package:moor/moor.dart';
|
||||
|
||||
enum MyEnum { foo, bar, baz }
|
||||
|
||||
class TableA extends Table {
|
||||
IntColumn get col => intEnum<MyEnum>()();
|
||||
}
|
||||
|
||||
class TableB extends Table {
|
||||
IntColumn get another => intEnum<MyEnum>()();
|
||||
}
|
||||
|
||||
@UseMoor(tables: [TableA, TableB])
|
||||
class Database {
|
||||
|
||||
}
|
||||
''',
|
||||
});
|
||||
|
||||
final file = await state.analyze('package:foo/a.dart');
|
||||
final db = (file.currentResult as ParsedDartFile).declaredDatabases.single;
|
||||
|
||||
final writer = Writer(const MoorOptions());
|
||||
DatabaseWriter(db, writer.child()).write();
|
||||
|
||||
expect(
|
||||
writer.writeGenerated(),
|
||||
allOf(
|
||||
contains(r'_$GeneratedConverter$0'),
|
||||
isNot(contains(r'_$GeneratedConverter$1')),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue