Fix use of primary key in migrations

This commit is contained in:
Simon Binder 2019-04-29 18:04:40 +02:00
parent 51ae079c33
commit 211bf56ae7
No known key found for this signature in database
GPG Key ID: B807FDF954BA00CF
5 changed files with 116 additions and 5 deletions

View File

@ -69,7 +69,8 @@ class Migrator {
if (i < table.$columns.length - 1) sql.write(', ');
}
if (table.$primaryKey != null && !hasAutoIncrement) {
final hasPrimaryKey = table.$primaryKey?.isNotEmpty ?? false;
if (hasPrimaryKey && !hasAutoIncrement) {
sql.write(', PRIMARY KEY (');
final pkList = table.$primaryKey.toList(growable: false);
for (var i = 0; i < pkList.length; i++) {

View File

@ -9,8 +9,8 @@ mixin TableInfo<TableDsl extends Table, DataClass> {
/// [TableInfo] and [TableDsl] and can thus just return their instance.
TableDsl get asDslTable;
/// The primary key of this table. Can be null if no custom primary key has
/// been specified
/// The primary key of this table. Can be null or empty if no custom primary
/// key has been specified.
Set<GeneratedColumn> get $primaryKey => null;
/// The table name in the sql table. This can be an alias for the actual table

View File

@ -46,7 +46,13 @@ class SharedTodos extends Table {
];
}
@UseMoor(tables: [TodosTable, Categories, Users, SharedTodos])
class TableWithoutPK extends Table {
IntColumn get notReallyAnId => integer()();
}
@UseMoor(tables: [TodosTable, Categories, Users, SharedTodos, TableWithoutPK])
class TodoDb extends _$TodoDb {
TodoDb(QueryExecutor e) : super(e);

View File

@ -642,6 +642,103 @@ class $SharedTodosTable extends SharedTodos
}
}
class TableWithoutPKData {
final int notReallyAnId;
TableWithoutPKData({this.notReallyAnId});
factory TableWithoutPKData.fromData(
Map<String, dynamic> data, GeneratedDatabase db,
{String prefix}) {
final effectivePrefix = prefix ?? '';
final intType = db.typeSystem.forDartType<int>();
return TableWithoutPKData(
notReallyAnId: intType
.mapFromDatabaseResponse(data['${effectivePrefix}not_really_an_id']),
);
}
factory TableWithoutPKData.fromJson(Map<String, dynamic> json) {
return TableWithoutPKData(
notReallyAnId: json['notReallyAnId'] as int,
);
}
Map<String, dynamic> toJson() {
return {
'notReallyAnId': notReallyAnId,
};
}
TableWithoutPKData copyWith({int notReallyAnId}) => TableWithoutPKData(
notReallyAnId: notReallyAnId ?? this.notReallyAnId,
);
@override
String toString() {
return (StringBuffer('TableWithoutPKData(')
..write('notReallyAnId: $notReallyAnId')
..write(')'))
.toString();
}
@override
int get hashCode => $mrjf($mrjc(0, notReallyAnId.hashCode));
@override
bool operator ==(other) =>
identical(this, other) ||
(other is TableWithoutPKData && other.notReallyAnId == notReallyAnId);
}
class $TableWithoutPKTable extends TableWithoutPK
with TableInfo<$TableWithoutPKTable, TableWithoutPKData> {
final GeneratedDatabase _db;
final String _alias;
$TableWithoutPKTable(this._db, [this._alias]);
GeneratedIntColumn _notReallyAnId;
@override
GeneratedIntColumn get notReallyAnId =>
_notReallyAnId ??= _constructNotReallyAnId();
GeneratedIntColumn _constructNotReallyAnId() {
var cName = 'not_really_an_id';
if (_alias != null) cName = '$_alias.$cName';
return GeneratedIntColumn(
'not_really_an_id',
$tableName,
false,
);
}
@override
List<GeneratedColumn> get $columns => [notReallyAnId];
@override
$TableWithoutPKTable get asDslTable => this;
@override
String get $tableName => _alias ?? 'table_without_p_k';
@override
final String actualTableName = 'table_without_p_k';
@override
bool validateIntegrity(TableWithoutPKData instance, bool isInserting) =>
notReallyAnId.isAcceptableValue(instance.notReallyAnId, isInserting);
@override
Set<GeneratedColumn> get $primaryKey => {};
@override
TableWithoutPKData map(Map<String, dynamic> data, {String tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : null;
return TableWithoutPKData.fromData(data, _db, prefix: effectivePrefix);
}
@override
Map<String, Variable> entityToSql(TableWithoutPKData d,
{bool includeNulls = false}) {
final map = <String, Variable>{};
if (d.notReallyAnId != null || includeNulls) {
map['not_really_an_id'] = Variable<int, IntType>(d.notReallyAnId);
}
return map;
}
@override
$TableWithoutPKTable createAlias(String alias) {
return $TableWithoutPKTable(_db, alias);
}
}
abstract class _$TodoDb extends GeneratedDatabase {
_$TodoDb(QueryExecutor e) : super(const SqlTypeSystem.withDefaults(), e);
$TodosTableTable _todosTable;
@ -652,6 +749,10 @@ abstract class _$TodoDb extends GeneratedDatabase {
$UsersTable get users => _users ??= $UsersTable(this);
$SharedTodosTable _sharedTodos;
$SharedTodosTable get sharedTodos => _sharedTodos ??= $SharedTodosTable(this);
$TableWithoutPKTable _tableWithoutPK;
$TableWithoutPKTable get tableWithoutPK =>
_tableWithoutPK ??= $TableWithoutPKTable(this);
@override
List<TableInfo> get allTables => [todosTable, categories, users, sharedTodos];
List<TableInfo> get allTables =>
[todosTable, categories, users, sharedTodos, tableWithoutPK];
}

View File

@ -40,6 +40,9 @@ void main() {
'FOREIGN KEY (todo) REFERENCES todos(id), '
'FOREIGN KEY (user) REFERENCES users(id)'
');'));
verify(mockQueryExecutor.call('CREATE TABLE IF NOT EXISTS '
'table_without_p_k (not_really_an_id INTEGER NOT NULL);'));
});
test('creates individual tables', () async {