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();
|
.go();
|
||||||
|
|
||||||
// And write the new ones
|
// And write the new ones
|
||||||
await into(shoppingCartEntries).insertAll([
|
for (final item in entry.items) {
|
||||||
for (var item in entry.items) ShoppingCartEntry(shoppingCart: cart.id, item: item.id)
|
await into(shoppingCartEntries).insert(ShoppingCartEntry(shoppingCart: cart.id, item: item.id));
|
||||||
]);
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -20,3 +20,23 @@ abstract class TypeConverter<D, S> {
|
||||||
/// nullable.
|
/// nullable.
|
||||||
D mapToDart(S fromDb);
|
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
|
// 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> {
|
class TodoEntry extends DataClass implements Insertable<TodoEntry> {
|
||||||
final int id;
|
final int id;
|
||||||
final String title;
|
final String title;
|
||||||
|
@ -573,7 +560,7 @@ class $CategoriesTable extends Categories
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeConverter<CategoryPriority, int> $converter0 =
|
static TypeConverter<CategoryPriority, int> $converter0 =
|
||||||
const _$GeneratedConverter$0();
|
const EnumIndexConverter<CategoryPriority>(CategoryPriority.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
class User extends DataClass implements Insertable<User> {
|
class User extends DataClass implements Insertable<User> {
|
||||||
|
|
|
@ -20,7 +20,7 @@ class UsedTypeConverter {
|
||||||
/// The expression that will construct the type converter at runtime. The
|
/// The expression that will construct the type converter at runtime. The
|
||||||
/// type converter constructed will map a [mappedType] to the [sqlType] and
|
/// type converter constructed will map a [mappedType] to the [sqlType] and
|
||||||
/// vice-versa.
|
/// vice-versa.
|
||||||
String expression;
|
final String expression;
|
||||||
|
|
||||||
/// The type that will be present at runtime.
|
/// The type that will be present at runtime.
|
||||||
final DartType mappedType;
|
final DartType mappedType;
|
||||||
|
@ -54,8 +54,10 @@ class UsedTypeConverter {
|
||||||
throw InvalidTypeForEnumConverterException('Not an enum', enumType);
|
throw InvalidTypeForEnumConverterException('Not an enum', enumType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final className = creatingClass.name;
|
||||||
|
|
||||||
return UsedTypeConverter(
|
return UsedTypeConverter(
|
||||||
expression: 'bogus expression for enum value',
|
expression: 'const EnumIndexConverter<$className>($className.values)',
|
||||||
mappedType: enumType,
|
mappedType: enumType,
|
||||||
sqlType: ColumnType.integer,
|
sqlType: ColumnType.integer,
|
||||||
isForEnum: true,
|
isForEnum: true,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
// ignore: implementation_imports
|
// ignore: implementation_imports
|
||||||
import 'package:moor/src/runtime/executor/stream_queries.dart';
|
import 'package:moor/src/runtime/executor/stream_queries.dart';
|
||||||
|
@ -17,44 +16,6 @@ class DatabaseWriter {
|
||||||
DatabaseWriter(this.db, this.scope);
|
DatabaseWriter(this.db, this.scope);
|
||||||
|
|
||||||
void write() {
|
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
|
// Write referenced tables
|
||||||
for (final table in db.tables) {
|
for (final table in db.tables) {
|
||||||
TableWriter(table, scope.child()).writeInto();
|
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