@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.
Files changed (46) hide show
  1. package/jest.config.js +10 -0
  2. package/lib/dialects/dialect.js +45 -0
  3. package/lib/dialects/index.js +6 -112
  4. package/lib/dialects/mysql/index.js +51 -0
  5. package/lib/dialects/mysql/schema-inspector.js +199 -0
  6. package/lib/dialects/postgresql/index.js +49 -0
  7. package/lib/dialects/postgresql/schema-inspector.js +232 -0
  8. package/lib/dialects/sqlite/index.js +73 -0
  9. package/lib/dialects/sqlite/schema-inspector.js +151 -0
  10. package/lib/entity-manager.js +18 -14
  11. package/lib/entity-repository.js +2 -3
  12. package/lib/errors.js +44 -2
  13. package/lib/fields.d.ts +2 -3
  14. package/lib/fields.js +7 -16
  15. package/lib/index.d.ts +67 -22
  16. package/lib/index.js +44 -27
  17. package/lib/lifecycles/index.d.ts +50 -0
  18. package/lib/{lifecycles.js → lifecycles/index.js} +25 -14
  19. package/lib/lifecycles/subscribers/index.d.ts +9 -0
  20. package/lib/lifecycles/subscribers/models-lifecycles.js +19 -0
  21. package/lib/lifecycles/subscribers/timestamps.js +65 -0
  22. package/lib/metadata/index.js +84 -95
  23. package/lib/metadata/relations.js +16 -0
  24. package/lib/migrations/index.d.ts +9 -0
  25. package/lib/migrations/index.js +69 -0
  26. package/lib/migrations/storage.js +51 -0
  27. package/lib/query/helpers/join.js +3 -5
  28. package/lib/query/helpers/order-by.js +21 -11
  29. package/lib/query/helpers/populate.js +35 -10
  30. package/lib/query/helpers/search.js +26 -12
  31. package/lib/query/helpers/transform.js +42 -14
  32. package/lib/query/helpers/where.js +92 -57
  33. package/lib/query/query-builder.js +116 -34
  34. package/lib/schema/__tests__/schema-diff.test.js +14 -1
  35. package/lib/schema/builder.js +315 -284
  36. package/lib/schema/diff.js +374 -0
  37. package/lib/schema/index.d.ts +49 -0
  38. package/lib/schema/index.js +47 -50
  39. package/lib/schema/schema.js +21 -26
  40. package/lib/schema/storage.js +79 -0
  41. package/lib/utils/content-types.js +0 -1
  42. package/package.json +26 -21
  43. package/examples/data.sqlite +0 -0
  44. package/lib/configuration.js +0 -49
  45. package/lib/schema/schema-diff.js +0 -337
  46. package/lib/schema/schema-storage.js +0 -44
@@ -1,344 +1,375 @@
1
1
  'use strict';
2
2
 
3
- const { isUndefined } = require('lodash/fp');
4
- const debug = require('debug')('@strapi/database');
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
- module.exports = db => ({
110
+ const createHelpers = db => {
7
111
  /**
8
- * Returns a knex schema builder instance
9
- * @param {string} table - table name
112
+ * Creates a foreign key on a table
113
+ * @param {Knex.TableBuilder} tableBuilder
114
+ * @param {ForeignKey} foreignKey
10
115
  */
11
- getSchemaBuilder(table, trx = db.connection) {
12
- return table.schema ? trx.schema.withSchema(table.schema) : trx.schema;
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
- * Creates schema in DB
17
- * @param {Schema} schema - database schema
138
+ * Drops a foreign key from a table
139
+ * @param {Knex.TableBuilder} tableBuilder
140
+ * @param {ForeignKey} foreignKey
18
141
  */
19
- async createSchema(schema) {
20
- // TODO: ensure database exists;
142
+ const dropForeignKey = (tableBuilder, foreignKey) => {
143
+ const { name, columns } = foreignKey;
21
144
 
22
- await db.connection.transaction(async trx => {
23
- // create tables without FKs first do avoid ordering issues
24
- await this.createTables(schema.tables, trx);
25
- });
26
- },
145
+ tableBuilder.dropForeign(columns, name);
146
+ };
27
147
 
28
148
  /**
29
- * Creates a list of tables in a schema
30
- * @param {KnexInstance} trx
31
- * @param {Table[]} tables
149
+ * Creates an index on a table
150
+ * @param {Knex.TableBuilder} tableBuilder
151
+ * @param {Index} index
32
152
  */
33
- async createTables(tables, trx) {
34
- for (const table of tables) {
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
- // 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(table, trx);
44
- await createTableForeignKeys(schemaBuilder, table);
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 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
170
+ * Drops an index from table
171
+ * @param {Knex.TableBuilder} tableBuilder
172
+ * @param {Index} index
52
173
  */
53
- async dropSchema(schema, { dropDatabase = false } = {}) {
54
- if (dropDatabase) {
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
- await db.connection.transaction(async trx => {
60
- for (const table of schema.tables.reverse()) {
61
- const schemaBuilder = this.getSchemaBuilder(table, trx);
62
- await dropTable(schemaBuilder, table);
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
- * Applies a schema diff update in the DB
69
- * @param {*} schemaDiff
195
+ * Creates a column in a table
196
+ * @param {Knex.TableBuilder} tableBuilder
197
+ * @param {Column} column
70
198
  */
71
- // TODO: implement force option to disable removal in DB
72
- async updateSchema(schemaDiff) {
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
- // drop all delete table foreign keys then delete the tables
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
- const schemaBuilder = this.getSchemaBuilder(table, trx);
81
- await dropTableForeignKeys(schemaBuilder, table);
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
- for (const table of schemaDiff.tables.updated) {
92
- debug(`Updating table: ${table.name}`);
93
- // alter table
94
- const schemaBuilder = this.getSchemaBuilder(table, trx);
208
+ if (!isNil(defaultTo)) {
209
+ const [value, opts] = castArray(defaultTo);
95
210
 
96
- await alterTable(schemaBuilder, table);
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
- * Drops an index from table
158
- * @param {Knex.TableBuilder} tableBuilder
159
- * @param {Index} index
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
- case 'unique': {
169
- return tableBuilder.dropUnique(columns, name);
170
- }
171
- default: {
172
- return tableBuilder.dropIndex(columns, name);
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
- * Creates a column in a table
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
- const col = tableBuilder[type](name, ...args);
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
- if (unsigned) {
188
- col.unsigned();
189
- }
250
+ // indexes
251
+ (table.indexes || []).forEach(index => createIndex(tableBuilder, index));
190
252
 
191
- if (!isUndefined(defaultTo)) {
192
- // TODO: allow some raw default values
193
- col.defaultTo(...[].concat(defaultTo));
194
- }
253
+ // foreign keys
195
254
 
196
- if (notNullable) {
197
- col.notNullable();
198
- } else {
199
- col.nullable();
200
- }
255
+ if (!db.dialect.canAlterConstraints()) {
256
+ (table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey));
257
+ }
258
+ });
259
+ };
201
260
 
202
- return col;
203
- };
261
+ const alterTable = async (schemaBuilder, table) => {
262
+ await schemaBuilder.alterTable(table.name, tableBuilder => {
263
+ // Delete indexes / fks / columns
204
264
 
205
- /**
206
- * Drops a column from a table
207
- * @param {Knex.TableBuilder} tableBuilder
208
- * @param {Column} column
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
- * Creates a table in a database
216
- * @param {SchemaBuilder} schemaBuilder
217
- * @param {Table} table
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 alterTable = async (schemaBuilder, table) => {
237
- await schemaBuilder.alterTable(table.name, tableBuilder => {
238
- // Delete indexes / fks / columns
275
+ for (const removedForeignKey of table.foreignKeys.removed) {
276
+ debug(`Dropping foreign key ${removedForeignKey.name}`);
277
+ dropForeignKey(tableBuilder, removedForeignKey);
278
+ }
239
279
 
240
- for (const removedIndex of table.indexes.removed) {
241
- debug(`Dropping index ${removedIndex.name}`);
242
- dropIndex(tableBuilder, removedIndex);
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
- for (const updateddIndex of table.indexes.updated) {
246
- debug(`Dropping updated index ${updateddIndex.name}`);
247
- dropIndex(tableBuilder, updateddIndex);
248
- }
285
+ for (const removedColumn of table.columns.removed) {
286
+ debug(`Dropping column ${removedColumn.name}`);
287
+ dropColumn(tableBuilder, removedColumn);
288
+ }
249
289
 
250
- for (const removedForeignKey of table.foreignKeys.removed) {
251
- debug(`Dropping foreign key ${removedForeignKey.name}`);
252
- dropForeignKey(tableBuilder, removedForeignKey);
253
- }
290
+ // Update existing columns / foreign keys / indexes
254
291
 
255
- for (const updatedForeignKey of table.foreignKeys.updated) {
256
- debug(`Dropping updated foreign key ${updatedForeignKey.name}`);
257
- dropForeignKey(tableBuilder, updatedForeignKey);
258
- }
292
+ for (const updatedColumn of table.columns.updated) {
293
+ debug(`Updating column ${updatedColumn.name}`);
259
294
 
260
- for (const removedColumn of table.columns.removed) {
261
- debug(`Dropping column ${removedColumn.name}`);
262
- dropColumn(tableBuilder, removedColumn);
263
- }
295
+ const { object } = updatedColumn;
264
296
 
265
- // Update existing columns / foreign keys / indexes
297
+ createColumn(tableBuilder, object).alter();
298
+ }
266
299
 
267
- for (const updatedColumn of table.columns.updated) {
268
- debug(`Updating column ${updatedColumn.name}`);
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
- // TODO: cleanup diffs for columns
271
- const { object } = updatedColumn;
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
- type -> recreate the type
275
- args -> recreate the type
276
- unsigned
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
- createColumn(tableBuilder, object).alter();
286
- }
315
+ for (const addedForeignKey of table.foreignKeys.added) {
316
+ debug(`Creating foreign keys ${addedForeignKey.name}`);
317
+ createForeignKey(tableBuilder, addedForeignKey);
318
+ }
287
319
 
288
- for (const updatedForeignKey of table.foreignKeys.updated) {
289
- debug(`Recreating updated foreign key ${updatedForeignKey.name}`);
290
- createForeignKey(tableBuilder, updatedForeignKey);
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
- for (const updatedIndex of table.indexes.updated) {
294
- debug(`Recreating updated index ${updatedIndex.name}`);
295
- createIndex(tableBuilder, updatedIndex);
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
- for (const addedColumn of table.columns.added) {
299
- debug(`Creating column ${addedColumn.name}`);
300
- createColumn(tableBuilder, addedColumn);
301
- }
337
+ return schemaBuilder.dropTableIfExists(table.name);
338
+ };
302
339
 
303
- for (const addedForeignKey of table.foreignKeys.added) {
304
- debug(`Creating foreign keys ${addedForeignKey.name}`);
305
- createForeignKey(tableBuilder, addedForeignKey);
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
- for (const addedIndex of table.indexes.added) {
309
- debug(`Creating index ${addedIndex.name}`);
310
- createIndex(tableBuilder, addedIndex);
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
- * Drops a table from a database
317
- * @param {Knex.SchemaBuilder} schemaBuilder
318
- * @param {Table} table
319
- */
320
- const dropTable = (schemaBuilder, table) => schemaBuilder.dropTableIfExists(table.name);
321
-
322
- /**
323
- * Creates a table foreign keys constraints
324
- * @param {SchemaBuilder} schemaBuilder
325
- * @param {Table} table
326
- */
327
- const createTableForeignKeys = async (schemaBuilder, table) => {
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
  };