diff --git a/docs/content/en/docs/Examples/relationships.md b/docs/content/en/docs/Examples/relationships.md index d7a607b1..f44ac518 100644 --- a/docs/content/en/docs/Examples/relationships.md +++ b/docs/content/en/docs/Examples/relationships.md @@ -69,9 +69,9 @@ Future 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)); + } }); } ``` diff --git a/moor/lib/src/runtime/types/custom_type.dart b/moor/lib/src/runtime/types/custom_type.dart index 87c61e27..470fbbf4 100644 --- a/moor/lib/src/runtime/types/custom_type.dart +++ b/moor/lib/src/runtime/types/custom_type.dart @@ -20,3 +20,23 @@ abstract class TypeConverter { /// 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 extends TypeConverter { + /// All values of the enum. + final List 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; + } +} diff --git a/moor/test/data/tables/todos.g.dart b/moor/test/data/tables/todos.g.dart index 18f9d7a5..f64d0d73 100644 --- a/moor/test/data/tables/todos.g.dart +++ b/moor/test/data/tables/todos.g.dart @@ -7,19 +7,6 @@ part of 'todos.dart'; // ************************************************************************** // ignore_for_file: unnecessary_brace_in_string_interps, unnecessary_this -class _$GeneratedConverter$0 extends TypeConverter { - 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 { final int id; final String title; @@ -573,7 +560,7 @@ class $CategoriesTable extends Categories } static TypeConverter $converter0 = - const _$GeneratedConverter$0(); + const EnumIndexConverter(CategoryPriority.values); } class User extends DataClass implements Insertable { diff --git a/moor_generator/lib/src/model/used_type_converter.dart b/moor_generator/lib/src/model/used_type_converter.dart index c0809030..bcedf8b8 100644 --- a/moor_generator/lib/src/model/used_type_converter.dart +++ b/moor_generator/lib/src/model/used_type_converter.dart @@ -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, diff --git a/moor_generator/lib/src/writer/database_writer.dart b/moor_generator/lib/src/writer/database_writer.dart index 08c05960..1e8a12e7 100644 --- a/moor_generator/lib/src/writer/database_writer.dart +++ b/moor_generator/lib/src/writer/database_writer.dart @@ -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 = {}; - 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(); diff --git a/moor_generator/test/writer/database_writer_test.dart b/moor_generator/test/writer/database_writer_test.dart deleted file mode 100644 index c4e92a23..00000000 --- a/moor_generator/test/writer/database_writer_test.dart +++ /dev/null @@ -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()(); - } - - class TableB extends Table { - IntColumn get another => intEnum()(); - } - - @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')), - ), - ); - }); -}