1
- import 'package:serverpod_shared/serverpod_shared.dart' ;
2
1
import 'package:serverpod_service_client/serverpod_service_client.dart' ;
2
+ import 'package:serverpod_shared/serverpod_shared.dart' ;
3
+
3
4
import 'extensions.dart' ;
4
5
5
6
DatabaseMigration generateDatabaseMigration ({
@@ -9,17 +10,25 @@ DatabaseMigration generateDatabaseMigration({
9
10
var warnings = < DatabaseMigrationWarning > [];
10
11
var actions = < DatabaseMigrationAction > [];
11
12
12
- // Find deleted tables
13
- var deleteTables = < String > [];
14
- var sourceTables = databaseSource.tables.where ((table) => table.isManaged);
15
- var targetTables = databaseTarget.tables.where ((table) => table.isManaged);
13
+ var sourceTables =
14
+ databaseSource.tables.where ((table) => table.isManaged).toList ();
15
+ var targetTables =
16
+ databaseTarget.tables.where ((table) => table.isManaged).toList ();
17
+ var deleteTables = < String > {};
16
18
19
+ // Mark tables which do not exist in the target schema anymore for deletion
17
20
for (var srcTable in sourceTables) {
18
21
if (! databaseTarget.containsTableNamed (srcTable.name)) {
19
- deleteTables.add (srcTable.name);
22
+ deleteTables.addAll ([
23
+ srcTable.name,
24
+ // For any table we delete, we also need to delete any other existing table that has and retains a foreign key pointing into this table
25
+ ..._findDependentTables (srcTable.name,
26
+ sourceTables: sourceTables, targetTables: targetTables),
27
+ ]);
20
28
}
21
29
}
22
- for (var tableName in deleteTables.reversed) {
30
+
31
+ for (var tableName in deleteTables.toList ().reversed) {
23
32
actions.add (
24
33
DatabaseMigrationAction (
25
34
type: DatabaseMigrationActionType .deleteTable,
@@ -43,12 +52,13 @@ DatabaseMigration generateDatabaseMigration({
43
52
(table) => table? .name == dstTable.name,
44
53
orElse: () => null );
45
54
46
- if (srcTable == null || srcTable.managed == false ) {
55
+ if (srcTable == null ||
56
+ srcTable.managed == false ||
57
+ deleteTables.contains (srcTable.name)) {
47
58
// Added table
48
-
49
59
actions.add (
50
60
DatabaseMigrationAction (
51
- type: srcTable == null
61
+ type: srcTable == null || deleteTables. contains (srcTable.name)
52
62
? DatabaseMigrationActionType .createTable
53
63
: DatabaseMigrationActionType .createTableIfNotExists,
54
64
createTable: dstTable,
@@ -92,6 +102,47 @@ DatabaseMigration generateDatabaseMigration({
92
102
);
93
103
}
94
104
105
+ /// Returns the set of table names for all tables which have any relation into the table mentioned by [tableName]
106
+ Set <String > _findDependentTables (
107
+ String tableName, {
108
+ required List <TableDefinition > sourceTables,
109
+ required List <TableDefinition > targetTables,
110
+ Set <String >? dependentTables,
111
+ }) {
112
+ dependentTables ?? = {};
113
+
114
+ /// Returns whether the [sourceTable] has a current and future relation to [tableName]
115
+ bool hasCurrentAndFutureRelationToTable (TableDefinition sourceTable) {
116
+ return sourceTable.foreignKeys.any ((foreignKey) =>
117
+ foreignKey.referenceTable == tableName &&
118
+ // Check whether the reference will also be upheld in the target table.
119
+ // otherwise the target table will already be modified and does not need to have be fully dropped
120
+ targetTables.any ((targetTable) =>
121
+ targetTable.name == sourceTable.name &&
122
+ targetTable.foreignKeys.any ((targetForeignKey) =>
123
+ targetForeignKey.constraintName == foreignKey.constraintName)));
124
+ }
125
+
126
+ for (var sourceTable in sourceTables) {
127
+ if (dependentTables.contains (sourceTable.name)) {
128
+ continue ;
129
+ }
130
+
131
+ if (hasCurrentAndFutureRelationToTable (sourceTable)) {
132
+ dependentTables.add (sourceTable.name);
133
+
134
+ _findDependentTables (
135
+ sourceTable.name,
136
+ sourceTables: sourceTables,
137
+ targetTables: targetTables,
138
+ dependentTables: dependentTables,
139
+ );
140
+ }
141
+ }
142
+
143
+ return dependentTables;
144
+ }
145
+
95
146
TableMigration ? generateTableMigration (
96
147
TableDefinition srcTable,
97
148
TableDefinition dstTable,
@@ -247,6 +298,7 @@ TableMigration? generateTableMigration(
247
298
}
248
299
if (! srcKey.like (dstKey)) {
249
300
deleteForeignKeys.add (srcKey.constraintName);
301
+
250
302
addForeignKeys.add (dstKey);
251
303
}
252
304
}
0 commit comments