@strapi/database 4.0.0-next.8 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jest.config.js +10 -0
- package/lib/dialects/dialect.js +45 -0
- package/lib/dialects/index.js +6 -112
- package/lib/dialects/mysql/index.js +51 -0
- package/lib/dialects/mysql/schema-inspector.js +199 -0
- package/lib/dialects/postgresql/index.js +49 -0
- package/lib/dialects/postgresql/schema-inspector.js +232 -0
- package/lib/dialects/sqlite/index.js +73 -0
- package/lib/dialects/sqlite/schema-inspector.js +151 -0
- package/lib/entity-manager.js +18 -14
- package/lib/entity-repository.js +2 -3
- package/lib/errors.js +44 -2
- package/lib/fields.d.ts +2 -3
- package/lib/fields.js +7 -16
- package/lib/index.d.ts +67 -22
- package/lib/index.js +44 -27
- package/lib/lifecycles/index.d.ts +50 -0
- package/lib/{lifecycles.js → lifecycles/index.js} +25 -14
- package/lib/lifecycles/subscribers/index.d.ts +9 -0
- package/lib/lifecycles/subscribers/models-lifecycles.js +19 -0
- package/lib/lifecycles/subscribers/timestamps.js +65 -0
- package/lib/metadata/index.js +84 -95
- package/lib/metadata/relations.js +16 -0
- package/lib/migrations/index.d.ts +9 -0
- package/lib/migrations/index.js +69 -0
- package/lib/migrations/storage.js +51 -0
- package/lib/query/helpers/join.js +3 -5
- package/lib/query/helpers/order-by.js +21 -11
- package/lib/query/helpers/populate.js +35 -10
- package/lib/query/helpers/search.js +26 -12
- package/lib/query/helpers/transform.js +42 -14
- package/lib/query/helpers/where.js +92 -57
- package/lib/query/query-builder.js +116 -34
- package/lib/schema/__tests__/schema-diff.test.js +14 -1
- package/lib/schema/builder.js +315 -284
- package/lib/schema/diff.js +374 -0
- package/lib/schema/index.d.ts +49 -0
- package/lib/schema/index.js +47 -50
- package/lib/schema/schema.js +21 -26
- package/lib/schema/storage.js +79 -0
- package/lib/utils/content-types.js +0 -1
- package/package.json +26 -21
- package/examples/data.sqlite +0 -0
- package/lib/configuration.js +0 -49
- package/lib/schema/schema-diff.js +0 -337
- package/lib/schema/schema-storage.js +0 -44
package/lib/schema/builder.js
CHANGED
|
@@ -1,344 +1,375 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const debug = require('debug')('
|
|
3
|
+
const { isNil, prop, omit, castArray } = require('lodash/fp');
|
|
4
|
+
const debug = require('debug')('strapi::database');
|
|
5
|
+
|
|
6
|
+
module.exports = db => {
|
|
7
|
+
const helpers = createHelpers(db);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
/**
|
|
11
|
+
* Returns a knex schema builder instance
|
|
12
|
+
* @param {string} table - table name
|
|
13
|
+
*/
|
|
14
|
+
getSchemaBuilder(trx) {
|
|
15
|
+
return db.getSchemaConnection(trx);
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates schema in DB
|
|
20
|
+
* @param {Schema} schema - database schema
|
|
21
|
+
*/
|
|
22
|
+
async createSchema(schema) {
|
|
23
|
+
await db.connection.transaction(async trx => {
|
|
24
|
+
await this.createTables(schema.tables, trx);
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a list of tables in a schema
|
|
30
|
+
* @param {KnexInstance} trx
|
|
31
|
+
* @param {Table[]} tables
|
|
32
|
+
*/
|
|
33
|
+
async createTables(tables, trx) {
|
|
34
|
+
for (const table of tables) {
|
|
35
|
+
debug(`Creating table: ${table.name}`);
|
|
36
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
37
|
+
await helpers.createTable(schemaBuilder, table);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// create FKs once all the tables exist
|
|
41
|
+
for (const table of tables) {
|
|
42
|
+
debug(`Creating table foreign keys: ${table.name}`);
|
|
43
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
44
|
+
await helpers.createTableForeignKeys(schemaBuilder, table);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Drops schema from DB
|
|
49
|
+
* @param {Schema} schema - database schema
|
|
50
|
+
* @param {object} opts
|
|
51
|
+
* @param {boolean} opts.dropDatabase - weather to drop the entire database or simply drop the tables
|
|
52
|
+
*/
|
|
53
|
+
async dropSchema(schema, { dropDatabase = false } = {}) {
|
|
54
|
+
if (dropDatabase) {
|
|
55
|
+
// TODO: drop database & return as it will drop everything
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
await db.connection.transaction(async trx => {
|
|
60
|
+
for (const table of schema.tables.reverse()) {
|
|
61
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
62
|
+
await helpers.dropTable(schemaBuilder, table);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Applies a schema diff update in the DB
|
|
69
|
+
* @param {*} schemaDiff
|
|
70
|
+
*/
|
|
71
|
+
// TODO: implement force option to disable removal in DB
|
|
72
|
+
async updateSchema(schemaDiff) {
|
|
73
|
+
const { forceMigration } = db.config.settings;
|
|
74
|
+
|
|
75
|
+
await db.dialect.startSchemaUpdate();
|
|
76
|
+
await db.connection.transaction(async trx => {
|
|
77
|
+
await this.createTables(schemaDiff.tables.added, trx);
|
|
78
|
+
|
|
79
|
+
if (forceMigration) {
|
|
80
|
+
// drop all delete table foreign keys then delete the tables
|
|
81
|
+
for (const table of schemaDiff.tables.removed) {
|
|
82
|
+
debug(`Removing table foreign keys: ${table.name}`);
|
|
83
|
+
|
|
84
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
85
|
+
await helpers.dropTableForeignKeys(schemaBuilder, table);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const table of schemaDiff.tables.removed) {
|
|
89
|
+
debug(`Removing table: ${table.name}`);
|
|
90
|
+
|
|
91
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
92
|
+
await helpers.dropTable(schemaBuilder, table);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const table of schemaDiff.tables.updated) {
|
|
97
|
+
debug(`Updating table: ${table.name}`);
|
|
98
|
+
// alter table
|
|
99
|
+
const schemaBuilder = this.getSchemaBuilder(trx);
|
|
100
|
+
|
|
101
|
+
await helpers.alterTable(schemaBuilder, table);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await db.dialect.endSchemaUpdate();
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
};
|
|
5
109
|
|
|
6
|
-
|
|
110
|
+
const createHelpers = db => {
|
|
7
111
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param {
|
|
112
|
+
* Creates a foreign key on a table
|
|
113
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
114
|
+
* @param {ForeignKey} foreignKey
|
|
10
115
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
116
|
+
const createForeignKey = (tableBuilder, foreignKey) => {
|
|
117
|
+
const { name, columns, referencedColumns, referencedTable, onDelete, onUpdate } = foreignKey;
|
|
118
|
+
|
|
119
|
+
const constraint = tableBuilder
|
|
120
|
+
.foreign(columns, name)
|
|
121
|
+
.references(referencedColumns)
|
|
122
|
+
.inTable(
|
|
123
|
+
db.connection.getSchemaName()
|
|
124
|
+
? `${db.connection.getSchemaName()}.${referencedTable}`
|
|
125
|
+
: referencedTable
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
if (onDelete) {
|
|
129
|
+
constraint.onDelete(onDelete);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (onUpdate) {
|
|
133
|
+
constraint.onUpdate(onUpdate);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
14
136
|
|
|
15
137
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @param {
|
|
138
|
+
* Drops a foreign key from a table
|
|
139
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
140
|
+
* @param {ForeignKey} foreignKey
|
|
18
141
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
142
|
+
const dropForeignKey = (tableBuilder, foreignKey) => {
|
|
143
|
+
const { name, columns } = foreignKey;
|
|
21
144
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
await this.createTables(schema.tables, trx);
|
|
25
|
-
});
|
|
26
|
-
},
|
|
145
|
+
tableBuilder.dropForeign(columns, name);
|
|
146
|
+
};
|
|
27
147
|
|
|
28
148
|
/**
|
|
29
|
-
* Creates
|
|
30
|
-
* @param {
|
|
31
|
-
* @param {
|
|
149
|
+
* Creates an index on a table
|
|
150
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
151
|
+
* @param {Index} index
|
|
32
152
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
debug(`Creating table: ${table.name}`);
|
|
36
|
-
const schemaBuilder = this.getSchemaBuilder(table, trx);
|
|
37
|
-
await createTable(schemaBuilder, table);
|
|
38
|
-
}
|
|
153
|
+
const createIndex = (tableBuilder, index) => {
|
|
154
|
+
const { type, columns, name } = index;
|
|
39
155
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
156
|
+
switch (type) {
|
|
157
|
+
case 'primary': {
|
|
158
|
+
return tableBuilder.primary(columns, name);
|
|
159
|
+
}
|
|
160
|
+
case 'unique': {
|
|
161
|
+
return tableBuilder.unique(columns, name);
|
|
162
|
+
}
|
|
163
|
+
default: {
|
|
164
|
+
return tableBuilder.index(columns, name, type);
|
|
165
|
+
}
|
|
45
166
|
}
|
|
46
|
-
}
|
|
167
|
+
};
|
|
168
|
+
|
|
47
169
|
/**
|
|
48
|
-
* Drops
|
|
49
|
-
* @param {
|
|
50
|
-
* @param {
|
|
51
|
-
* @param {boolean} opts.dropDatabase - weather to drop the entire database or simply drop the tables
|
|
170
|
+
* Drops an index from table
|
|
171
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
172
|
+
* @param {Index} index
|
|
52
173
|
*/
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
// TODO: drop database & return as it will drop everything
|
|
174
|
+
const dropIndex = (tableBuilder, index) => {
|
|
175
|
+
if (!db.config.settings.forceMigration) {
|
|
56
176
|
return;
|
|
57
177
|
}
|
|
58
178
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
179
|
+
const { type, columns, name } = index;
|
|
180
|
+
|
|
181
|
+
switch (type) {
|
|
182
|
+
case 'primary': {
|
|
183
|
+
return tableBuilder.dropPrimary(name);
|
|
63
184
|
}
|
|
64
|
-
|
|
65
|
-
|
|
185
|
+
case 'unique': {
|
|
186
|
+
return tableBuilder.dropUnique(columns, name);
|
|
187
|
+
}
|
|
188
|
+
default: {
|
|
189
|
+
return tableBuilder.dropIndex(columns, name);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
66
193
|
|
|
67
194
|
/**
|
|
68
|
-
*
|
|
69
|
-
* @param {
|
|
195
|
+
* Creates a column in a table
|
|
196
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
197
|
+
* @param {Column} column
|
|
70
198
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
await db.connection.transaction(async trx => {
|
|
74
|
-
await this.createTables(schemaDiff.tables.added, trx);
|
|
199
|
+
const createColumn = (tableBuilder, column) => {
|
|
200
|
+
const { type, name, args = [], defaultTo, unsigned, notNullable } = column;
|
|
75
201
|
|
|
76
|
-
|
|
77
|
-
for (const table of schemaDiff.tables.removed) {
|
|
78
|
-
debug(`Removing table foreign keys: ${table.name}`);
|
|
202
|
+
const col = tableBuilder[type](name, ...args);
|
|
79
203
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
for (const table of schemaDiff.tables.removed) {
|
|
85
|
-
debug(`Removing table: ${table.name}`);
|
|
86
|
-
|
|
87
|
-
const schemaBuilder = this.getSchemaBuilder(table, trx);
|
|
88
|
-
await dropTable(schemaBuilder, table);
|
|
89
|
-
}
|
|
204
|
+
if (unsigned === true) {
|
|
205
|
+
col.unsigned();
|
|
206
|
+
}
|
|
90
207
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// alter table
|
|
94
|
-
const schemaBuilder = this.getSchemaBuilder(table, trx);
|
|
208
|
+
if (!isNil(defaultTo)) {
|
|
209
|
+
const [value, opts] = castArray(defaultTo);
|
|
95
210
|
|
|
96
|
-
|
|
211
|
+
if (prop('isRaw', opts)) {
|
|
212
|
+
col.defaultTo(db.connection.raw(value), omit('isRaw', opts));
|
|
213
|
+
} else {
|
|
214
|
+
col.defaultTo(value, opts);
|
|
97
215
|
}
|
|
98
|
-
});
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Creates a foreign key on a table
|
|
104
|
-
* @param {Knex.TableBuilder} tableBuilder
|
|
105
|
-
* @param {ForeignKey} foreignKey
|
|
106
|
-
*/
|
|
107
|
-
const createForeignKey = (tableBuilder, foreignKey) => {
|
|
108
|
-
const { name, columns, referencedColumns, referencedTable, onDelete, onUpdate } = foreignKey;
|
|
109
|
-
|
|
110
|
-
const constraint = tableBuilder
|
|
111
|
-
.foreign(columns, name)
|
|
112
|
-
.references(referencedColumns)
|
|
113
|
-
.inTable(referencedTable);
|
|
114
|
-
|
|
115
|
-
if (onDelete) {
|
|
116
|
-
constraint.onDelete(onDelete);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (onUpdate) {
|
|
120
|
-
constraint.onUpdate(onUpdate);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Drops a foreign key from a table
|
|
126
|
-
* @param {Knex.TableBuilder} tableBuilder
|
|
127
|
-
* @param {ForeignKey} foreignKey
|
|
128
|
-
*/
|
|
129
|
-
const dropForeignKey = (tableBuilder, foreignKey) => {
|
|
130
|
-
const { name, columns } = foreignKey;
|
|
131
|
-
|
|
132
|
-
tableBuilder.dropForeign(columns, name);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Creates an index on a table
|
|
137
|
-
* @param {Knex.TableBuilder} tableBuilder
|
|
138
|
-
* @param {Index} index
|
|
139
|
-
*/
|
|
140
|
-
const createIndex = (tableBuilder, index) => {
|
|
141
|
-
const { type, columns, name } = index;
|
|
142
|
-
|
|
143
|
-
switch (type) {
|
|
144
|
-
case 'primary': {
|
|
145
|
-
return tableBuilder.primary(columns, name);
|
|
146
216
|
}
|
|
147
|
-
case 'unique': {
|
|
148
|
-
return tableBuilder.unique(columns, name);
|
|
149
|
-
}
|
|
150
|
-
default: {
|
|
151
|
-
return tableBuilder.index(columns, name, type);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
217
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
*/
|
|
161
|
-
const dropIndex = (tableBuilder, index) => {
|
|
162
|
-
const { type, columns, name } = index;
|
|
163
|
-
|
|
164
|
-
switch (type) {
|
|
165
|
-
case 'primary': {
|
|
166
|
-
return tableBuilder.dropPrimary(name);
|
|
218
|
+
if (notNullable === true) {
|
|
219
|
+
col.notNullable();
|
|
220
|
+
} else {
|
|
221
|
+
col.nullable();
|
|
167
222
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
223
|
+
|
|
224
|
+
return col;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Drops a column from a table
|
|
229
|
+
* @param {Knex.TableBuilder} tableBuilder
|
|
230
|
+
* @param {Column} column
|
|
231
|
+
*/
|
|
232
|
+
const dropColumn = (tableBuilder, column) => {
|
|
233
|
+
if (!db.config.settings.forceMigration) {
|
|
234
|
+
return;
|
|
173
235
|
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
236
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
* @param {Knex.TableBuilder} tableBuilder
|
|
180
|
-
* @param {Column} column
|
|
181
|
-
*/
|
|
182
|
-
const createColumn = (tableBuilder, column) => {
|
|
183
|
-
const { type, name, args = [], defaultTo, unsigned, notNullable } = column;
|
|
237
|
+
return tableBuilder.dropColumn(column.name);
|
|
238
|
+
};
|
|
184
239
|
|
|
185
|
-
|
|
240
|
+
/**
|
|
241
|
+
* Creates a table in a database
|
|
242
|
+
* @param {SchemaBuilder} schemaBuilder
|
|
243
|
+
* @param {Table} table
|
|
244
|
+
*/
|
|
245
|
+
const createTable = async (schemaBuilder, table) => {
|
|
246
|
+
await schemaBuilder.createTable(table.name, tableBuilder => {
|
|
247
|
+
// columns
|
|
248
|
+
(table.columns || []).forEach(column => createColumn(tableBuilder, column));
|
|
186
249
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
250
|
+
// indexes
|
|
251
|
+
(table.indexes || []).forEach(index => createIndex(tableBuilder, index));
|
|
190
252
|
|
|
191
|
-
|
|
192
|
-
// TODO: allow some raw default values
|
|
193
|
-
col.defaultTo(...[].concat(defaultTo));
|
|
194
|
-
}
|
|
253
|
+
// foreign keys
|
|
195
254
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
255
|
+
if (!db.dialect.canAlterConstraints()) {
|
|
256
|
+
(table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey));
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
};
|
|
201
260
|
|
|
202
|
-
|
|
203
|
-
|
|
261
|
+
const alterTable = async (schemaBuilder, table) => {
|
|
262
|
+
await schemaBuilder.alterTable(table.name, tableBuilder => {
|
|
263
|
+
// Delete indexes / fks / columns
|
|
204
264
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
*/
|
|
210
|
-
const dropColumn = (tableBuilder, column) => {
|
|
211
|
-
tableBuilder.dropColumn(column.name);
|
|
212
|
-
};
|
|
265
|
+
for (const removedIndex of table.indexes.removed) {
|
|
266
|
+
debug(`Dropping index ${removedIndex.name}`);
|
|
267
|
+
dropIndex(tableBuilder, removedIndex);
|
|
268
|
+
}
|
|
213
269
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
*/
|
|
219
|
-
const createTable = async (schemaBuilder, table) => {
|
|
220
|
-
if (await schemaBuilder.hasTable(table.name)) {
|
|
221
|
-
debug(`Table ${table.name} already exists trying to alter it`);
|
|
222
|
-
|
|
223
|
-
// TODO: implement a DB sync at some point
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
await schemaBuilder.createTable(table.name, tableBuilder => {
|
|
228
|
-
// columns
|
|
229
|
-
(table.columns || []).forEach(column => createColumn(tableBuilder, column));
|
|
230
|
-
|
|
231
|
-
// indexes
|
|
232
|
-
(table.indexes || []).forEach(index => createIndex(tableBuilder, index));
|
|
233
|
-
});
|
|
234
|
-
};
|
|
270
|
+
for (const updateddIndex of table.indexes.updated) {
|
|
271
|
+
debug(`Dropping updated index ${updateddIndex.name}`);
|
|
272
|
+
dropIndex(tableBuilder, updateddIndex.object);
|
|
273
|
+
}
|
|
235
274
|
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
275
|
+
for (const removedForeignKey of table.foreignKeys.removed) {
|
|
276
|
+
debug(`Dropping foreign key ${removedForeignKey.name}`);
|
|
277
|
+
dropForeignKey(tableBuilder, removedForeignKey);
|
|
278
|
+
}
|
|
239
279
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
280
|
+
for (const updatedForeignKey of table.foreignKeys.updated) {
|
|
281
|
+
debug(`Dropping updated foreign key ${updatedForeignKey.name}`);
|
|
282
|
+
dropForeignKey(tableBuilder, updatedForeignKey.object);
|
|
283
|
+
}
|
|
244
284
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
285
|
+
for (const removedColumn of table.columns.removed) {
|
|
286
|
+
debug(`Dropping column ${removedColumn.name}`);
|
|
287
|
+
dropColumn(tableBuilder, removedColumn);
|
|
288
|
+
}
|
|
249
289
|
|
|
250
|
-
|
|
251
|
-
debug(`Dropping foreign key ${removedForeignKey.name}`);
|
|
252
|
-
dropForeignKey(tableBuilder, removedForeignKey);
|
|
253
|
-
}
|
|
290
|
+
// Update existing columns / foreign keys / indexes
|
|
254
291
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
dropForeignKey(tableBuilder, updatedForeignKey);
|
|
258
|
-
}
|
|
292
|
+
for (const updatedColumn of table.columns.updated) {
|
|
293
|
+
debug(`Updating column ${updatedColumn.name}`);
|
|
259
294
|
|
|
260
|
-
|
|
261
|
-
debug(`Dropping column ${removedColumn.name}`);
|
|
262
|
-
dropColumn(tableBuilder, removedColumn);
|
|
263
|
-
}
|
|
295
|
+
const { object } = updatedColumn;
|
|
264
296
|
|
|
265
|
-
|
|
297
|
+
createColumn(tableBuilder, object).alter();
|
|
298
|
+
}
|
|
266
299
|
|
|
267
|
-
|
|
268
|
-
|
|
300
|
+
for (const updatedForeignKey of table.foreignKeys.updated) {
|
|
301
|
+
debug(`Recreating updated foreign key ${updatedForeignKey.name}`);
|
|
302
|
+
createForeignKey(tableBuilder, updatedForeignKey.object);
|
|
303
|
+
}
|
|
269
304
|
|
|
270
|
-
|
|
271
|
-
|
|
305
|
+
for (const updatedIndex of table.indexes.updated) {
|
|
306
|
+
debug(`Recreating updated index ${updatedIndex.name}`);
|
|
307
|
+
createIndex(tableBuilder, updatedIndex.object);
|
|
308
|
+
}
|
|
272
309
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if changed then recreate the type
|
|
278
|
-
if removed then check if old value was true -> recreate the type else do nothing
|
|
279
|
-
defaultTo
|
|
280
|
-
reapply the default to previous data
|
|
281
|
-
notNullable
|
|
282
|
-
if null to not null we need a default value to migrate the data
|
|
283
|
-
*/
|
|
310
|
+
for (const addedColumn of table.columns.added) {
|
|
311
|
+
debug(`Creating column ${addedColumn.name}`);
|
|
312
|
+
createColumn(tableBuilder, addedColumn);
|
|
313
|
+
}
|
|
284
314
|
|
|
285
|
-
|
|
286
|
-
|
|
315
|
+
for (const addedForeignKey of table.foreignKeys.added) {
|
|
316
|
+
debug(`Creating foreign keys ${addedForeignKey.name}`);
|
|
317
|
+
createForeignKey(tableBuilder, addedForeignKey);
|
|
318
|
+
}
|
|
287
319
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
320
|
+
for (const addedIndex of table.indexes.added) {
|
|
321
|
+
debug(`Creating index ${addedIndex.name}`);
|
|
322
|
+
createIndex(tableBuilder, addedIndex);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
};
|
|
292
326
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
327
|
+
/**
|
|
328
|
+
* Drops a table from a database
|
|
329
|
+
* @param {Knex.SchemaBuilder} schemaBuilder
|
|
330
|
+
* @param {Table} table
|
|
331
|
+
*/
|
|
332
|
+
const dropTable = (schemaBuilder, table) => {
|
|
333
|
+
if (!db.config.settings.forceMigration) {
|
|
334
|
+
return;
|
|
296
335
|
}
|
|
297
336
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
createColumn(tableBuilder, addedColumn);
|
|
301
|
-
}
|
|
337
|
+
return schemaBuilder.dropTableIfExists(table.name);
|
|
338
|
+
};
|
|
302
339
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
340
|
+
/**
|
|
341
|
+
* Creates a table foreign keys constraints
|
|
342
|
+
* @param {SchemaBuilder} schemaBuilder
|
|
343
|
+
* @param {Table} table
|
|
344
|
+
*/
|
|
345
|
+
const createTableForeignKeys = async (schemaBuilder, table) => {
|
|
346
|
+
// foreign keys
|
|
347
|
+
await schemaBuilder.table(table.name, tableBuilder => {
|
|
348
|
+
(table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey));
|
|
349
|
+
});
|
|
350
|
+
};
|
|
307
351
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
352
|
+
/**
|
|
353
|
+
* Drops a table foreign keys constraints
|
|
354
|
+
* @param {SchemaBuilder} schemaBuilder
|
|
355
|
+
* @param {Table} table
|
|
356
|
+
*/
|
|
357
|
+
const dropTableForeignKeys = async (schemaBuilder, table) => {
|
|
358
|
+
if (!db.config.settings.forceMigration) {
|
|
359
|
+
return;
|
|
311
360
|
}
|
|
312
|
-
});
|
|
313
|
-
};
|
|
314
361
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
// foreign keys
|
|
329
|
-
await schemaBuilder.table(table.name, tableBuilder => {
|
|
330
|
-
(table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey));
|
|
331
|
-
});
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Drops a table foreign keys constraints
|
|
336
|
-
* @param {SchemaBuilder} schemaBuilder
|
|
337
|
-
* @param {Table} table
|
|
338
|
-
*/
|
|
339
|
-
const dropTableForeignKeys = async (schemaBuilder, table) => {
|
|
340
|
-
// foreign keys
|
|
341
|
-
await schemaBuilder.table(table.name, tableBuilder => {
|
|
342
|
-
(table.foreignKeys || []).forEach(foreignKey => dropForeignKey(tableBuilder, foreignKey));
|
|
343
|
-
});
|
|
362
|
+
// foreign keys
|
|
363
|
+
await schemaBuilder.table(table.name, tableBuilder => {
|
|
364
|
+
(table.foreignKeys || []).forEach(foreignKey => dropForeignKey(tableBuilder, foreignKey));
|
|
365
|
+
});
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
return {
|
|
369
|
+
createTable,
|
|
370
|
+
alterTable,
|
|
371
|
+
dropTable,
|
|
372
|
+
createTableForeignKeys,
|
|
373
|
+
dropTableForeignKeys,
|
|
374
|
+
};
|
|
344
375
|
};
|