mirror of https://github.com/AMT-Cheif/drift.git
Extract custom Dart table constraints into schema
This commit is contained in:
parent
add680b8bf
commit
657b68ab76
|
@ -272,38 +272,40 @@ class Migrator {
|
|||
|
||||
final dslTable = table.asDslTable;
|
||||
|
||||
// we're in a bit of a hacky situation where we don't write the primary
|
||||
// as table constraint if it has already been written on a primary key
|
||||
// column, even though that column appears in table.$primaryKey because we
|
||||
// need to know all primary keys for the update(table).replace(row) API
|
||||
final hasPrimaryKey = table.$primaryKey.isNotEmpty;
|
||||
final dontWritePk = dslTable.dontWriteConstraints || hasAutoIncrement;
|
||||
if (hasPrimaryKey && !dontWritePk) {
|
||||
context.buffer.write(', PRIMARY KEY (');
|
||||
final pkList = table.$primaryKey.toList(growable: false);
|
||||
for (var i = 0; i < pkList.length; i++) {
|
||||
final column = pkList[i];
|
||||
if (!dslTable.dontWriteConstraints) {
|
||||
final hasPrimaryKey = table.$primaryKey.isNotEmpty;
|
||||
|
||||
context.buffer.write(column.escapedName);
|
||||
|
||||
if (i != pkList.length - 1) context.buffer.write(', ');
|
||||
}
|
||||
context.buffer.write(')');
|
||||
}
|
||||
|
||||
if (table.uniqueKeys.isNotEmpty) {
|
||||
for (final key in table.uniqueKeys) {
|
||||
context.buffer.write(', UNIQUE (');
|
||||
final uqList = key.toList(growable: false);
|
||||
for (var i = 0; i < uqList.length; i++) {
|
||||
final column = uqList[i];
|
||||
// we're in a bit of a hacky situation where we don't write the primary
|
||||
// as table constraint if it has already been written on a primary key
|
||||
// column, even though that column appears in table.$primaryKey because we
|
||||
// need to know all primary keys for the update(table).replace(row) API
|
||||
if (hasPrimaryKey && !hasAutoIncrement) {
|
||||
context.buffer.write(', PRIMARY KEY (');
|
||||
final pkList = table.$primaryKey.toList(growable: false);
|
||||
for (var i = 0; i < pkList.length; i++) {
|
||||
final column = pkList[i];
|
||||
|
||||
context.buffer.write(column.escapedName);
|
||||
|
||||
if (i != uqList.length - 1) context.buffer.write(', ');
|
||||
if (i != pkList.length - 1) context.buffer.write(', ');
|
||||
}
|
||||
context.buffer.write(')');
|
||||
}
|
||||
|
||||
if (table.uniqueKeys.isNotEmpty) {
|
||||
for (final key in table.uniqueKeys) {
|
||||
context.buffer.write(', UNIQUE (');
|
||||
final uqList = key.toList(growable: false);
|
||||
for (var i = 0; i < uqList.length; i++) {
|
||||
final column = uqList[i];
|
||||
|
||||
context.buffer.write(column.escapedName);
|
||||
|
||||
if (i != uqList.length - 1) context.buffer.write(', ');
|
||||
}
|
||||
context.buffer.write(')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final constraints = dslTable.customConstraints;
|
||||
|
|
|
@ -1029,6 +1029,10 @@ class Mytable extends Table with TableInfo<Mytable, MytableData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {someid};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [
|
||||
{sometext, isInserting},
|
||||
];
|
||||
@override
|
||||
MytableData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return MytableData(
|
||||
|
@ -1049,7 +1053,8 @@ class Mytable extends Table with TableInfo<Mytable, MytableData> {
|
|||
}
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => const ['PRIMARY KEY(someid DESC)'];
|
||||
List<String> get customConstraints =>
|
||||
const ['PRIMARY KEY(someid DESC)', 'UNIQUE(sometext, is_inserting)'];
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ CREATE TABLE mytable (
|
|||
sometext TEXT,
|
||||
is_inserting BOOLEAN,
|
||||
somedate DATETIME,
|
||||
PRIMARY KEY (someid DESC)
|
||||
PRIMARY KEY (someid DESC),
|
||||
UNIQUE (sometext, is_inserting)
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE email USING fts5(sender, title, body) AS EMail;
|
||||
|
|
|
@ -29,7 +29,8 @@ const _createMyTable = 'CREATE TABLE IF NOT EXISTS "mytable" ('
|
|||
'"sometext" TEXT, '
|
||||
'"is_inserting" INTEGER, '
|
||||
'"somedate" TEXT, '
|
||||
'PRIMARY KEY(someid DESC)'
|
||||
'PRIMARY KEY(someid DESC), '
|
||||
'UNIQUE(sometext, is_inserting)'
|
||||
');';
|
||||
|
||||
const _createEmail = 'CREATE VIRTUAL TABLE IF NOT EXISTS "email" USING '
|
||||
|
|
|
@ -61,6 +61,7 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
|
|||
for (final uniqueKey in uniqueKeys ?? const <Set<DriftColumn>>[])
|
||||
UniqueColumns(uniqueKey),
|
||||
],
|
||||
overrideTableConstraints: await _readCustomConstraints(element),
|
||||
withoutRowId: await _overrideWithoutRowId(element) ?? false,
|
||||
);
|
||||
|
||||
|
@ -330,4 +331,44 @@ class DartTableResolver extends LocalElementResolver<DiscoveredDartTable> {
|
|||
MethodDeclaration declaration, Element element) async {
|
||||
return ColumnParser(this).parse(declaration, element);
|
||||
}
|
||||
|
||||
Future<List<String>> _readCustomConstraints(ClassElement element) async {
|
||||
final customConstraints =
|
||||
element.lookUpGetter('customConstraints', element.library);
|
||||
|
||||
if (customConstraints == null || customConstraints.isFromDefaultTable) {
|
||||
// Does not define custom constraints
|
||||
return const [];
|
||||
}
|
||||
|
||||
final ast = await resolver.driver.backend
|
||||
.loadElementDeclaration(customConstraints) as MethodDeclaration;
|
||||
final body = ast.body;
|
||||
if (body is! ExpressionFunctionBody) {
|
||||
reportError(DriftAnalysisError.forDartElement(customConstraints,
|
||||
'This must return a list literal with the => syntax'));
|
||||
return const [];
|
||||
}
|
||||
final expression = body.expression;
|
||||
final foundConstraints = <String>[];
|
||||
|
||||
if (expression is ListLiteral) {
|
||||
for (final entry in expression.elements) {
|
||||
if (entry is StringLiteral) {
|
||||
final value = entry.stringValue;
|
||||
if (value != null) {
|
||||
foundConstraints.add(value);
|
||||
}
|
||||
} else {
|
||||
reportError(DriftAnalysisError.inDartAst(
|
||||
element, entry, 'This must be a string literal.'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reportError(DriftAnalysisError.forDartElement(
|
||||
customConstraints, 'This must return a list literal!'));
|
||||
}
|
||||
|
||||
return foundConstraints;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -507,7 +507,12 @@ class TableWriter extends TableOrViewWriter {
|
|||
..write('bool get isStrict => true;\n');
|
||||
}
|
||||
|
||||
if (table.overrideTableConstraints != null) {
|
||||
// For Dart tables, the user already overrides the `customConstraints`
|
||||
// getter in the source. So, since we extend that class by default, there's
|
||||
// no need to override them again.
|
||||
final writeTableConstraints = table.definingDartClass == null ||
|
||||
scope.generationOptions.forSchema != null;
|
||||
if (writeTableConstraints && table.overrideTableConstraints != null) {
|
||||
final value =
|
||||
table.overrideTableConstraints!.map(asDartLiteral).join(', ');
|
||||
|
||||
|
|
|
@ -288,4 +288,43 @@ class InvalidConstraints extends Table {
|
|||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('reads custom constraints from table', () async {
|
||||
final backend = TestBackend.inTest({
|
||||
'a|lib/a.dart': '''
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
class BadTable extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => constructConstraints();
|
||||
}
|
||||
|
||||
class WithConstraints extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => [
|
||||
1, 'two', 'three'
|
||||
];
|
||||
}
|
||||
'''
|
||||
});
|
||||
|
||||
final state = await backend.analyze('package:a/a.dart');
|
||||
final badTable = state.analysis[state.id('bad_table')]!;
|
||||
final withConstraints = state.analysis[state.id('with_constraints')]!;
|
||||
|
||||
expect((badTable.result as DriftTable).overrideTableConstraints, []);
|
||||
//expect(withConstraints.overrideTableConstraints, ['two', 'three']);
|
||||
|
||||
expect(state.errorsDuringDiscovery, isEmpty);
|
||||
expect(badTable.errorsDuringAnalysis, [
|
||||
isDriftError('This must return a list literal!')
|
||||
.withSpan('customConstraints')
|
||||
]);
|
||||
expect(withConstraints.errorsDuringAnalysis,
|
||||
[isDriftError('This must be a string literal.').withSpan('1')]);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.0.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":"ColumnType.integer","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":"ColumnType.text","nullable":false,"customConstraints":null,"default_dart":"const Constant('name')","default_client_dart":null,"dsl_features":[]},{"name":"birthday","getter_name":"birthday","moor_type":"ColumnType.datetime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"next_user","getter_name":"nextUser","moor_type":"ColumnType.integer","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":"ColumnType.integer","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"title","getter_name":"title","moor_type":"ColumnType.text","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"deleted","getter_name":"deleted","moor_type":"ColumnType.boolean","nullable":true,"customConstraints":"DEFAULT FALSE","default_dart":"const CustomExpression('FALSE')","default_client_dart":null,"dsl_features":[]},{"name":"owner","getter_name":"owner","moor_type":"ColumnType.integer","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":"ColumnType.text","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"content","getter_name":"content","moor_type":"ColumnType.text","nullable":false,"customConstraints":"","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"search_terms","getter_name":"searchTerms","moor_type":"ColumnType.text","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":[1,0],"type":"view","data":{"name":"group_count","sql":"CREATE VIEW group_count AS SELECT\n users.*,\n (SELECT COUNT(*) FROM \"groups\" WHERE owner = users.id) AS group_count\n FROM users;","dart_data_name":"GroupCountData","dart_info_name":"GroupCount","columns":[{"name":"id","getter_name":"id","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"ColumnType.text","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"birthday","getter_name":"birthday","moor_type":"ColumnType.datetime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"next_user","getter_name":"nextUser","moor_type":"ColumnType.integer","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"group_count","getter_name":"groupCount","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}]}}]}
|
|
@ -3,13 +3,16 @@ import 'package:drift/drift.dart';
|
|||
import 'tables.dart';
|
||||
import 'src/generated/schema_v2.dart' as v2;
|
||||
import 'src/generated/schema_v4.dart' as v4;
|
||||
import 'src/generated/schema_v8.dart' as v8;
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@DriftDatabase(include: {'tables.drift'})
|
||||
class Database extends _$Database {
|
||||
static const latestSchemaVersion = 9;
|
||||
|
||||
@override
|
||||
int get schemaVersion => 8;
|
||||
int get schemaVersion => latestSchemaVersion;
|
||||
|
||||
Database(DatabaseConnection connection) : super.connect(connection);
|
||||
|
||||
|
@ -60,7 +63,18 @@ class Database extends _$Database {
|
|||
break;
|
||||
case 8:
|
||||
// Added a unique key to the users table
|
||||
|
||||
// TODO: Figure out why dropping the view is necessary (https://sqlite.org/forum/forumpost/de614349cb)
|
||||
await m.drop(groupCount);
|
||||
await m.alterTable(TableMigration(v8.Users(this)));
|
||||
await m.recreateAllViews();
|
||||
break;
|
||||
case 9:
|
||||
// Added a check to the users table
|
||||
await m.drop(groupCount);
|
||||
await m.alterTable(TableMigration(users));
|
||||
await m.recreateAllViews();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
//@dart=2.12
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/internal/migrations.dart';
|
||||
import 'schema_v9.dart' as v9;
|
||||
import 'schema_v8.dart' as v8;
|
||||
import 'schema_v1.dart' as v1;
|
||||
import 'schema_v2.dart' as v2;
|
||||
|
@ -15,6 +16,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
@override
|
||||
GeneratedDatabase databaseForVersion(QueryExecutor db, int version) {
|
||||
switch (version) {
|
||||
case 9:
|
||||
return v9.DatabaseAtV9(db);
|
||||
case 8:
|
||||
return v8.DatabaseAtV8(db);
|
||||
case 1:
|
||||
|
@ -32,7 +35,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
case 3:
|
||||
return v3.DatabaseAtV3(db);
|
||||
default:
|
||||
throw MissingSchemaException(version, const {8, 1, 2, 6, 7, 4, 5, 3});
|
||||
throw MissingSchemaException(
|
||||
version, const {9, 8, 1, 2, 6, 7, 4, 5, 3});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||
//@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<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
hasAutoIncrement: true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: const Constant('name'));
|
||||
late final GeneratedColumn<DateTime> birthday = GeneratedColumn<DateTime>(
|
||||
'birthday', aliasedName, true,
|
||||
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
||||
late final GeneratedColumn<int> nextUser = GeneratedColumn<int>(
|
||||
'next_user', aliasedName, true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('REFERENCES users (id)'));
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, birthday, nextUser];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'users';
|
||||
@override
|
||||
String get actualTableName => 'users';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [
|
||||
{name, birthday},
|
||||
];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
Users createAlias(String alias) {
|
||||
return Users(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => const ['CHECK (LENGTH(name) < 10)'];
|
||||
}
|
||||
|
||||
class Groups extends Table with TableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Groups(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: 'NOT NULL');
|
||||
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||
'title', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: 'NOT NULL');
|
||||
late final GeneratedColumn<bool> deleted = GeneratedColumn<bool>(
|
||||
'deleted', aliasedName, true,
|
||||
type: DriftSqlType.bool,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: 'DEFAULT FALSE',
|
||||
defaultValue: const CustomExpression('FALSE'));
|
||||
late final GeneratedColumn<int> owner = GeneratedColumn<int>(
|
||||
'owner', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: 'NOT NULL REFERENCES users(id)');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, title, deleted, owner];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'groups';
|
||||
@override
|
||||
String get actualTableName => 'groups';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
Groups createAlias(String alias) {
|
||||
return Groups(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => const ['PRIMARY KEY(id)'];
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class Notes extends Table with TableInfo, VirtualTableInfo {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Notes(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||
'title', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
late final GeneratedColumn<String> content = GeneratedColumn<String>(
|
||||
'content', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
late final GeneratedColumn<String> searchTerms = GeneratedColumn<String>(
|
||||
'search_terms', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [title, content, searchTerms];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'notes';
|
||||
@override
|
||||
String get actualTableName => 'notes';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => const {};
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
@override
|
||||
Notes createAlias(String alias) {
|
||||
return Notes(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
String get moduleAndArgs =>
|
||||
'fts5(title, content, search_terms, tokenize = "unicode61 tokenchars \'.\'")';
|
||||
}
|
||||
|
||||
class GroupCount extends ViewInfo<GroupCount, Never> implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final DatabaseAtV9 attachedDatabase;
|
||||
GroupCount(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns =>
|
||||
[id, name, birthday, nextUser, groupCount];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'group_count';
|
||||
@override
|
||||
String get createViewStmt =>
|
||||
'CREATE VIEW group_count AS SELECT\n users.*,\n (SELECT COUNT(*) FROM "groups" WHERE owner = users.id) AS group_count\n FROM users;';
|
||||
@override
|
||||
GroupCount get asDslTable => this;
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
||||
late final GeneratedColumn<int> id =
|
||||
GeneratedColumn<int>('id', aliasedName, false, type: DriftSqlType.int);
|
||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: DriftSqlType.string);
|
||||
late final GeneratedColumn<DateTime> birthday = GeneratedColumn<DateTime>(
|
||||
'birthday', aliasedName, true,
|
||||
type: DriftSqlType.dateTime);
|
||||
late final GeneratedColumn<int> nextUser = GeneratedColumn<int>(
|
||||
'next_user', aliasedName, true,
|
||||
type: DriftSqlType.int);
|
||||
late final GeneratedColumn<int> groupCount = GeneratedColumn<int>(
|
||||
'group_count', aliasedName, false,
|
||||
type: DriftSqlType.int);
|
||||
@override
|
||||
GroupCount createAlias(String alias) {
|
||||
return GroupCount(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {};
|
||||
}
|
||||
|
||||
class DatabaseAtV9 extends GeneratedDatabase {
|
||||
DatabaseAtV9(QueryExecutor e) : super(e);
|
||||
DatabaseAtV9.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Users users = Users(this);
|
||||
late final Groups groups = Groups(this);
|
||||
late final Notes notes = Notes(this);
|
||||
late final GroupCount groupCount = GroupCount(this);
|
||||
@override
|
||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[users, groups, notes, groupCount];
|
||||
@override
|
||||
int get schemaVersion => 9;
|
||||
@override
|
||||
DriftDatabaseOptions get options =>
|
||||
const DriftDatabaseOptions(storeDateTimeAsText: true);
|
||||
}
|
|
@ -16,4 +16,10 @@ class Users extends Table {
|
|||
List<Set<Column>> get uniqueKeys => [
|
||||
{name, birthday}
|
||||
];
|
||||
|
||||
@override
|
||||
List<String> get customConstraints => [
|
||||
// This constraint has been added in schema version 9
|
||||
'CHECK (LENGTH(name) < 10)',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
//@dart=2.12
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/internal/migrations.dart';
|
||||
import 'schema_v9.dart' as v9;
|
||||
import 'schema_v8.dart' as v8;
|
||||
import 'schema_v1.dart' as v1;
|
||||
import 'schema_v2.dart' as v2;
|
||||
|
@ -15,6 +16,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
@override
|
||||
GeneratedDatabase databaseForVersion(QueryExecutor db, int version) {
|
||||
switch (version) {
|
||||
case 9:
|
||||
return v9.DatabaseAtV9(db);
|
||||
case 8:
|
||||
return v8.DatabaseAtV8(db);
|
||||
case 1:
|
||||
|
@ -32,7 +35,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||
case 3:
|
||||
return v3.DatabaseAtV3(db);
|
||||
default:
|
||||
throw MissingSchemaException(version, const {8, 1, 2, 6, 7, 4, 5, 3});
|
||||
throw MissingSchemaException(
|
||||
version, const {9, 8, 1, 2, 6, 7, 4, 5, 3});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,790 @@
|
|||
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||
//@dart=2.12
|
||||
import 'package:drift/drift.dart';
|
||||
|
||||
class UsersData extends DataClass implements Insertable<UsersData> {
|
||||
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<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<int>(id);
|
||||
map['name'] = Variable<String>(name);
|
||||
if (!nullToAbsent || birthday != null) {
|
||||
map['birthday'] = Variable<DateTime>(birthday);
|
||||
}
|
||||
if (!nullToAbsent || nextUser != null) {
|
||||
map['next_user'] = Variable<int>(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<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return UsersData(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
name: serializer.fromJson<String>(json['name']),
|
||||
birthday: serializer.fromJson<DateTime?>(json['birthday']),
|
||||
nextUser: serializer.fromJson<int?>(json['nextUser']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'name': serializer.toJson<String>(name),
|
||||
'birthday': serializer.toJson<DateTime?>(birthday),
|
||||
'nextUser': serializer.toJson<int?>(nextUser),
|
||||
};
|
||||
}
|
||||
|
||||
UsersData copyWith(
|
||||
{int? id,
|
||||
String? name,
|
||||
Value<DateTime?> birthday = const Value.absent(),
|
||||
Value<int?> 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<UsersData> {
|
||||
final Value<int> id;
|
||||
final Value<String> name;
|
||||
final Value<DateTime?> birthday;
|
||||
final Value<int?> 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<UsersData> custom({
|
||||
Expression<int>? id,
|
||||
Expression<String>? name,
|
||||
Expression<DateTime>? birthday,
|
||||
Expression<int>? 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<int>? id,
|
||||
Value<String>? name,
|
||||
Value<DateTime?>? birthday,
|
||||
Value<int?>? nextUser}) {
|
||||
return UsersCompanion(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
birthday: birthday ?? this.birthday,
|
||||
nextUser: nextUser ?? this.nextUser,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (id.present) {
|
||||
map['id'] = Variable<int>(id.value);
|
||||
}
|
||||
if (name.present) {
|
||||
map['name'] = Variable<String>(name.value);
|
||||
}
|
||||
if (birthday.present) {
|
||||
map['birthday'] = Variable<DateTime>(birthday.value);
|
||||
}
|
||||
if (nextUser.present) {
|
||||
map['next_user'] = Variable<int>(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 Users extends Table with TableInfo<Users, UsersData> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Users(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
hasAutoIncrement: true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: const Constant('name'));
|
||||
late final GeneratedColumn<DateTime> birthday = GeneratedColumn<DateTime>(
|
||||
'birthday', aliasedName, true,
|
||||
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
||||
late final GeneratedColumn<int> nextUser = GeneratedColumn<int>(
|
||||
'next_user', aliasedName, true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('REFERENCES users (id)'));
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, birthday, nextUser];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'users';
|
||||
@override
|
||||
String get actualTableName => 'users';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [
|
||||
{name, birthday},
|
||||
];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> 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<String> get customConstraints => const ['CHECK (LENGTH(name) < 10)'];
|
||||
}
|
||||
|
||||
class GroupsData extends DataClass implements Insertable<GroupsData> {
|
||||
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<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<int>(id);
|
||||
map['title'] = Variable<String>(title);
|
||||
if (!nullToAbsent || deleted != null) {
|
||||
map['deleted'] = Variable<bool>(deleted);
|
||||
}
|
||||
map['owner'] = Variable<int>(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<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return GroupsData(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
title: serializer.fromJson<String>(json['title']),
|
||||
deleted: serializer.fromJson<bool?>(json['deleted']),
|
||||
owner: serializer.fromJson<int>(json['owner']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'title': serializer.toJson<String>(title),
|
||||
'deleted': serializer.toJson<bool?>(deleted),
|
||||
'owner': serializer.toJson<int>(owner),
|
||||
};
|
||||
}
|
||||
|
||||
GroupsData copyWith(
|
||||
{int? id,
|
||||
String? title,
|
||||
Value<bool?> 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<GroupsData> {
|
||||
final Value<int> id;
|
||||
final Value<String> title;
|
||||
final Value<bool?> deleted;
|
||||
final Value<int> 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<GroupsData> custom({
|
||||
Expression<int>? id,
|
||||
Expression<String>? title,
|
||||
Expression<bool>? deleted,
|
||||
Expression<int>? 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<int>? id,
|
||||
Value<String>? title,
|
||||
Value<bool?>? deleted,
|
||||
Value<int>? owner}) {
|
||||
return GroupsCompanion(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
deleted: deleted ?? this.deleted,
|
||||
owner: owner ?? this.owner,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (id.present) {
|
||||
map['id'] = Variable<int>(id.value);
|
||||
}
|
||||
if (title.present) {
|
||||
map['title'] = Variable<String>(title.value);
|
||||
}
|
||||
if (deleted.present) {
|
||||
map['deleted'] = Variable<bool>(deleted.value);
|
||||
}
|
||||
if (owner.present) {
|
||||
map['owner'] = Variable<int>(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 Groups extends Table with TableInfo<Groups, GroupsData> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Groups(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||
'id', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: 'NOT NULL');
|
||||
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||
'title', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: 'NOT NULL');
|
||||
late final GeneratedColumn<bool> deleted = GeneratedColumn<bool>(
|
||||
'deleted', aliasedName, true,
|
||||
type: DriftSqlType.bool,
|
||||
requiredDuringInsert: false,
|
||||
$customConstraints: 'DEFAULT FALSE',
|
||||
defaultValue: const CustomExpression('FALSE'));
|
||||
late final GeneratedColumn<int> owner = GeneratedColumn<int>(
|
||||
'owner', aliasedName, false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: 'NOT NULL REFERENCES users(id)');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, title, deleted, owner];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'groups';
|
||||
@override
|
||||
String get actualTableName => 'groups';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
GroupsData map(Map<String, dynamic> 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<String> get customConstraints => const ['PRIMARY KEY(id)'];
|
||||
@override
|
||||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class NotesData extends DataClass implements Insertable<NotesData> {
|
||||
final String title;
|
||||
final String content;
|
||||
final String searchTerms;
|
||||
const NotesData(
|
||||
{required this.title, required this.content, required this.searchTerms});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['title'] = Variable<String>(title);
|
||||
map['content'] = Variable<String>(content);
|
||||
map['search_terms'] = Variable<String>(searchTerms);
|
||||
return map;
|
||||
}
|
||||
|
||||
NotesCompanion toCompanion(bool nullToAbsent) {
|
||||
return NotesCompanion(
|
||||
title: Value(title),
|
||||
content: Value(content),
|
||||
searchTerms: Value(searchTerms),
|
||||
);
|
||||
}
|
||||
|
||||
factory NotesData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return NotesData(
|
||||
title: serializer.fromJson<String>(json['title']),
|
||||
content: serializer.fromJson<String>(json['content']),
|
||||
searchTerms: serializer.fromJson<String>(json['searchTerms']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'title': serializer.toJson<String>(title),
|
||||
'content': serializer.toJson<String>(content),
|
||||
'searchTerms': serializer.toJson<String>(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<NotesData> {
|
||||
final Value<String> title;
|
||||
final Value<String> content;
|
||||
final Value<String> searchTerms;
|
||||
const NotesCompanion({
|
||||
this.title = const Value.absent(),
|
||||
this.content = const Value.absent(),
|
||||
this.searchTerms = const Value.absent(),
|
||||
});
|
||||
NotesCompanion.insert({
|
||||
required String title,
|
||||
required String content,
|
||||
required String searchTerms,
|
||||
}) : title = Value(title),
|
||||
content = Value(content),
|
||||
searchTerms = Value(searchTerms);
|
||||
static Insertable<NotesData> custom({
|
||||
Expression<String>? title,
|
||||
Expression<String>? content,
|
||||
Expression<String>? searchTerms,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (title != null) 'title': title,
|
||||
if (content != null) 'content': content,
|
||||
if (searchTerms != null) 'search_terms': searchTerms,
|
||||
});
|
||||
}
|
||||
|
||||
NotesCompanion copyWith(
|
||||
{Value<String>? title,
|
||||
Value<String>? content,
|
||||
Value<String>? searchTerms}) {
|
||||
return NotesCompanion(
|
||||
title: title ?? this.title,
|
||||
content: content ?? this.content,
|
||||
searchTerms: searchTerms ?? this.searchTerms,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (title.present) {
|
||||
map['title'] = Variable<String>(title.value);
|
||||
}
|
||||
if (content.present) {
|
||||
map['content'] = Variable<String>(content.value);
|
||||
}
|
||||
if (searchTerms.present) {
|
||||
map['search_terms'] = Variable<String>(searchTerms.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('NotesCompanion(')
|
||||
..write('title: $title, ')
|
||||
..write('content: $content, ')
|
||||
..write('searchTerms: $searchTerms')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Notes extends Table
|
||||
with TableInfo<Notes, NotesData>, VirtualTableInfo<Notes, NotesData> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
Notes(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<String> title = GeneratedColumn<String>(
|
||||
'title', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
late final GeneratedColumn<String> content = GeneratedColumn<String>(
|
||||
'content', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
late final GeneratedColumn<String> searchTerms = GeneratedColumn<String>(
|
||||
'search_terms', aliasedName, false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
$customConstraints: '');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [title, content, searchTerms];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'notes';
|
||||
@override
|
||||
String get actualTableName => 'notes';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => const {};
|
||||
@override
|
||||
NotesData map(Map<String, dynamic> 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 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<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return GroupCountData(
|
||||
id: serializer.fromJson<int>(json['id']),
|
||||
name: serializer.fromJson<String>(json['name']),
|
||||
birthday: serializer.fromJson<DateTime?>(json['birthday']),
|
||||
nextUser: serializer.fromJson<int?>(json['nextUser']),
|
||||
groupCount: serializer.fromJson<int>(json['groupCount']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<int>(id),
|
||||
'name': serializer.toJson<String>(name),
|
||||
'birthday': serializer.toJson<DateTime?>(birthday),
|
||||
'nextUser': serializer.toJson<int?>(nextUser),
|
||||
'groupCount': serializer.toJson<int>(groupCount),
|
||||
};
|
||||
}
|
||||
|
||||
GroupCountData copyWith(
|
||||
{int? id,
|
||||
String? name,
|
||||
Value<DateTime?> birthday = const Value.absent(),
|
||||
Value<int?> 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<GroupCount, GroupCountData>
|
||||
implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final DatabaseAtV9 attachedDatabase;
|
||||
GroupCount(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns =>
|
||||
[id, name, birthday, nextUser, groupCount];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'group_count';
|
||||
@override
|
||||
String get createViewStmt =>
|
||||
'CREATE VIEW group_count AS SELECT\n users.*,\n (SELECT COUNT(*) FROM "groups" WHERE owner = users.id) AS group_count\n FROM users;';
|
||||
@override
|
||||
GroupCount get asDslTable => this;
|
||||
@override
|
||||
GroupCountData map(Map<String, dynamic> 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<int> id =
|
||||
GeneratedColumn<int>('id', aliasedName, false, type: DriftSqlType.int);
|
||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||
'name', aliasedName, false,
|
||||
type: DriftSqlType.string);
|
||||
late final GeneratedColumn<DateTime> birthday = GeneratedColumn<DateTime>(
|
||||
'birthday', aliasedName, true,
|
||||
type: DriftSqlType.dateTime);
|
||||
late final GeneratedColumn<int> nextUser = GeneratedColumn<int>(
|
||||
'next_user', aliasedName, true,
|
||||
type: DriftSqlType.int);
|
||||
late final GeneratedColumn<int> groupCount = GeneratedColumn<int>(
|
||||
'group_count', aliasedName, false,
|
||||
type: DriftSqlType.int);
|
||||
@override
|
||||
GroupCount createAlias(String alias) {
|
||||
return GroupCount(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {};
|
||||
}
|
||||
|
||||
class DatabaseAtV9 extends GeneratedDatabase {
|
||||
DatabaseAtV9(QueryExecutor e) : super(e);
|
||||
DatabaseAtV9.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Users users = Users(this);
|
||||
late final Groups groups = Groups(this);
|
||||
late final Notes notes = Notes(this);
|
||||
late final GroupCount groupCount = GroupCount(this);
|
||||
@override
|
||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[users, groups, notes, groupCount];
|
||||
@override
|
||||
int get schemaVersion => 9;
|
||||
@override
|
||||
DriftDatabaseOptions get options =>
|
||||
const DriftDatabaseOptions(storeDateTimeAsText: true);
|
||||
}
|
|
@ -24,7 +24,7 @@ void main() {
|
|||
// the schema is correct after the migration.
|
||||
// More complex tests ensuring data integrity are written below.
|
||||
group('general migration', () {
|
||||
const currentSchema = 7;
|
||||
const currentSchema = Database.latestSchemaVersion;
|
||||
|
||||
for (var oldVersion = 1; oldVersion < currentSchema; oldVersion++) {
|
||||
group('from v$oldVersion', () {
|
||||
|
|
Loading…
Reference in New Issue