diff --git a/drift_dev/lib/src/analysis/resolver/resolver.dart b/drift_dev/lib/src/analysis/resolver/resolver.dart index e1ee5b28..9a325ad2 100644 --- a/drift_dev/lib/src/analysis/resolver/resolver.dart +++ b/drift_dev/lib/src/analysis/resolver/resolver.dart @@ -265,7 +265,7 @@ abstract class LocalElementResolver { } else { // todo: Better type description in error message reportError( - createError('Expected a $T, but got a ${element.runtimeType}')); + createError('Expected a $E, but got a ${element.runtimeType}')); } } else { reportErrorForUnresolvedReference(result, createError); diff --git a/drift_dev/lib/src/backends/build/analyzer.dart b/drift_dev/lib/src/backends/build/analyzer.dart index c34ddd33..70ac0890 100644 --- a/drift_dev/lib/src/backends/build/analyzer.dart +++ b/drift_dev/lib/src/backends/build/analyzer.dart @@ -54,7 +54,7 @@ class DriftDiscover extends Builder { 'kind': entry.kind.name, 'name': entry.ownId.name, if (entry is DiscoveredDartElement) - 'dart_name': entry.dartElement.name, + 'dart_name': entry.dartElementName, } ] }), diff --git a/drift_dev/test/cli/schema/dump_test.dart b/drift_dev/test/cli/schema/dump_test.dart index a146d15a..6323fb6a 100644 --- a/drift_dev/test/cli/schema/dump_test.dart +++ b/drift_dev/test/cli/schema/dump_test.dart @@ -34,7 +34,7 @@ void main() { { "_meta": { "description": "This file contains a serialized version of schema entities for drift.", - "version": "1.0.0" + "version": "1.1.0" }, "options": { "store_date_time_values_as_text": false diff --git a/drift_dev/test/writer/table_writer_test.dart b/drift_dev/test/writer/table_writer_test.dart index 07beb236..bba4a44c 100644 --- a/drift_dev/test/writer/table_writer_test.dart +++ b/drift_dev/test/writer/table_writer_test.dart @@ -33,4 +33,54 @@ class Tags extends Table { ), }, result.dartOutputs, result.writer); }); + + test('generates index attached to table in monolithic build', () async { + final result = await emulateDriftBuild( + inputs: { + 'a|lib/a.dart': ''' +import 'package:drift/drift.dart'; + +@TableIndex(name: 'tag_id', columns: {#id}) +class Tags extends Table { + IntColumn get id => integer().autoIncrement()(); +} + +@DriftDatabase(tables: [Tags]) +class MyDatabase {} +''', + }, + ); + + checkOutputs({ + 'a|lib/a.drift.dart': decodedMatches(allOf( + contains( + "Index tagId = Index('tag_id', 'CREATE INDEX tag_id ON tags (id)')", + ), + contains('allSchemaEntities => [tags, tagId]'), + )), + }, result.dartOutputs, result.writer); + }); + + test('generates index attached to table in modular build', () async { + final result = await emulateDriftBuild( + inputs: { + 'a|lib/a.dart': ''' +import 'package:drift/drift.dart'; + +@TableIndex(name: 'tag_id', columns: {#id}) +class Tags extends Table { + IntColumn get id => integer().autoIncrement()(); +} +''', + }, + modularBuild: true, + ); + + checkOutputs({ + 'a|lib/a.drift.dart': decodedMatches( + contains( + "i0.Index get tagId => i0.Index('tag_id', 'CREATE INDEX tag_id ON tags (id)')"), + ), + }, result.dartOutputs, result.writer); + }); } diff --git a/examples/migrations_example/drift_migrations/drift_schema_v10.json b/examples/migrations_example/drift_migrations/drift_schema_v10.json new file mode 100644 index 00000000..9518155a --- /dev/null +++ b/examples/migrations_example/drift_migrations/drift_schema_v10.json @@ -0,0 +1 @@ +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.1.0"},"options":{"store_date_time_values_as_text":true},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"users","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"defaultConstraints":"PRIMARY KEY AUTOINCREMENT","default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const Constant('name')","default_client_dart":null,"dsl_features":[]},{"name":"birthday","getter_name":"birthday","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"next_user","getter_name":"nextUser","moor_type":"int","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES users (id)","default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":false,"constraints":["CHECK (LENGTH(name) < 10)"],"unique_keys":[["name","birthday"]]}},{"id":1,"references":[0],"type":"table","data":{"name":"groups","was_declared_in_moor":true,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"title","getter_name":"title","moor_type":"string","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"deleted","getter_name":"deleted","moor_type":"bool","nullable":true,"customConstraints":"DEFAULT FALSE","default_dart":"const CustomExpression('FALSE')","default_client_dart":null,"dsl_features":[]},{"name":"owner","getter_name":"owner","moor_type":"int","nullable":false,"customConstraints":"NOT NULL REFERENCES users(id)","default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":false,"constraints":["PRIMARY KEY(id)"],"explicit_pk":["id"]}},{"id":2,"references":[],"type":"table","data":{"name":"notes","was_declared_in_moor":true,"columns":[{"name":"title","getter_name":"title","moor_type":"string","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"string","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"search_terms","getter_name":"searchTerms","moor_type":"string","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":true,"create_virtual_stmt":"CREATE VIRTUAL TABLE \"notes\" USING fts5(title, content, search_terms, tokenize = \"unicode61 tokenchars '.'\")","without_rowid":false,"constraints":[]}},{"id":3,"references":[0,1],"type":"view","data":{"name":"group_count","sql":"CREATE VIEW group_count AS SELECT users.*, (SELECT COUNT(*) FROM \"groups\" WHERE owner = users.id) AS group_count FROM users;","dart_info_name":"GroupCount","columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"birthday","getter_name":"birthday","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"next_user","getter_name":"nextUser","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"group_count","getter_name":"groupCount","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}]}},{"id":4,"references":[0],"type":"index","data":{"on":0,"name":"user_name","sql":null,"unique":false,"columns":["name"]}}]} \ No newline at end of file diff --git a/examples/migrations_example/lib/database.dart b/examples/migrations_example/lib/database.dart index f933fcc5..2476b51d 100644 --- a/examples/migrations_example/lib/database.dart +++ b/examples/migrations_example/lib/database.dart @@ -16,7 +16,7 @@ const kDebugMode = true; include: {'tables.drift'}, ) class Database extends _$Database { - static const latestSchemaVersion = 9; + static const latestSchemaVersion = 10; @override int get schemaVersion => latestSchemaVersion; @@ -100,5 +100,9 @@ class Database extends _$Database { // Added a check to the users table await m.alterTable(TableMigration(schema.users)); }, + from9To10: (m, schema) async { + // Added an index to the users table + await m.create(schema.userName); + }, ); } diff --git a/examples/migrations_example/lib/database.g.dart b/examples/migrations_example/lib/database.g.dart index ef35da42..03050074 100644 --- a/examples/migrations_example/lib/database.g.dart +++ b/examples/migrations_example/lib/database.g.dart @@ -885,12 +885,14 @@ abstract class _$Database extends GeneratedDatabase { late final Groups groups = Groups(this); late final Notes notes = Notes(this); late final GroupCount groupCount = GroupCount(this); + late final Index userName = + Index('user_name', 'CREATE INDEX user_name ON users (name)'); @override Iterable> get allTables => allSchemaEntities.whereType>(); @override List get allSchemaEntities => - [users, groups, notes, groupCount]; + [users, groups, notes, groupCount, userName]; @override DriftDatabaseOptions get options => const DriftDatabaseOptions(storeDateTimeAsText: true); diff --git a/examples/migrations_example/lib/src/versions.dart b/examples/migrations_example/lib/src/versions.dart index ef9aefdd..74e95d05 100644 --- a/examples/migrations_example/lib/src/versions.dart +++ b/examples/migrations_example/lib/src/versions.dart @@ -585,6 +585,84 @@ i1.GeneratedColumn _column_17(String aliasedName) => i1.GeneratedColumn('owner', aliasedName, false, type: i1.DriftSqlType.int, $customConstraints: 'NOT NULL REFERENCES users(id)'); + +final class _S10 extends i0.VersionedSchema { + _S10({required super.database}) : super(version: 10); + @override + late final List entities = [ + users, + groups, + notes, + groupCount, + userName, + ]; + late final Shape4 users = Shape4( + source: i0.VersionedTable( + entityName: 'users', + withoutRowId: false, + isStrict: false, + tableConstraints: [ + 'UNIQUE(name, birthday)', + 'CHECK (LENGTH(name) < 10)', + ], + columns: [ + _column_0, + _column_6, + _column_11, + _column_7, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape1 groups = Shape1( + source: i0.VersionedTable( + entityName: 'groups', + withoutRowId: false, + isStrict: false, + tableConstraints: [ + 'PRIMARY KEY(id)', + ], + columns: [ + _column_2, + _column_3, + _column_16, + _column_17, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape6 notes = Shape6( + source: i0.VersionedVirtualTable( + entityName: 'notes', + moduleAndArgs: + 'fts5(title, content, search_terms, tokenize = "unicode61 tokenchars \'.\'")', + columns: [ + _column_12, + _column_13, + _column_14, + ], + attachedDatabase: database, + ), + alias: null); + late final Shape5 groupCount = Shape5( + source: i0.VersionedView( + entityName: 'group_count', + createViewStmt: + 'CREATE VIEW group_count AS SELECT users.*, (SELECT COUNT(*) FROM "groups" WHERE owner = users.id) AS group_count FROM users;', + columns: [ + _column_8, + _column_1, + _column_11, + _column_9, + _column_10, + ], + attachedDatabase: database, + ), + alias: null); + final i1.Index userName = + i1.Index('user_name', 'CREATE INDEX user_name ON users (name)'); +} + i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, _S2 schema) from1To2, required Future Function(i1.Migrator m, _S3 schema) from2To3, @@ -594,6 +672,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, _S7 schema) from6To7, required Future Function(i1.Migrator m, _S8 schema) from7To8, required Future Function(i1.Migrator m, _S9 schema) from8To9, + required Future Function(i1.Migrator m, _S10 schema) from9To10, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -637,6 +716,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from8To9(migrator, schema); return 9; + case 9: + final schema = _S10(database: database); + final migrator = i1.Migrator(database, schema); + await from9To10(migrator, schema); + return 10; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -652,6 +736,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, _S7 schema) from6To7, required Future Function(i1.Migrator m, _S8 schema) from7To8, required Future Function(i1.Migrator m, _S9 schema) from8To9, + required Future Function(i1.Migrator m, _S10 schema) from9To10, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( @@ -663,4 +748,5 @@ i1.OnUpgrade stepByStep({ from6To7: from6To7, from7To8: from7To8, from8To9: from8To9, + from9To10: from9To10, )); diff --git a/examples/migrations_example/lib/tables.dart b/examples/migrations_example/lib/tables.dart index ef80b6b4..f9923cba 100644 --- a/examples/migrations_example/lib/tables.dart +++ b/examples/migrations_example/lib/tables.dart @@ -1,5 +1,7 @@ import 'package:drift/drift.dart'; +// This index on the user table has been added in schema version 10 +@TableIndex(name: 'user_name', columns: {#name}) class Users extends Table { IntColumn get id => integer().autoIncrement()(); diff --git a/examples/migrations_example/test/generated/schema.dart b/examples/migrations_example/test/generated/schema.dart index 28f662de..5b68fcc5 100644 --- a/examples/migrations_example/test/generated/schema.dart +++ b/examples/migrations_example/test/generated/schema.dart @@ -12,6 +12,7 @@ import 'schema_v6.dart' as v6; import 'schema_v7.dart' as v7; import 'schema_v8.dart' as v8; import 'schema_v9.dart' as v9; +import 'schema_v10.dart' as v10; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -35,9 +36,11 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v8.DatabaseAtV8(db); case 9: return v9.DatabaseAtV9(db); + case 10: + return v10.DatabaseAtV10(db); default: throw MissingSchemaException( - version, const {1, 2, 3, 4, 5, 6, 7, 8, 9}); + version, const {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); } } } diff --git a/examples/migrations_example/test/generated/schema_v10.dart b/examples/migrations_example/test/generated/schema_v10.dart new file mode 100644 index 00000000..2ad771ef --- /dev/null +++ b/examples/migrations_example/test/generated/schema_v10.dart @@ -0,0 +1,805 @@ +// GENERATED CODE, DO NOT EDIT BY HAND. +// ignore_for_file: type=lint +//@dart=2.12 +import 'package:drift/drift.dart'; + +class Users extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Users(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT')); + late final GeneratedColumn name = GeneratedColumn( + 'name', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const Constant('name')); + late final GeneratedColumn birthday = GeneratedColumn( + 'birthday', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + late final GeneratedColumn nextUser = GeneratedColumn( + 'next_user', aliasedName, true, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultConstraints: + GeneratedColumn.constraintIsAlways('REFERENCES users (id)')); + @override + List get $columns => [id, name, birthday, nextUser]; + @override + String get aliasedName => _alias ?? 'users'; + @override + String get actualTableName => 'users'; + @override + Set get $primaryKey => {id}; + @override + List> get uniqueKeys => [ + {name, birthday}, + ]; + @override + UsersData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UsersData( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + name: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}name'])!, + birthday: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}birthday']), + nextUser: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}next_user']), + ); + } + + @override + Users createAlias(String alias) { + return Users(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['CHECK (LENGTH(name) < 10)']; +} + +class UsersData extends DataClass implements Insertable { + final int id; + final String name; + final DateTime? birthday; + final int? nextUser; + const UsersData( + {required this.id, required this.name, this.birthday, this.nextUser}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + if (!nullToAbsent || birthday != null) { + map['birthday'] = Variable(birthday); + } + if (!nullToAbsent || nextUser != null) { + map['next_user'] = Variable(nextUser); + } + return map; + } + + UsersCompanion toCompanion(bool nullToAbsent) { + return UsersCompanion( + id: Value(id), + name: Value(name), + birthday: birthday == null && nullToAbsent + ? const Value.absent() + : Value(birthday), + nextUser: nextUser == null && nullToAbsent + ? const Value.absent() + : Value(nextUser), + ); + } + + factory UsersData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UsersData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + birthday: serializer.fromJson(json['birthday']), + nextUser: serializer.fromJson(json['nextUser']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'birthday': serializer.toJson(birthday), + 'nextUser': serializer.toJson(nextUser), + }; + } + + UsersData copyWith( + {int? id, + String? name, + Value birthday = const Value.absent(), + Value nextUser = const Value.absent()}) => + UsersData( + id: id ?? this.id, + name: name ?? this.name, + birthday: birthday.present ? birthday.value : this.birthday, + nextUser: nextUser.present ? nextUser.value : this.nextUser, + ); + @override + String toString() { + return (StringBuffer('UsersData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('birthday: $birthday, ') + ..write('nextUser: $nextUser') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name, birthday, nextUser); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UsersData && + other.id == this.id && + other.name == this.name && + other.birthday == this.birthday && + other.nextUser == this.nextUser); +} + +class UsersCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value birthday; + final Value nextUser; + const UsersCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.birthday = const Value.absent(), + this.nextUser = const Value.absent(), + }); + UsersCompanion.insert({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.birthday = const Value.absent(), + this.nextUser = const Value.absent(), + }); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? birthday, + Expression? nextUser, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (birthday != null) 'birthday': birthday, + if (nextUser != null) 'next_user': nextUser, + }); + } + + UsersCompanion copyWith( + {Value? id, + Value? name, + Value? birthday, + Value? nextUser}) { + return UsersCompanion( + id: id ?? this.id, + name: name ?? this.name, + birthday: birthday ?? this.birthday, + nextUser: nextUser ?? this.nextUser, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (birthday.present) { + map['birthday'] = Variable(birthday.value); + } + if (nextUser.present) { + map['next_user'] = Variable(nextUser.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UsersCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('birthday: $birthday, ') + ..write('nextUser: $nextUser') + ..write(')')) + .toString(); + } +} + +class Groups extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Groups(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL'); + late final GeneratedColumn title = GeneratedColumn( + 'title', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL'); + late final GeneratedColumn deleted = GeneratedColumn( + 'deleted', aliasedName, true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + $customConstraints: 'DEFAULT FALSE', + defaultValue: const CustomExpression('FALSE')); + late final GeneratedColumn owner = GeneratedColumn( + 'owner', aliasedName, false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES users(id)'); + @override + List get $columns => [id, title, deleted, owner]; + @override + String get aliasedName => _alias ?? 'groups'; + @override + String get actualTableName => 'groups'; + @override + Set get $primaryKey => {id}; + @override + GroupsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupsData( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + title: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}title'])!, + deleted: attachedDatabase.typeMapping + .read(DriftSqlType.bool, data['${effectivePrefix}deleted']), + owner: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}owner'])!, + ); + } + + @override + Groups createAlias(String alias) { + return Groups(attachedDatabase, alias); + } + + @override + List get customConstraints => const ['PRIMARY KEY(id)']; + @override + bool get dontWriteConstraints => true; +} + +class GroupsData extends DataClass implements Insertable { + final int id; + final String title; + final bool? deleted; + final int owner; + const GroupsData( + {required this.id, + required this.title, + this.deleted, + required this.owner}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['title'] = Variable(title); + if (!nullToAbsent || deleted != null) { + map['deleted'] = Variable(deleted); + } + map['owner'] = Variable(owner); + return map; + } + + GroupsCompanion toCompanion(bool nullToAbsent) { + return GroupsCompanion( + id: Value(id), + title: Value(title), + deleted: deleted == null && nullToAbsent + ? const Value.absent() + : Value(deleted), + owner: Value(owner), + ); + } + + factory GroupsData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupsData( + id: serializer.fromJson(json['id']), + title: serializer.fromJson(json['title']), + deleted: serializer.fromJson(json['deleted']), + owner: serializer.fromJson(json['owner']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'title': serializer.toJson(title), + 'deleted': serializer.toJson(deleted), + 'owner': serializer.toJson(owner), + }; + } + + GroupsData copyWith( + {int? id, + String? title, + Value deleted = const Value.absent(), + int? owner}) => + GroupsData( + id: id ?? this.id, + title: title ?? this.title, + deleted: deleted.present ? deleted.value : this.deleted, + owner: owner ?? this.owner, + ); + @override + String toString() { + return (StringBuffer('GroupsData(') + ..write('id: $id, ') + ..write('title: $title, ') + ..write('deleted: $deleted, ') + ..write('owner: $owner') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, title, deleted, owner); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupsData && + other.id == this.id && + other.title == this.title && + other.deleted == this.deleted && + other.owner == this.owner); +} + +class GroupsCompanion extends UpdateCompanion { + final Value id; + final Value title; + final Value deleted; + final Value owner; + const GroupsCompanion({ + this.id = const Value.absent(), + this.title = const Value.absent(), + this.deleted = const Value.absent(), + this.owner = const Value.absent(), + }); + GroupsCompanion.insert({ + this.id = const Value.absent(), + required String title, + this.deleted = const Value.absent(), + required int owner, + }) : title = Value(title), + owner = Value(owner); + static Insertable custom({ + Expression? id, + Expression? title, + Expression? deleted, + Expression? owner, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (title != null) 'title': title, + if (deleted != null) 'deleted': deleted, + if (owner != null) 'owner': owner, + }); + } + + GroupsCompanion copyWith( + {Value? id, + Value? title, + Value? deleted, + Value? owner}) { + return GroupsCompanion( + id: id ?? this.id, + title: title ?? this.title, + deleted: deleted ?? this.deleted, + owner: owner ?? this.owner, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (title.present) { + map['title'] = Variable(title.value); + } + if (deleted.present) { + map['deleted'] = Variable(deleted.value); + } + if (owner.present) { + map['owner'] = Variable(owner.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('GroupsCompanion(') + ..write('id: $id, ') + ..write('title: $title, ') + ..write('deleted: $deleted, ') + ..write('owner: $owner') + ..write(')')) + .toString(); + } +} + +class Notes extends Table + with TableInfo, VirtualTableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Notes(this.attachedDatabase, [this._alias]); + late final GeneratedColumn title = GeneratedColumn( + 'title', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: ''); + late final GeneratedColumn content = GeneratedColumn( + 'content', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: ''); + late final GeneratedColumn searchTerms = GeneratedColumn( + 'search_terms', aliasedName, false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: ''); + @override + List get $columns => [title, content, searchTerms]; + @override + String get aliasedName => _alias ?? 'notes'; + @override + String get actualTableName => 'notes'; + @override + Set get $primaryKey => const {}; + @override + NotesData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return NotesData( + title: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}title'])!, + content: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}content'])!, + searchTerms: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}search_terms'])!, + ); + } + + @override + Notes createAlias(String alias) { + return Notes(attachedDatabase, alias); + } + + @override + String get moduleAndArgs => + 'fts5(title, content, search_terms, tokenize = "unicode61 tokenchars \'.\'")'; +} + +class NotesData extends DataClass implements Insertable { + final String title; + final String content; + final String searchTerms; + const NotesData( + {required this.title, required this.content, required this.searchTerms}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['title'] = Variable(title); + map['content'] = Variable(content); + map['search_terms'] = Variable(searchTerms); + return map; + } + + NotesCompanion toCompanion(bool nullToAbsent) { + return NotesCompanion( + title: Value(title), + content: Value(content), + searchTerms: Value(searchTerms), + ); + } + + factory NotesData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return NotesData( + title: serializer.fromJson(json['title']), + content: serializer.fromJson(json['content']), + searchTerms: serializer.fromJson(json['searchTerms']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'title': serializer.toJson(title), + 'content': serializer.toJson(content), + 'searchTerms': serializer.toJson(searchTerms), + }; + } + + NotesData copyWith({String? title, String? content, String? searchTerms}) => + NotesData( + title: title ?? this.title, + content: content ?? this.content, + searchTerms: searchTerms ?? this.searchTerms, + ); + @override + String toString() { + return (StringBuffer('NotesData(') + ..write('title: $title, ') + ..write('content: $content, ') + ..write('searchTerms: $searchTerms') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(title, content, searchTerms); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is NotesData && + other.title == this.title && + other.content == this.content && + other.searchTerms == this.searchTerms); +} + +class NotesCompanion extends UpdateCompanion { + final Value title; + final Value content; + final Value searchTerms; + final Value rowid; + const NotesCompanion({ + this.title = const Value.absent(), + this.content = const Value.absent(), + this.searchTerms = const Value.absent(), + this.rowid = const Value.absent(), + }); + NotesCompanion.insert({ + required String title, + required String content, + required String searchTerms, + this.rowid = const Value.absent(), + }) : title = Value(title), + content = Value(content), + searchTerms = Value(searchTerms); + static Insertable custom({ + Expression? title, + Expression? content, + Expression? searchTerms, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (title != null) 'title': title, + if (content != null) 'content': content, + if (searchTerms != null) 'search_terms': searchTerms, + if (rowid != null) 'rowid': rowid, + }); + } + + NotesCompanion copyWith( + {Value? title, + Value? content, + Value? searchTerms, + Value? rowid}) { + return NotesCompanion( + title: title ?? this.title, + content: content ?? this.content, + searchTerms: searchTerms ?? this.searchTerms, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (title.present) { + map['title'] = Variable(title.value); + } + if (content.present) { + map['content'] = Variable(content.value); + } + if (searchTerms.present) { + map['search_terms'] = Variable(searchTerms.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('NotesCompanion(') + ..write('title: $title, ') + ..write('content: $content, ') + ..write('searchTerms: $searchTerms, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + +class GroupCountData extends DataClass { + final int id; + final String name; + final DateTime? birthday; + final int? nextUser; + final int groupCount; + const GroupCountData( + {required this.id, + required this.name, + this.birthday, + this.nextUser, + required this.groupCount}); + factory GroupCountData.fromJson(Map json, + {ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return GroupCountData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + birthday: serializer.fromJson(json['birthday']), + nextUser: serializer.fromJson(json['nextUser']), + groupCount: serializer.fromJson(json['groupCount']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'birthday': serializer.toJson(birthday), + 'nextUser': serializer.toJson(nextUser), + 'groupCount': serializer.toJson(groupCount), + }; + } + + GroupCountData copyWith( + {int? id, + String? name, + Value birthday = const Value.absent(), + Value nextUser = const Value.absent(), + int? groupCount}) => + GroupCountData( + id: id ?? this.id, + name: name ?? this.name, + birthday: birthday.present ? birthday.value : this.birthday, + nextUser: nextUser.present ? nextUser.value : this.nextUser, + groupCount: groupCount ?? this.groupCount, + ); + @override + String toString() { + return (StringBuffer('GroupCountData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('birthday: $birthday, ') + ..write('nextUser: $nextUser, ') + ..write('groupCount: $groupCount') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, name, birthday, nextUser, groupCount); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is GroupCountData && + other.id == this.id && + other.name == this.name && + other.birthday == this.birthday && + other.nextUser == this.nextUser && + other.groupCount == this.groupCount); +} + +class GroupCount extends ViewInfo + implements HasResultSet { + final String? _alias; + @override + final DatabaseAtV10 attachedDatabase; + GroupCount(this.attachedDatabase, [this._alias]); + @override + List get $columns => + [id, name, birthday, nextUser, groupCount]; + @override + String get aliasedName => _alias ?? entityName; + @override + String get entityName => 'group_count'; + @override + Map get createViewStatements => { + SqlDialect.sqlite: + 'CREATE VIEW group_count AS SELECT users.*, (SELECT COUNT(*) FROM "groups" WHERE owner = users.id) AS group_count FROM users;' + }; + @override + GroupCount get asDslTable => this; + @override + GroupCountData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return GroupCountData( + id: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}id'])!, + name: attachedDatabase.typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}name'])!, + birthday: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}birthday']), + nextUser: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}next_user']), + groupCount: attachedDatabase.typeMapping + .read(DriftSqlType.int, data['${effectivePrefix}group_count'])!, + ); + } + + late final GeneratedColumn id = + GeneratedColumn('id', aliasedName, false, type: DriftSqlType.int); + late final GeneratedColumn name = GeneratedColumn( + 'name', aliasedName, false, + type: DriftSqlType.string); + late final GeneratedColumn birthday = GeneratedColumn( + 'birthday', aliasedName, true, + type: DriftSqlType.dateTime); + late final GeneratedColumn nextUser = GeneratedColumn( + 'next_user', aliasedName, true, + type: DriftSqlType.int); + late final GeneratedColumn groupCount = GeneratedColumn( + 'group_count', aliasedName, false, + type: DriftSqlType.int); + @override + GroupCount createAlias(String alias) { + return GroupCount(attachedDatabase, alias); + } + + @override + Query? get query => null; + @override + Set get readTables => const {}; +} + +class DatabaseAtV10 extends GeneratedDatabase { + DatabaseAtV10(QueryExecutor e) : super(e); + late final Users users = Users(this); + late final Groups groups = Groups(this); + late final Notes notes = Notes(this); + late final GroupCount groupCount = GroupCount(this); + late final Index userName = + Index('user_name', 'CREATE INDEX user_name ON users (name)'); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => + [users, groups, notes, groupCount, userName]; + @override + int get schemaVersion => 10; + @override + DriftDatabaseOptions get options => + const DriftDatabaseOptions(storeDateTimeAsText: true); +}