diff --git a/drift/CHANGELOG.md b/drift/CHANGELOG.md index c82b64a9..e4e7ef3b 100644 --- a/drift/CHANGELOG.md +++ b/drift/CHANGELOG.md @@ -2,6 +2,8 @@ - Adds `companion` entry to `DataClassName` to override the name of the generated companion class. +- Add the `TypeConverter.extensionType` factory to create type converters for + extension types. ## 2.16.0 diff --git a/drift/lib/src/runtime/types/converters.dart b/drift/lib/src/runtime/types/converters.dart index 30a2cda4..a2c0d6e7 100644 --- a/drift/lib/src/runtime/types/converters.dart +++ b/drift/lib/src/runtime/types/converters.dart @@ -47,6 +47,35 @@ abstract class TypeConverter { json: json, ); } + + /// A type converter mapping [extension types] to their underlying + /// representation to store them in databases. + /// + /// Here, [ExtType] is the extension type to use in Dart classes, and [Inner] + /// is the underlying type stored in the database. For instance, if you had + /// a type to represent ids in a database: + /// + /// ```dart + /// extension type IdNumber(int id) {} + /// ``` + /// + /// You could use `TypeConverter.extensionType()` in a column + /// definition: + /// + /// ```dart + /// class Users extends Table { + /// IntColumn get id => integer() + /// .autoIncrement() + /// .map(TypeConverter.extensionType())(); + /// TextColumn get name => text()(); + /// } + /// ``` + /// + /// [extension types]: https://dart.dev/language/extension-types + static JsonTypeConverter + extensionType() { + return _ExtensionTypeConverter(); + } } /// A mixin for [TypeConverter]s that should also apply to drift's builtin @@ -264,3 +293,17 @@ class _NullWrappingTypeConverterWithJson return value == null ? null : requireToJson(value); } } + +class _ExtensionTypeConverter + extends TypeConverter + with JsonTypeConverter { + const _ExtensionTypeConverter(); + + @override + ExtType fromSql(Inner fromDb) { + return fromDb as ExtType; + } + + @override + Inner toSql(ExtType value) => value as Inner; +} diff --git a/drift/test/database/batch_test.dart b/drift/test/database/batch_test.dart index dcf1d51c..1e527289 100644 --- a/drift/test/database/batch_test.dart +++ b/drift/test/database/batch_test.dart @@ -35,14 +35,14 @@ void main() { ); b.replaceAll(db.categories, const [ - CategoriesCompanion(id: Value(1), description: Value('new1')), - CategoriesCompanion(id: Value(2), description: Value('new2')), + CategoriesCompanion(id: Value(RowId(1)), description: Value('new1')), + CategoriesCompanion(id: Value(RowId(2)), description: Value('new2')), ]); b.deleteWhere<$CategoriesTable, Category>( db.categories, (tbl) => tbl.id.equals(1)); b.deleteAll(db.categories); - b.delete(db.todosTable, const TodosTableCompanion(id: Value(3))); + b.delete(db.todosTable, const TodosTableCompanion(id: Value(RowId(3)))); b.update(db.users, const UsersCompanion(name: Value('new name 2'))); @@ -97,7 +97,7 @@ void main() { db.categories, CategoriesCompanion.insert(description: 'description'), onConflict: DoUpdate((old) { - return const CategoriesCompanion(id: Value(42)); + return const CategoriesCompanion(id: Value(RowId(42))); }), ); }); @@ -203,16 +203,17 @@ void main() { test('updates stream queries', () async { await db.batch((b) { - b.insert(db.todosTable, const TodoEntry(id: 3, content: 'content')); + b.insert( + db.todosTable, const TodoEntry(id: RowId(3), content: 'content')); b.update(db.users, const UsersCompanion(name: Value('new user name'))); b.replace( db.todosTable, - const TodosTableCompanion(id: Value(3), content: Value('new')), + const TodosTableCompanion(id: Value(RowId(3)), content: Value('new')), ); b.deleteWhere(db.todosTable, (TodosTable row) => row.id.equals(3)); - b.delete(db.todosTable, const TodosTableCompanion(id: Value(3))); + b.delete(db.todosTable, const TodosTableCompanion(id: Value(RowId(3)))); }); verify( diff --git a/drift/test/database/data_class_test.dart b/drift/test/database/data_class_test.dart index 05afec45..c290bf8d 100644 --- a/drift/test/database/data_class_test.dart +++ b/drift/test/database/data_class_test.dart @@ -6,7 +6,7 @@ import '../generated/todos.dart'; void main() { test('data classes can be serialized', () { final entry = TodoEntry( - id: 13, + id: RowId(13), title: 'Title', content: 'Content', targetDate: DateTime.now(), @@ -36,7 +36,7 @@ void main() { driftRuntimeOptions.defaultSerializer = _MySerializer(); final entry = TodoEntry( - id: 13, + id: RowId(13), title: 'Title', content: 'Content', category: 3, @@ -59,7 +59,7 @@ void main() { test('can serialize and deserialize blob columns', () { final user = User( - id: 3, + id: RowId(3), name: 'Username', isAwesome: true, profilePicture: Uint8List.fromList(const [1, 2, 3, 4]), @@ -79,7 +79,7 @@ void main() { test('generated data classes can be converted to companions', () { const entry = Category( - id: 3, + id: RowId(3), description: 'description', priority: CategoryPriority.low, descriptionInUpperCase: 'ignored', @@ -91,7 +91,7 @@ void main() { companion, equals(CategoriesCompanion.insert( description: 'description', - id: const Value(3), + id: const Value(RowId(3)), priority: const Value(CategoryPriority.low), )), ); diff --git a/drift/test/database/database_test.dart b/drift/test/database/database_test.dart index fe8943d7..e96efd43 100644 --- a/drift/test/database/database_test.dart +++ b/drift/test/database/database_test.dart @@ -72,7 +72,7 @@ void main() { final executor = MockExecutor(); final db = TodoDb(executor); - await db.someDao.todosForUser(user: 1).get(); + await db.someDao.todosForUser(user: RowId(1)).get(); verify(executor.runSelect(argThat(contains('SELECT t.* FROM todos')), [1])); }); diff --git a/drift/test/database/statements/custom_queries_test.dart b/drift/test/database/statements/custom_queries_test.dart index 288a1a31..5759ba1c 100644 --- a/drift/test/database/statements/custom_queries_test.dart +++ b/drift/test/database/statements/custom_queries_test.dart @@ -23,7 +23,7 @@ void main() { group('compiled custom queries', () { // defined query: SELECT * FROM todos WHERE title = ?2 OR id IN ? OR title = ?1 test('work with arrays', () async { - await db.withIn('one', 'two', [1, 2, 3]).get(); + await db.withIn('one', 'two', [RowId(1), RowId(2), RowId(3)]).get(); verify( executor.runSelect( diff --git a/drift/test/database/statements/delete_test.dart b/drift/test/database/statements/delete_test.dart index 24eeb19a..a4db7352 100644 --- a/drift/test/database/statements/delete_test.dart +++ b/drift/test/database/statements/delete_test.dart @@ -58,13 +58,14 @@ void main() { final returnedValue = await db .delete(db.todosTable) - .deleteReturning(const TodosTableCompanion(id: Value(10))); + .deleteReturning(const TodosTableCompanion(id: Value(RowId(10)))); verify(executor.runSelect( 'DELETE FROM "todos" WHERE "id" = ? RETURNING *;', [10])); verify(streamQueries.handleTableUpdates( {TableUpdate.onTable(db.todosTable, kind: UpdateKind.delete)})); - expect(returnedValue, const TodoEntry(id: 10, content: 'Content')); + expect( + returnedValue, const TodoEntry(id: RowId(10), content: 'Content')); }); test('for multiple rows', () async { @@ -112,7 +113,7 @@ void main() { }); test('deleteOne()', () async { - await db.users.deleteOne(const UsersCompanion(id: Value(3))); + await db.users.deleteOne(const UsersCompanion(id: Value(RowId(3)))); verify( executor.runDelete('DELETE FROM "users" WHERE "id" = ?;', const [3])); diff --git a/drift/test/database/statements/insert_test.dart b/drift/test/database/statements/insert_test.dart index 77b15685..971f7ce8 100644 --- a/drift/test/database/statements/insert_test.dart +++ b/drift/test/database/statements/insert_test.dart @@ -56,7 +56,7 @@ void main() { test('generates insert or replace statements', () async { await db.into(db.todosTable).insert( const TodoEntry( - id: 113, + id: RowId(113), content: 'Done', ), mode: InsertMode.insertOrReplace); @@ -405,7 +405,8 @@ void main() { when(executor.runInsert(any, any)).thenAnswer((_) => Future.value(3)); final id = await db.into(db.todosTable).insertOnConflictUpdate( - TodosTableCompanion.insert(content: 'content', id: const Value(3))); + TodosTableCompanion.insert( + content: 'content', id: const Value(RowId(3)))); verify(executor.runInsert( 'INSERT INTO "todos" ("id", "content") VALUES (?, ?) ' @@ -615,7 +616,7 @@ void main() { expect( row, const Category( - id: 1, + id: RowId(1), description: 'description', descriptionInUpperCase: 'DESCRIPTION', priority: CategoryPriority.medium, diff --git a/drift/test/database/statements/join_test.dart b/drift/test/database/statements/join_test.dart index c8d33eae..295f507d 100644 --- a/drift/test/database/statements/join_test.dart +++ b/drift/test/database/statements/join_test.dart @@ -81,7 +81,7 @@ void main() { expect( row.readTable(todos), TodoEntry( - id: 5, + id: RowId(5), title: 'title', content: 'content', targetDate: date, @@ -92,7 +92,7 @@ void main() { expect( row.readTable(categories), const Category( - id: 3, + id: RowId(3), description: 'description', priority: CategoryPriority.high, descriptionInUpperCase: 'DESCRIPTION', @@ -134,7 +134,7 @@ void main() { expect( row.readTable(db.todosTable), const TodoEntry( - id: 5, + id: RowId(5), title: 'title', content: 'content', )); @@ -256,7 +256,7 @@ void main() { result.readTable(categories), equals( const Category( - id: 3, + id: RowId(3), description: 'Description', descriptionInUpperCase: 'DESCRIPTION', priority: CategoryPriority.medium, @@ -306,7 +306,7 @@ void main() { result.readTable(categories), equals( const Category( - id: 3, + id: RowId(3), description: 'Description', descriptionInUpperCase: 'DESCRIPTION', priority: CategoryPriority.medium, @@ -362,7 +362,7 @@ void main() { expect( result.readTable(categories), const Category( - id: 3, + id: RowId(3), description: 'desc', descriptionInUpperCase: 'DESC', priority: CategoryPriority.low, diff --git a/drift/test/database/statements/select_test.dart b/drift/test/database/statements/select_test.dart index 52cc3748..3f1fd1d1 100644 --- a/drift/test/database/statements/select_test.dart +++ b/drift/test/database/statements/select_test.dart @@ -16,7 +16,7 @@ final _dataOfTodoEntry = { }; const _todoEntry = TodoEntry( - id: 10, + id: RowId(10), title: 'A todo title', content: 'Content', category: 3, @@ -126,7 +126,7 @@ void main() { } ]; const resolved = TodoEntry( - id: 10, + id: RowId(10), title: null, content: 'Content', category: null, @@ -198,7 +198,7 @@ void main() { expect( category, const Category( - id: 1, + id: RowId(1), description: 'description', descriptionInUpperCase: 'DESCRIPTION', priority: CategoryPriority.high, @@ -232,7 +232,7 @@ void main() { expect(rows, [ TodoEntry( - id: 10, + id: RowId(10), title: null, content: 'Content', category: null, diff --git a/drift/test/database/statements/update_test.dart b/drift/test/database/statements/update_test.dart index af99b1cc..ce95a733 100644 --- a/drift/test/database/statements/update_test.dart +++ b/drift/test/database/statements/update_test.dart @@ -55,7 +55,7 @@ void main() { group('generates replace statements', () { test('regular', () async { await db.update(db.todosTable).replace(const TodoEntry( - id: 3, + id: RowId(3), title: 'Title', content: 'Updated content', status: TodoStatus.workInProgress, @@ -71,7 +71,7 @@ void main() { test('applies default values', () async { await db.update(db.users).replace( UsersCompanion( - id: const Value(3), + id: const Value(RowId(3)), name: const Value('Hummingbird'), profilePicture: Value(Uint8List(0)), ), @@ -167,14 +167,14 @@ void main() { group('update on table instances', () { test('update()', () async { - await db.users.update().write(const UsersCompanion(id: Value(3))); + await db.users.update().write(const UsersCompanion(id: Value(RowId(3)))); verify(executor.runUpdate('UPDATE "users" SET "id" = ?;', [3])); }); test('replace', () async { await db.categories.replaceOne(const CategoriesCompanion( - id: Value(3), description: Value('new name'))); + id: Value(RowId(3)), description: Value('new name'))); verify(executor.runUpdate( 'UPDATE "categories" SET "desc" = ?, "priority" = 0 WHERE "id" = ?;', @@ -205,7 +205,7 @@ void main() { expect(rows, const [ Category( - id: 3, + id: RowId(3), description: 'test', priority: CategoryPriority.low, descriptionInUpperCase: 'TEST', diff --git a/drift/test/database/tables_test.dart b/drift/test/database/tables_test.dart index 21426964..0f0bb909 100644 --- a/drift/test/database/tables_test.dart +++ b/drift/test/database/tables_test.dart @@ -59,7 +59,7 @@ void main() { expect( todo, const TodoEntry( - id: 1, + id: RowId(1), title: 'some title', content: 'do this', targetDate: null, diff --git a/drift/test/database/types/type_converter_test.dart b/drift/test/database/types/type_converter_test.dart index 4e773e2a..eadf1ef2 100644 --- a/drift/test/database/types/type_converter_test.dart +++ b/drift/test/database/types/type_converter_test.dart @@ -4,6 +4,7 @@ import 'package:drift/drift.dart'; import 'package:test/test.dart'; import '../../generated/converter.dart'; +import '../../generated/todos.dart'; enum _MyEnum { one, two, three } @@ -34,6 +35,16 @@ void main() { }); }); + test('TypeConverter.extensionType', () { + final converter = TypeConverter.extensionType(); + + expect(converter.toSql(RowId(123)), 123); + expect(converter.fromSql(15), RowId(15)); + expect(converter.fromSql(15), 15); + expect(converter.fromJson(16), RowId(16)); + expect(converter.toJson(RowId(124)), 124); + }); + group('enum name', () { const converter = EnumNameConverter(_MyEnum.values); const values = { diff --git a/drift/test/generated/todos.dart b/drift/test/generated/todos.dart index 7d5576a3..a7fa13df 100644 --- a/drift/test/generated/todos.dart +++ b/drift/test/generated/todos.dart @@ -4,8 +4,14 @@ import 'package:uuid/uuid.dart'; part 'todos.g.dart'; +extension type RowId._(int id) { + const RowId(this.id); +} + mixin AutoIncrement on Table { - IntColumn get id => integer().autoIncrement()(); + IntColumn get id => integer() + .autoIncrement() + .map(TypeConverter.extensionType())(); } @DataClassName('TodoEntry') diff --git a/drift/test/generated/todos.g.dart b/drift/test/generated/todos.g.dart index cc61ad3c..4685760b 100644 --- a/drift/test/generated/todos.g.dart +++ b/drift/test/generated/todos.g.dart @@ -11,13 +11,14 @@ class $CategoriesTable extends Categories $CategoriesTable(this.attachedDatabase, [this._alias]); static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - hasAutoIncrement: true, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + late final GeneratedColumnWithTypeConverter id = GeneratedColumn< + int>('id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')) + .withConverter($CategoriesTable.$converterid); static const VerificationMeta _descriptionMeta = const VerificationMeta('description'); @override @@ -56,9 +57,7 @@ class $CategoriesTable extends Categories {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } + context.handle(_idMeta, const VerificationResult.success()); if (data.containsKey('desc')) { context.handle(_descriptionMeta, description.isAcceptableOrUnknown(data['desc']!, _descriptionMeta)); @@ -81,8 +80,8 @@ class $CategoriesTable extends Categories Category map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return Category( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + id: $CategoriesTable.$converterid.fromSql(attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!), description: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}desc'])!, priority: $CategoriesTable.$converterpriority.fromSql(attachedDatabase @@ -99,12 +98,14 @@ class $CategoriesTable extends Categories return $CategoriesTable(attachedDatabase, alias); } + static JsonTypeConverter2 $converterid = + TypeConverter.extensionType(); static JsonTypeConverter2 $converterpriority = const EnumIndexConverter(CategoryPriority.values); } class Category extends DataClass implements Insertable { - final int id; + final RowId id; final String description; final CategoryPriority priority; final String descriptionInUpperCase; @@ -116,7 +117,9 @@ class Category extends DataClass implements Insertable { @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); + { + map['id'] = Variable($CategoriesTable.$converterid.toSql(id)); + } map['desc'] = Variable(description); { map['priority'] = @@ -137,7 +140,8 @@ class Category extends DataClass implements Insertable { {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return Category( - id: serializer.fromJson(json['id']), + id: $CategoriesTable.$converterid + .fromJson(serializer.fromJson(json['id'])), description: serializer.fromJson(json['description']), priority: $CategoriesTable.$converterpriority .fromJson(serializer.fromJson(json['priority'])), @@ -154,7 +158,7 @@ class Category extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), + 'id': serializer.toJson($CategoriesTable.$converterid.toJson(id)), 'description': serializer.toJson(description), 'priority': serializer .toJson($CategoriesTable.$converterpriority.toJson(priority)), @@ -164,7 +168,7 @@ class Category extends DataClass implements Insertable { } Category copyWith( - {int? id, + {RowId? id, String? description, CategoryPriority? priority, String? descriptionInUpperCase}) => @@ -200,7 +204,7 @@ class Category extends DataClass implements Insertable { } class CategoriesCompanion extends UpdateCompanion { - final Value id; + final Value id; final Value description; final Value priority; const CategoriesCompanion({ @@ -226,7 +230,7 @@ class CategoriesCompanion extends UpdateCompanion { } CategoriesCompanion copyWith( - {Value? id, + {Value? id, Value? description, Value? priority}) { return CategoriesCompanion( @@ -240,7 +244,7 @@ class CategoriesCompanion extends UpdateCompanion { Map toColumns(bool nullToAbsent) { final map = {}; if (id.present) { - map['id'] = Variable(id.value); + map['id'] = Variable($CategoriesTable.$converterid.toSql(id.value)); } if (description.present) { map['desc'] = Variable(description.value); @@ -271,13 +275,14 @@ class $TodosTableTable extends TodosTable $TodosTableTable(this.attachedDatabase, [this._alias]); static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - hasAutoIncrement: true, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + late final GeneratedColumnWithTypeConverter id = GeneratedColumn< + int>('id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')) + .withConverter($TodosTableTable.$converterid); static const VerificationMeta _titleMeta = const VerificationMeta('title'); @override late final GeneratedColumn title = GeneratedColumn( @@ -328,9 +333,7 @@ class $TodosTableTable extends TodosTable {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } + context.handle(_idMeta, const VerificationResult.success()); if (data.containsKey('title')) { context.handle( _titleMeta, title.isAcceptableOrUnknown(data['title']!, _titleMeta)); @@ -366,8 +369,8 @@ class $TodosTableTable extends TodosTable TodoEntry map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return TodoEntry( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + id: $TodosTableTable.$converterid.fromSql(attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!), title: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}title']), content: attachedDatabase.typeMapping @@ -387,6 +390,8 @@ class $TodosTableTable extends TodosTable return $TodosTableTable(attachedDatabase, alias); } + static JsonTypeConverter2 $converterid = + TypeConverter.extensionType(); static JsonTypeConverter2 $converterstatus = const EnumNameConverter(TodoStatus.values); static JsonTypeConverter2 $converterstatusn = @@ -394,7 +399,7 @@ class $TodosTableTable extends TodosTable } class TodoEntry extends DataClass implements Insertable { - final int id; + final RowId id; final String? title; final String content; final DateTime? targetDate; @@ -410,7 +415,9 @@ class TodoEntry extends DataClass implements Insertable { @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); + { + map['id'] = Variable($TodosTableTable.$converterid.toSql(id)); + } if (!nullToAbsent || title != null) { map['title'] = Variable(title); } @@ -449,7 +456,8 @@ class TodoEntry extends DataClass implements Insertable { {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return TodoEntry( - id: serializer.fromJson(json['id']), + id: $TodosTableTable.$converterid + .fromJson(serializer.fromJson(json['id'])), title: serializer.fromJson(json['title']), content: serializer.fromJson(json['content']), targetDate: serializer.fromJson(json['target_date']), @@ -467,7 +475,7 @@ class TodoEntry extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), + 'id': serializer.toJson($TodosTableTable.$converterid.toJson(id)), 'title': serializer.toJson(title), 'content': serializer.toJson(content), 'target_date': serializer.toJson(targetDate), @@ -478,7 +486,7 @@ class TodoEntry extends DataClass implements Insertable { } TodoEntry copyWith( - {int? id, + {RowId? id, Value title = const Value.absent(), String? content, Value targetDate = const Value.absent(), @@ -521,7 +529,7 @@ class TodoEntry extends DataClass implements Insertable { } class TodosTableCompanion extends UpdateCompanion { - final Value id; + final Value id; final Value title; final Value content; final Value targetDate; @@ -562,7 +570,7 @@ class TodosTableCompanion extends UpdateCompanion { } TodosTableCompanion copyWith( - {Value? id, + {Value? id, Value? title, Value? content, Value? targetDate, @@ -582,7 +590,7 @@ class TodosTableCompanion extends UpdateCompanion { Map toColumns(bool nullToAbsent) { final map = {}; if (id.present) { - map['id'] = Variable(id.value); + map['id'] = Variable($TodosTableTable.$converterid.toSql(id.value)); } if (title.present) { map['title'] = Variable(title.value); @@ -624,13 +632,14 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> { $UsersTable(this.attachedDatabase, [this._alias]); static const VerificationMeta _idMeta = const VerificationMeta('id'); @override - late final GeneratedColumn id = GeneratedColumn( - 'id', aliasedName, false, - hasAutoIncrement: true, - type: DriftSqlType.int, - requiredDuringInsert: false, - defaultConstraints: - GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + late final GeneratedColumnWithTypeConverter id = GeneratedColumn< + int>('id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')) + .withConverter($UsersTable.$converterid); static const VerificationMeta _nameMeta = const VerificationMeta('name'); @override late final GeneratedColumn name = GeneratedColumn( @@ -678,9 +687,7 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> { {bool isInserting = false}) { final context = VerificationContext(); final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } + context.handle(_idMeta, const VerificationResult.success()); if (data.containsKey('name')) { context.handle( _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta)); @@ -714,8 +721,8 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> { User map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return User( - id: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + id: $UsersTable.$converterid.fromSql(attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!), name: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}name'])!, isAwesome: attachedDatabase.typeMapping @@ -731,10 +738,13 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> { $UsersTable createAlias(String alias) { return $UsersTable(attachedDatabase, alias); } + + static JsonTypeConverter2 $converterid = + TypeConverter.extensionType(); } class User extends DataClass implements Insertable { - final int id; + final RowId id; final String name; final bool isAwesome; final Uint8List profilePicture; @@ -748,7 +758,9 @@ class User extends DataClass implements Insertable { @override Map toColumns(bool nullToAbsent) { final map = {}; - map['id'] = Variable(id); + { + map['id'] = Variable($UsersTable.$converterid.toSql(id)); + } map['name'] = Variable(name); map['is_awesome'] = Variable(isAwesome); map['profile_picture'] = Variable(profilePicture); @@ -770,7 +782,8 @@ class User extends DataClass implements Insertable { {ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return User( - id: serializer.fromJson(json['id']), + id: $UsersTable.$converterid + .fromJson(serializer.fromJson(json['id'])), name: serializer.fromJson(json['name']), isAwesome: serializer.fromJson(json['isAwesome']), profilePicture: serializer.fromJson(json['profilePicture']), @@ -785,7 +798,7 @@ class User extends DataClass implements Insertable { Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { - 'id': serializer.toJson(id), + 'id': serializer.toJson($UsersTable.$converterid.toJson(id)), 'name': serializer.toJson(name), 'isAwesome': serializer.toJson(isAwesome), 'profilePicture': serializer.toJson(profilePicture), @@ -794,7 +807,7 @@ class User extends DataClass implements Insertable { } User copyWith( - {int? id, + {RowId? id, String? name, bool? isAwesome, Uint8List? profilePicture, @@ -834,7 +847,7 @@ class User extends DataClass implements Insertable { } class UsersCompanion extends UpdateCompanion { - final Value id; + final Value id; final Value name; final Value isAwesome; final Value profilePicture; @@ -871,7 +884,7 @@ class UsersCompanion extends UpdateCompanion { } UsersCompanion copyWith( - {Value? id, + {Value? id, Value? name, Value? isAwesome, Value? profilePicture, @@ -889,7 +902,7 @@ class UsersCompanion extends UpdateCompanion { Map toColumns(bool nullToAbsent) { final map = {}; if (id.present) { - map['id'] = Variable(id.value); + map['id'] = Variable($UsersTable.$converterid.toSql(id.value)); } if (name.present) { map['name'] = Variable(name.value); @@ -1872,7 +1885,7 @@ abstract class _$TodoDb extends GeneratedDatabase { todosTable, }).map((QueryRow row) => AllTodosWithCategoryResult( row: row, - id: row.read('id'), + id: $TodosTableTable.$converterid.fromSql(row.read('id')), title: row.readNullable('title'), content: row.read('content'), targetDate: row.readNullable('target_date'), @@ -1880,21 +1893,21 @@ abstract class _$TodoDb extends GeneratedDatabase { status: NullAwareTypeConverter.wrapFromSql( $TodosTableTable.$converterstatus, row.readNullable('status')), - catId: row.read('catId'), + catId: $CategoriesTable.$converterid.fromSql(row.read('catId')), catDesc: row.read('catDesc'), )); } - Future deleteTodoById(int var1) { + Future deleteTodoById(RowId var1) { return customUpdate( 'DELETE FROM todos WHERE id = ?1', - variables: [Variable(var1)], + variables: [Variable($TodosTableTable.$converterid.toSql(var1))], updates: {todosTable}, updateKind: UpdateKind.delete, ); } - Selectable withIn(String? var1, String? var2, List var3) { + Selectable withIn(String? var1, String? var2, List var3) { var $arrayStartIndex = 3; final expandedvar3 = $expandVar($arrayStartIndex, var3.length); $arrayStartIndex += var3.length; @@ -1903,18 +1916,19 @@ abstract class _$TodoDb extends GeneratedDatabase { variables: [ Variable(var1), Variable(var2), - for (var $ in var3) Variable($) + for (var $ in var3) + Variable($TodosTableTable.$converterid.toSql($)) ], readsFrom: { todosTable, }).asyncMap(todosTable.mapFromRow); } - Selectable search({required int id}) { + Selectable search({required RowId id}) { return customSelect( 'SELECT * FROM todos WHERE CASE WHEN -1 = ?1 THEN 1 ELSE id = ?1 END', variables: [ - Variable(id) + Variable($TodosTableTable.$converterid.toSql(id)) ], readsFrom: { todosTable, @@ -1949,13 +1963,13 @@ abstract class _$TodoDb extends GeneratedDatabase { } class AllTodosWithCategoryResult extends CustomResultSet { - final int id; + final RowId id; final String? title; final String content; final DateTime? targetDate; final int? category; final TodoStatus? status; - final int catId; + final RowId catId; final String catDesc; AllTodosWithCategoryResult({ required QueryRow row, @@ -2006,11 +2020,11 @@ mixin _$SomeDaoMixin on DatabaseAccessor { $SharedTodosTable get sharedTodos => attachedDatabase.sharedTodos; $TodoWithCategoryViewView get todoWithCategoryView => attachedDatabase.todoWithCategoryView; - Selectable todosForUser({required int user}) { + Selectable todosForUser({required RowId user}) { return customSelect( 'SELECT t.* FROM todos AS t INNER JOIN shared_todos AS st ON st.todo = t.id INNER JOIN users AS u ON u.id = st.user WHERE u.id = ?1', variables: [ - Variable(user) + Variable($UsersTable.$converterid.toSql(user)) ], readsFrom: { todosTable, diff --git a/drift/test/integration_tests/insert_integration_test.dart b/drift/test/integration_tests/insert_integration_test.dart index 153c1975..d4e97006 100644 --- a/drift/test/integration_tests/insert_integration_test.dart +++ b/drift/test/integration_tests/insert_integration_test.dart @@ -109,7 +109,7 @@ void main() { expect( entry, const Category( - id: 1, + id: RowId(1), description: 'Description', priority: CategoryPriority.low, descriptionInUpperCase: 'DESCRIPTION', diff --git a/drift/test/integration_tests/select_integration_test.dart b/drift/test/integration_tests/select_integration_test.dart index 09b85241..e2cd8d09 100644 --- a/drift/test/integration_tests/select_integration_test.dart +++ b/drift/test/integration_tests/select_integration_test.dart @@ -26,7 +26,7 @@ void main() { final rows = await (db.select(db.users) ..orderBy([(_) => OrderingTerm.random()])) .get(); - expect(rows.isSorted((a, b) => a.id.compareTo(b.id)), isFalse); + expect(rows.isSorted((a, b) => a.id.id.compareTo(b.id.id)), isFalse); }); test('can select view', () async { @@ -35,7 +35,7 @@ void main() { await db.todosTable.insertOne(TodosTableCompanion.insert( content: 'some content', title: const Value('title'), - category: Value(category.id))); + category: Value(category.id.id))); final result = await db.todoWithCategoryView.select().getSingle(); expect( diff --git a/drift/test/isolate_test.dart b/drift/test/isolate_test.dart index 665d8299..da8cf9ef 100644 --- a/drift/test/isolate_test.dart +++ b/drift/test/isolate_test.dart @@ -190,7 +190,7 @@ void main() { stream, emits([ Category( - id: 1, + id: RowId(1), description: 'From remote isolate!', priority: CategoryPriority.low, descriptionInUpperCase: 'FROM REMOTE ISOLATE!', @@ -318,7 +318,7 @@ void _runTests(FutureOr Function() spawner, bool terminateIsolate, await database.into(database.todosTable).insert(initialCompanion); await expectLater( stream, - emits(const TodoEntry(id: 1, content: 'my content')), + emits(const TodoEntry(id: RowId(1), content: 'my content')), ); }); diff --git a/drift/test/serialization_test.dart b/drift/test/serialization_test.dart index e277c48a..41b1ec79 100644 --- a/drift/test/serialization_test.dart +++ b/drift/test/serialization_test.dart @@ -6,7 +6,7 @@ import 'generated/todos.dart'; final DateTime _someDate = DateTime(2019, 06, 08); final TodoEntry _someTodoEntry = TodoEntry( - id: 3, + id: RowId(3), title: null, content: 'content', targetDate: _someDate, diff --git a/drift/test/test_utils/test_utils.mocks.dart b/drift/test/test_utils/test_utils.mocks.dart index 0d052c05..03d207d3 100644 --- a/drift/test/test_utils/test_utils.mocks.dart +++ b/drift/test/test_utils/test_utils.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.4.4 from annotations +// Mocks generated by Mockito 5.4.3 from annotations // in drift/test/test_utils/test_utils.dart. // Do not manually edit this file.