Add moor-file based table to migration example

This commit is contained in:
Simon Binder 2020-11-09 18:55:45 +01:00
parent 95dacd986c
commit f83aa1a35a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
10 changed files with 439 additions and 13 deletions

View File

@ -2,19 +2,12 @@ import 'package:moor/moor.dart';
part 'database.g.dart'; part 'database.g.dart';
class Users extends Table { @UseMoor(include: {'tables.moor'})
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()(); // added in schema version 2
}
@UseMoor(tables: [Users])
class Database extends _$Database { class Database extends _$Database {
@override @override
final int schemaVersion; int get schemaVersion => 3;
Database(this.schemaVersion, DatabaseConnection connection) Database(DatabaseConnection connection) : super.connect(connection);
: super.connect(connection);
@override @override
MigrationStrategy get migration { MigrationStrategy get migration {
@ -24,6 +17,9 @@ class Database extends _$Database {
if (target == 2) { if (target == 2) {
// Migration from 1 to 2: Add name column in users // Migration from 1 to 2: Add name column in users
await m.addColumn(users, users.name); await m.addColumn(users, users.name);
} else if (target == 3) {
// Migration from 2 to 3: We added the groups table
await m.createTable(groups);
} }
} }
}, },

View File

@ -192,13 +192,288 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
} }
} }
class Group extends DataClass implements Insertable<Group> {
final int id;
final String title;
final bool deleted;
final int owner;
Group(
{@required this.id,
@required this.title,
this.deleted,
@required this.owner});
factory Group.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String prefix}) {
final effectivePrefix = prefix ?? '';
final intType = db.typeSystem.forDartType<int>();
final stringType = db.typeSystem.forDartType<String>();
final boolType = db.typeSystem.forDartType<bool>();
return Group(
id: intType.mapFromDatabaseResponse(data['${effectivePrefix}id']),
title:
stringType.mapFromDatabaseResponse(data['${effectivePrefix}title']),
deleted:
boolType.mapFromDatabaseResponse(data['${effectivePrefix}deleted']),
owner: intType.mapFromDatabaseResponse(data['${effectivePrefix}owner']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (!nullToAbsent || id != null) {
map['id'] = Variable<int>(id);
}
if (!nullToAbsent || title != null) {
map['title'] = Variable<String>(title);
}
if (!nullToAbsent || deleted != null) {
map['deleted'] = Variable<bool>(deleted);
}
if (!nullToAbsent || owner != null) {
map['owner'] = Variable<int>(owner);
}
return map;
}
GroupsCompanion toCompanion(bool nullToAbsent) {
return GroupsCompanion(
id: id == null && nullToAbsent ? const Value.absent() : Value(id),
title:
title == null && nullToAbsent ? const Value.absent() : Value(title),
deleted: deleted == null && nullToAbsent
? const Value.absent()
: Value(deleted),
owner:
owner == null && nullToAbsent ? const Value.absent() : Value(owner),
);
}
factory Group.fromJson(Map<String, dynamic> json,
{ValueSerializer serializer}) {
serializer ??= moorRuntimeOptions.defaultSerializer;
return Group(
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 ??= moorRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'title': serializer.toJson<String>(title),
'deleted': serializer.toJson<bool>(deleted),
'owner': serializer.toJson<int>(owner),
};
}
Group copyWith({int id, String title, bool deleted, int owner}) => Group(
id: id ?? this.id,
title: title ?? this.title,
deleted: deleted ?? this.deleted,
owner: owner ?? this.owner,
);
@override
String toString() {
return (StringBuffer('Group(')
..write('id: $id, ')
..write('title: $title, ')
..write('deleted: $deleted, ')
..write('owner: $owner')
..write(')'))
.toString();
}
@override
int get hashCode => $mrjf($mrjc(id.hashCode,
$mrjc(title.hashCode, $mrjc(deleted.hashCode, owner.hashCode))));
@override
bool operator ==(dynamic other) =>
identical(this, other) ||
(other is Group &&
other.id == this.id &&
other.title == this.title &&
other.deleted == this.deleted &&
other.owner == this.owner);
}
class GroupsCompanion extends UpdateCompanion<Group> {
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<Group> 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, Group> {
final GeneratedDatabase _db;
final String _alias;
Groups(this._db, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
GeneratedIntColumn _id;
GeneratedIntColumn get id => _id ??= _constructId();
GeneratedIntColumn _constructId() {
return GeneratedIntColumn('id', $tableName, false,
$customConstraints: 'NOT NULL');
}
final VerificationMeta _titleMeta = const VerificationMeta('title');
GeneratedTextColumn _title;
GeneratedTextColumn get title => _title ??= _constructTitle();
GeneratedTextColumn _constructTitle() {
return GeneratedTextColumn('title', $tableName, false,
$customConstraints: 'NOT NULL');
}
final VerificationMeta _deletedMeta = const VerificationMeta('deleted');
GeneratedBoolColumn _deleted;
GeneratedBoolColumn get deleted => _deleted ??= _constructDeleted();
GeneratedBoolColumn _constructDeleted() {
return GeneratedBoolColumn('deleted', $tableName, true,
$customConstraints: 'DEFAULT FALSE',
defaultValue: const CustomExpression<bool>('FALSE'));
}
final VerificationMeta _ownerMeta = const VerificationMeta('owner');
GeneratedIntColumn _owner;
GeneratedIntColumn get owner => _owner ??= _constructOwner();
GeneratedIntColumn _constructOwner() {
return GeneratedIntColumn('owner', $tableName, false,
$customConstraints: 'NOT NULL REFERENCES users (id)');
}
@override
List<GeneratedColumn> get $columns => [id, title, deleted, owner];
@override
Groups get asDslTable => this;
@override
String get $tableName => _alias ?? 'groups';
@override
final String actualTableName = 'groups';
@override
VerificationContext validateIntegrity(Insertable<Group> instance,
{bool isInserting = false}) {
final context = VerificationContext();
final data = instance.toColumns(true);
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id'], _idMeta));
}
if (data.containsKey('title')) {
context.handle(
_titleMeta, title.isAcceptableOrUnknown(data['title'], _titleMeta));
} else if (isInserting) {
context.missing(_titleMeta);
}
if (data.containsKey('deleted')) {
context.handle(_deletedMeta,
deleted.isAcceptableOrUnknown(data['deleted'], _deletedMeta));
}
if (data.containsKey('owner')) {
context.handle(
_ownerMeta, owner.isAcceptableOrUnknown(data['owner'], _ownerMeta));
} else if (isInserting) {
context.missing(_ownerMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
Group map(Map<String, dynamic> data, {String tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : null;
return Group.fromData(data, _db, prefix: effectivePrefix);
}
@override
Groups createAlias(String alias) {
return Groups(_db, alias);
}
@override
List<String> get customConstraints => const ['PRIMARY KEY (id)'];
@override
bool get dontWriteConstraints => true;
}
abstract class _$Database extends GeneratedDatabase { abstract class _$Database extends GeneratedDatabase {
_$Database(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e); _$Database(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
_$Database.connect(DatabaseConnection c) : super.connect(c); _$Database.connect(DatabaseConnection c) : super.connect(c);
$UsersTable _users; $UsersTable _users;
$UsersTable get users => _users ??= $UsersTable(this); $UsersTable get users => _users ??= $UsersTable(this);
Groups _groups;
Groups get groups => _groups ??= Groups(this);
@override @override
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>(); Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
@override @override
List<DatabaseSchemaEntity> get allSchemaEntities => [users]; List<DatabaseSchemaEntity> get allSchemaEntities => [users, groups];
} }

View File

@ -0,0 +1,7 @@
import 'package:moor/moor.dart';
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()(); // added in schema version 2
}

View File

@ -0,0 +1,11 @@
import 'tables.dart';
-- This table was added in schema version 3
CREATE TABLE "groups" (
id INTEGER NOT NULL,
title TEXT NOT NULL,
deleted BOOLEAN DEFAULT FALSE,
owner INTEGER NOT NULL REFERENCES users (id),
PRIMARY KEY (id)
);

View File

@ -0,0 +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","moor_type":"ColumnType.integer","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":["auto-increment","primary-key"]},{"name":"name","moor_type":"ColumnType.text","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false}},{"id":1,"references":[0],"type":"table","data":{"name":"groups","was_declared_in_moor":true,"columns":[{"name":"id","moor_type":"ColumnType.integer","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"title","moor_type":"ColumnType.text","nullable":false,"customConstraints":"NOT NULL","default_dart":null,"default_client_dart":null,"dsl_features":[]},{"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","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"]}}]}

View File

@ -3,6 +3,7 @@ import 'package:moor/moor.dart';
import 'package:moor_generator/api/migrations.dart'; import 'package:moor_generator/api/migrations.dart';
import 'schema_v1.dart' as v1; import 'schema_v1.dart' as v1;
import 'schema_v2.dart' as v2; import 'schema_v2.dart' as v2;
import 'schema_v3.dart' as v3;
class GeneratedHelper implements SchemaInstantiationHelper { class GeneratedHelper implements SchemaInstantiationHelper {
@override @override
@ -12,8 +13,10 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v1.DatabaseAtV1(db); return v1.DatabaseAtV1(db);
case 2: case 2:
return v2.DatabaseAtV2(db); return v2.DatabaseAtV2(db);
case 3:
return v3.DatabaseAtV3(db);
default: default:
throw MissingSchemaException(version, const {1, 2}); throw MissingSchemaException(version, const {1, 2, 3});
} }
} }
} }

View File

@ -31,6 +31,9 @@ class _Users extends Table with TableInfo {
_Users createAlias(String alias) { _Users createAlias(String alias) {
return _Users(_db, alias); return _Users(_db, alias);
} }
@override
bool get dontWriteConstraints => false;
} }
class DatabaseAtV1 extends GeneratedDatabase { class DatabaseAtV1 extends GeneratedDatabase {

View File

@ -41,6 +41,9 @@ class _Users extends Table with TableInfo {
_Users createAlias(String alias) { _Users createAlias(String alias) {
return _Users(_db, alias); return _Users(_db, alias);
} }
@override
bool get dontWriteConstraints => false;
} }
class DatabaseAtV2 extends GeneratedDatabase { class DatabaseAtV2 extends GeneratedDatabase {

View File

@ -0,0 +1,120 @@
// GENERATED CODE, DO NOT EDIT BY HAND.
import 'package:moor/moor.dart';
class _Users extends Table with TableInfo {
final GeneratedDatabase _db;
final String _alias;
_Users(this._db, [this._alias]);
GeneratedIntColumn _id;
GeneratedIntColumn get id => _id ??= _constructId();
GeneratedIntColumn _constructId() {
return GeneratedIntColumn('id', $tableName, false,
hasAutoIncrement: true, declaredAsPrimaryKey: true);
}
GeneratedTextColumn _name;
GeneratedTextColumn get name => _name ??= _constructName();
GeneratedTextColumn _constructName() {
return GeneratedTextColumn(
'name',
$tableName,
false,
);
}
@override
List<GeneratedColumn> get $columns => [id, name];
@override
_Users get asDslTable => this;
@override
String get $tableName => _alias ?? 'users';
@override
final String actualTableName = 'users';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
Null map(Map<String, dynamic> data, {String tablePrefix}) {
return null;
}
@override
_Users createAlias(String alias) {
return _Users(_db, alias);
}
@override
bool get dontWriteConstraints => false;
}
class _Groups extends Table with TableInfo {
final GeneratedDatabase _db;
final String _alias;
_Groups(this._db, [this._alias]);
GeneratedIntColumn _id;
GeneratedIntColumn get id => _id ??= _constructId();
GeneratedIntColumn _constructId() {
return GeneratedIntColumn('id', $tableName, false,
$customConstraints: 'NOT NULL');
}
GeneratedTextColumn _title;
GeneratedTextColumn get title => _title ??= _constructTitle();
GeneratedTextColumn _constructTitle() {
return GeneratedTextColumn('title', $tableName, false,
$customConstraints: 'NOT NULL');
}
GeneratedBoolColumn _deleted;
GeneratedBoolColumn get deleted => _deleted ??= _constructDeleted();
GeneratedBoolColumn _constructDeleted() {
return GeneratedBoolColumn('deleted', $tableName, true,
$customConstraints: 'DEFAULT FALSE');
}
GeneratedIntColumn _owner;
GeneratedIntColumn get owner => _owner ??= _constructOwner();
GeneratedIntColumn _constructOwner() {
return GeneratedIntColumn('owner', $tableName, false,
$customConstraints: 'NOT NULL REFERENCES users (id)');
}
@override
List<GeneratedColumn> get $columns => [id, title, deleted, owner];
@override
_Groups get asDslTable => this;
@override
String get $tableName => _alias ?? 'groups';
@override
final String actualTableName = 'groups';
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
Null map(Map<String, dynamic> data, {String tablePrefix}) {
return null;
}
@override
_Groups createAlias(String alias) {
return _Groups(_db, alias);
}
@override
List<String> get customConstraints => const ['PRIMARY KEY (id)'];
@override
bool get dontWriteConstraints => true;
}
class DatabaseAtV3 extends GeneratedDatabase {
DatabaseAtV3(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
DatabaseAtV3.connect(DatabaseConnection c) : super.connect(c);
_Users _users;
_Users get users => _users ??= _Users(this);
_Groups _groups;
_Groups get groups => _groups ??= _Groups(this);
@override
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities => [users, groups];
@override
int get schemaVersion => 3;
}

View File

@ -14,8 +14,15 @@ void main() {
test('upgrade from v1 to v2', () async { test('upgrade from v1 to v2', () async {
final connection = await verifier.startAt(1); final connection = await verifier.startAt(1);
final db = Database(2, connection); final db = Database(connection);
await verifier.migrateAndValidate(db, 2); await verifier.migrateAndValidate(db, 2);
}); });
test('upgrade from v2 to v3', () async {
final connection = await verifier.startAt(2);
final db = Database(connection);
await verifier.migrateAndValidate(db, 3);
});
} }