mirror of https://github.com/AMT-Cheif/drift.git
Support drift-defined views schema tools (#1813)
This commit is contained in:
parent
d0694f9d65
commit
80c8c86031
|
@ -60,6 +60,22 @@ class SchemaWriter {
|
|||
'name': entity.name,
|
||||
'sql': entity.createStmt,
|
||||
};
|
||||
} else if (entity is MoorView) {
|
||||
if (entity.declaration is! MoorViewDeclaration) {
|
||||
throw UnsupportedError(
|
||||
'Exporting Dart-defined views into a schema is not '
|
||||
'currently supported');
|
||||
}
|
||||
|
||||
type = 'view';
|
||||
data = {
|
||||
'name': entity.name,
|
||||
'sql': entity
|
||||
.createSql(const MoorOptions.defaults(newSqlCodeGeneration: true)),
|
||||
'dart_data_name': entity.dartTypeName,
|
||||
'dart_info_name': entity.entityInfoName,
|
||||
'columns': [for (final column in entity.columns) _columnData(column)],
|
||||
};
|
||||
} else if (entity is SpecialQuery) {
|
||||
type = 'special-query';
|
||||
data = {
|
||||
|
@ -200,6 +216,9 @@ class SchemaReader {
|
|||
case 'table':
|
||||
entity = _readTable(content);
|
||||
break;
|
||||
case 'view':
|
||||
entity = _readView(content);
|
||||
break;
|
||||
case 'special-query':
|
||||
// Not relevant for the schema.
|
||||
return;
|
||||
|
@ -284,6 +303,18 @@ class SchemaReader {
|
|||
);
|
||||
}
|
||||
|
||||
MoorView _readView(Map<String, dynamic> content) {
|
||||
return MoorView(
|
||||
declaration: null,
|
||||
name: content['name'] as String,
|
||||
dartTypeName: content['dart_data_name'] as String,
|
||||
entityInfoName: content['dart_info_name'] as String,
|
||||
)..columns = [
|
||||
for (final column in content['columns'])
|
||||
_readColumn(column as Map<String, dynamic>)
|
||||
];
|
||||
}
|
||||
|
||||
MoorColumn _readColumn(Map<String, dynamic> data) {
|
||||
final name = data['name'] as String;
|
||||
final moorType = ColumnType.values
|
||||
|
|
|
@ -40,6 +40,8 @@ CREATE TRIGGER delete_empty_groups AFTER DELETE ON group_members BEGIN
|
|||
END;
|
||||
|
||||
CREATE INDEX groups_name ON "groups"(name);
|
||||
|
||||
CREATE VIEW my_view AS SELECT id FROM "groups";
|
||||
''',
|
||||
'foo|lib/main.dart': '''
|
||||
import 'package:drift/drift.dart';
|
||||
|
@ -281,6 +283,33 @@ const expected = r'''
|
|||
},
|
||||
{
|
||||
"id": 5,
|
||||
"references": [
|
||||
0
|
||||
],
|
||||
"type": "view",
|
||||
"data": {
|
||||
"name": "my_view",
|
||||
"sql": "CREATE VIEW my_view AS SELECT id FROM \"groups\"",
|
||||
"dart_data_name": "MyViewData",
|
||||
"dart_info_name": "MyView",
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "ColumnType.integer",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"references": [
|
||||
|
||||
],
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"_meta":{"description":"This file contains a serialized version of schema entities for moor.","version":"0.1.0-dev-preview"},"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","primary-key"]},{"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":"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}},{"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<bool>('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":[]}],"is_virtual":false,"constraints":["PRIMARY KEY (id)"],"explicit_pk":["id"]}}]}
|
||||
{"_meta":{"description":"This file contains a serialized version of schema entities for moor.","version":"0.1.0-dev-preview"},"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","primary-key"]},{"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":"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}},{"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<bool>('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":[]}],"is_virtual":false,"constraints":["PRIMARY KEY (id)"],"explicit_pk":["id"]}},{"id":2,"references":[1,0],"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_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":"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":[]}]}}]}
|
|
@ -44,6 +44,9 @@ class Database extends _$Database {
|
|||
} else if (target == 5) {
|
||||
// Just add a new column that was added in version 5;
|
||||
await m.addColumn(users, users.nextUser);
|
||||
|
||||
// And create the view on users
|
||||
await m.createView(groupCount);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -204,8 +204,6 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
User map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return User.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -454,8 +452,6 @@ class Groups extends Table with TableInfo<Groups, Group> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Group map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return Group.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -472,13 +468,135 @@ class Groups extends Table with TableInfo<Groups, Group> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class GroupCountData extends DataClass {
|
||||
final int id;
|
||||
final String name;
|
||||
final int? nextUser;
|
||||
final int groupCount;
|
||||
GroupCountData(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
this.nextUser,
|
||||
required this.groupCount});
|
||||
factory GroupCountData.fromData(Map<String, dynamic> data, {String? prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
return GroupCountData(
|
||||
id: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
|
||||
name: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}name'])!,
|
||||
nextUser: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}next_user']),
|
||||
groupCount: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}group_count'])!,
|
||||
);
|
||||
}
|
||||
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']),
|
||||
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),
|
||||
'nextUser': serializer.toJson<int?>(nextUser),
|
||||
'groupCount': serializer.toJson<int>(groupCount),
|
||||
};
|
||||
}
|
||||
|
||||
GroupCountData copyWith(
|
||||
{int? id, String? name, int? nextUser, int? groupCount}) =>
|
||||
GroupCountData(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
nextUser: nextUser ?? this.nextUser,
|
||||
groupCount: groupCount ?? this.groupCount,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('GroupCountData(')
|
||||
..write('id: $id, ')
|
||||
..write('name: $name, ')
|
||||
..write('nextUser: $nextUser, ')
|
||||
..write('groupCount: $groupCount')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(id, name, nextUser, groupCount);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is GroupCountData &&
|
||||
other.id == this.id &&
|
||||
other.name == this.name &&
|
||||
other.nextUser == this.nextUser &&
|
||||
other.groupCount == this.groupCount);
|
||||
}
|
||||
|
||||
class GroupCount extends ViewInfo<GroupCount, GroupCountData>
|
||||
implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final _$Database attachedDatabase;
|
||||
GroupCount(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, 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}) {
|
||||
return GroupCountData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
}
|
||||
|
||||
late final GeneratedColumn<int?> id =
|
||||
GeneratedColumn<int?>('id', aliasedName, false, type: const IntType());
|
||||
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
|
||||
'name', aliasedName, false,
|
||||
type: const StringType());
|
||||
late final GeneratedColumn<int?> nextUser = GeneratedColumn<int?>(
|
||||
'next_user', aliasedName, true,
|
||||
type: const IntType());
|
||||
late final GeneratedColumn<int?> groupCount = GeneratedColumn<int?>(
|
||||
'group_count', aliasedName, false,
|
||||
type: const IntType());
|
||||
@override
|
||||
GroupCount createAlias(String alias) {
|
||||
return GroupCount(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {'groups', 'users'};
|
||||
}
|
||||
|
||||
abstract class _$Database extends GeneratedDatabase {
|
||||
_$Database(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
||||
_$Database.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final $UsersTable users = $UsersTable(this);
|
||||
late final Groups groups = Groups(this);
|
||||
late final GroupCount groupCount = GroupCount(this);
|
||||
@override
|
||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [users, groups];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[users, groups, groupCount];
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ class Users extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@ class Users extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@ class Users extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
@ -74,8 +72,6 @@ class Groups extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ class Users extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
@ -76,8 +74,6 @@ class Groups extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ class Users extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
@ -81,8 +79,6 @@ class Groups extends Table with TableInfo {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
Never map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
throw UnsupportedError('TableInfo.map in schema verification code');
|
||||
}
|
||||
|
@ -98,15 +94,59 @@ class Groups extends Table with TableInfo {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class GroupCount extends ViewInfo<GroupCount, Never> implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final DatabaseAtV5 attachedDatabase;
|
||||
GroupCount(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, nextUser, groupCount];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'group_count';
|
||||
@override
|
||||
String? get createViewStmt => null;
|
||||
@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: const IntType());
|
||||
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
|
||||
'name', aliasedName, false,
|
||||
type: const StringType());
|
||||
late final GeneratedColumn<int?> nextUser = GeneratedColumn<int?>(
|
||||
'next_user', aliasedName, true,
|
||||
type: const IntType());
|
||||
late final GeneratedColumn<int?> groupCount = GeneratedColumn<int?>(
|
||||
'group_count', aliasedName, false,
|
||||
type: const IntType());
|
||||
@override
|
||||
GroupCount createAlias(String alias) {
|
||||
return GroupCount(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {};
|
||||
}
|
||||
|
||||
class DatabaseAtV5 extends GeneratedDatabase {
|
||||
DatabaseAtV5(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
||||
DatabaseAtV5.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Users users = Users(this);
|
||||
late final Groups groups = Groups(this);
|
||||
late final GroupCount groupCount = GroupCount(this);
|
||||
@override
|
||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [users, groups];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[users, groups, groupCount];
|
||||
@override
|
||||
int get schemaVersion => 5;
|
||||
}
|
||||
|
|
|
@ -8,4 +8,10 @@ CREATE TABLE "groups" (
|
|||
owner INTEGER NOT NULL REFERENCES users (id),
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
);
|
||||
|
||||
-- This view was added in schema version 5
|
||||
CREATE VIEW group_count AS SELECT
|
||||
users.*,
|
||||
(SELECT COUNT(*) FROM "groups" WHERE owner = users.id) AS group_count
|
||||
FROM users;
|
||||
|
|
|
@ -117,8 +117,6 @@ class Users extends Table with TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return UsersData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
|
|
@ -140,8 +140,6 @@ class Users extends Table with TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return UsersData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
|
|
@ -140,8 +140,6 @@ class Users extends Table with TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return UsersData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -363,8 +361,6 @@ class Groups extends Table with TableInfo<Groups, GroupsData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
GroupsData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return GroupsData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
|
|
@ -142,8 +142,6 @@ class Users extends Table with TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return UsersData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -365,8 +363,6 @@ class Groups extends Table with TableInfo<Groups, GroupsData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
GroupsData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return GroupsData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
|
|
@ -174,8 +174,6 @@ class Users extends Table with TableInfo<Users, UsersData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
UsersData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return UsersData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -397,8 +395,6 @@ class Groups extends Table with TableInfo<Groups, GroupsData> {
|
|||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
List<Set<GeneratedColumn>> get uniqueKeys => [];
|
||||
@override
|
||||
GroupsData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return GroupsData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
|
@ -415,15 +411,136 @@ class Groups extends Table with TableInfo<Groups, GroupsData> {
|
|||
bool get dontWriteConstraints => true;
|
||||
}
|
||||
|
||||
class GroupCountData extends DataClass {
|
||||
final int id;
|
||||
final String name;
|
||||
final int? nextUser;
|
||||
final int groupCount;
|
||||
GroupCountData(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
this.nextUser,
|
||||
required this.groupCount});
|
||||
factory GroupCountData.fromData(Map<String, dynamic> data, {String? prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
return GroupCountData(
|
||||
id: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
|
||||
name: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}name'])!,
|
||||
nextUser: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}next_user']),
|
||||
groupCount: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}group_count'])!,
|
||||
);
|
||||
}
|
||||
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']),
|
||||
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),
|
||||
'nextUser': serializer.toJson<int?>(nextUser),
|
||||
'groupCount': serializer.toJson<int>(groupCount),
|
||||
};
|
||||
}
|
||||
|
||||
GroupCountData copyWith(
|
||||
{int? id, String? name, int? nextUser, int? groupCount}) =>
|
||||
GroupCountData(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
nextUser: nextUser ?? this.nextUser,
|
||||
groupCount: groupCount ?? this.groupCount,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('GroupCountData(')
|
||||
..write('id: $id, ')
|
||||
..write('name: $name, ')
|
||||
..write('nextUser: $nextUser, ')
|
||||
..write('groupCount: $groupCount')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(id, name, nextUser, groupCount);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is GroupCountData &&
|
||||
other.id == this.id &&
|
||||
other.name == this.name &&
|
||||
other.nextUser == this.nextUser &&
|
||||
other.groupCount == this.groupCount);
|
||||
}
|
||||
|
||||
class GroupCount extends ViewInfo<GroupCount, GroupCountData>
|
||||
implements HasResultSet {
|
||||
final String? _alias;
|
||||
@override
|
||||
final DatabaseAtV5 attachedDatabase;
|
||||
GroupCount(this.attachedDatabase, [this._alias]);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [id, name, nextUser, groupCount];
|
||||
@override
|
||||
String get aliasedName => _alias ?? entityName;
|
||||
@override
|
||||
String get entityName => 'group_count';
|
||||
@override
|
||||
String? get createViewStmt => null;
|
||||
@override
|
||||
GroupCount get asDslTable => this;
|
||||
@override
|
||||
GroupCountData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return GroupCountData.fromData(data,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
}
|
||||
|
||||
late final GeneratedColumn<int?> id =
|
||||
GeneratedColumn<int?>('id', aliasedName, false, type: const IntType());
|
||||
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
|
||||
'name', aliasedName, false,
|
||||
type: const StringType());
|
||||
late final GeneratedColumn<int?> nextUser = GeneratedColumn<int?>(
|
||||
'next_user', aliasedName, true,
|
||||
type: const IntType());
|
||||
late final GeneratedColumn<int?> groupCount = GeneratedColumn<int?>(
|
||||
'group_count', aliasedName, false,
|
||||
type: const IntType());
|
||||
@override
|
||||
GroupCount createAlias(String alias) {
|
||||
return GroupCount(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
@override
|
||||
Query? get query => null;
|
||||
@override
|
||||
Set<String> get readTables => const {};
|
||||
}
|
||||
|
||||
class DatabaseAtV5 extends GeneratedDatabase {
|
||||
DatabaseAtV5(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
||||
DatabaseAtV5.connect(DatabaseConnection c) : super.connect(c);
|
||||
late final Users users = Users(this);
|
||||
late final Groups groups = Groups(this);
|
||||
late final GroupCount groupCount = GroupCount(this);
|
||||
@override
|
||||
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
|
||||
@override
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities => [users, groups];
|
||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||
[users, groups, groupCount];
|
||||
@override
|
||||
int get schemaVersion => 5;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import 'generated/schema.dart';
|
|||
|
||||
import 'generated/schema_v1.dart' as v1;
|
||||
import 'generated/schema_v2.dart' as v2;
|
||||
import 'generated/schema_v4.dart' as v4;
|
||||
import 'generated/schema_v5.dart' as v5;
|
||||
|
||||
void main() {
|
||||
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
|
||||
|
@ -61,4 +63,39 @@ void main() {
|
|||
await verifier.migrateAndValidate(db, 5);
|
||||
await db.close();
|
||||
});
|
||||
|
||||
test('view works after upgrade from v4 to v5', () async {
|
||||
final schema = await verifier.schemaAt(4);
|
||||
|
||||
final oldDb = v4.DatabaseAtV4.connect(schema.newConnection());
|
||||
await oldDb.batch((batch) {
|
||||
batch
|
||||
..insert(oldDb.users, v4.UsersCompanion.insert(id: Value(1)))
|
||||
..insert(oldDb.users, v4.UsersCompanion.insert(id: Value(2)))
|
||||
..insert(
|
||||
oldDb.groups, v4.GroupsCompanion.insert(title: 'Test', owner: 1));
|
||||
});
|
||||
await oldDb.close();
|
||||
|
||||
// Run the migration and verify that it adds the view.
|
||||
final db = Database(schema.newConnection());
|
||||
await verifier.migrateAndValidate(db, 5);
|
||||
await db.close();
|
||||
|
||||
// Make sure the view works!
|
||||
final migratedDb = v5.DatabaseAtV5.connect(schema.newConnection());
|
||||
final viewCount = await migratedDb.select(migratedDb.groupCount).get();
|
||||
|
||||
expect(
|
||||
viewCount,
|
||||
contains(isA<v5.GroupCountData>()
|
||||
.having((e) => e.id, 'id', 1)
|
||||
.having((e) => e.groupCount, 'groupCount', 1)));
|
||||
expect(
|
||||
viewCount,
|
||||
contains(isA<v5.GroupCountData>()
|
||||
.having((e) => e.id, 'id', 2)
|
||||
.having((e) => e.groupCount, 'groupCount', 0)));
|
||||
await migratedDb.close();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue