| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | const { isNil, prop, omit, castArray } = require('lodash/fp'); | 
					
						
							|  |  |  | const debug = require('debug')('strapi::database'); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | module.exports = db => { | 
					
						
							|  |  |  |   const helpers = createHelpers(db); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns a knex schema builder instance | 
					
						
							|  |  |  |      * @param {string} table - table name | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |     getSchemaBuilder(trx) { | 
					
						
							|  |  |  |       return db.getSchemaConnection(trx); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Creates schema in DB | 
					
						
							|  |  |  |      * @param {Schema} schema - database schema | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async createSchema(schema) { | 
					
						
							|  |  |  |       await db.connection.transaction(async trx => { | 
					
						
							|  |  |  |         await this.createTables(schema.tables, trx); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Creates a list of tables in a schema | 
					
						
							|  |  |  |      * @param {KnexInstance} trx | 
					
						
							|  |  |  |      * @param {Table[]} tables | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async createTables(tables, trx) { | 
					
						
							|  |  |  |       for (const table of tables) { | 
					
						
							|  |  |  |         debug(`Creating table: ${table.name}`); | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |         const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         await helpers.createTable(schemaBuilder, table); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       // create FKs once all the tables exist
 | 
					
						
							|  |  |  |       for (const table of tables) { | 
					
						
							|  |  |  |         debug(`Creating table foreign keys: ${table.name}`); | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |         const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         await helpers.createTableForeignKeys(schemaBuilder, table); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Drops schema from DB | 
					
						
							|  |  |  |      * @param {Schema} schema - database schema | 
					
						
							|  |  |  |      * @param {object} opts | 
					
						
							|  |  |  |      * @param {boolean} opts.dropDatabase - weather to drop the entire database or simply drop the tables | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     async dropSchema(schema, { dropDatabase = false } = {}) { | 
					
						
							|  |  |  |       if (dropDatabase) { | 
					
						
							|  |  |  |         // TODO: drop database & return as it will drop everything
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       await db.connection.transaction(async trx => { | 
					
						
							|  |  |  |         for (const table of schema.tables.reverse()) { | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |           const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |           await helpers.dropTable(schemaBuilder, table); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Applies a schema diff update in the DB | 
					
						
							|  |  |  |      * @param {*} schemaDiff | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     // TODO: implement force option to disable removal in DB
 | 
					
						
							|  |  |  |     async updateSchema(schemaDiff) { | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |       const { forceMigration } = db.config.settings; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |       await db.dialect.startSchemaUpdate(); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       await db.connection.transaction(async trx => { | 
					
						
							|  |  |  |         await this.createTables(schemaDiff.tables.added, trx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |         if (forceMigration) { | 
					
						
							|  |  |  |           // drop all delete table foreign keys then delete the tables
 | 
					
						
							|  |  |  |           for (const table of schemaDiff.tables.removed) { | 
					
						
							|  |  |  |             debug(`Removing table foreign keys: ${table.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |             const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							|  |  |  |             await helpers.dropTableForeignKeys(schemaBuilder, table); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |           for (const table of schemaDiff.tables.removed) { | 
					
						
							|  |  |  |             debug(`Removing table: ${table.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |             const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							|  |  |  |             await helpers.dropTable(schemaBuilder, table); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const table of schemaDiff.tables.updated) { | 
					
						
							|  |  |  |           debug(`Updating table: ${table.name}`); | 
					
						
							|  |  |  |           // alter table
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |           const schemaBuilder = this.getSchemaBuilder(trx); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           await helpers.alterTable(schemaBuilder, table); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       await db.dialect.endSchemaUpdate(); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | const createHelpers = db => { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |    *  Creates a foreign key on a table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {ForeignKey} foreignKey | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   const createForeignKey = (tableBuilder, foreignKey) => { | 
					
						
							|  |  |  |     const { name, columns, referencedColumns, referencedTable, onDelete, onUpdate } = foreignKey; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const constraint = tableBuilder | 
					
						
							|  |  |  |       .foreign(columns, name) | 
					
						
							|  |  |  |       .references(referencedColumns) | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |       .inTable( | 
					
						
							|  |  |  |         db.connection.getSchemaName() | 
					
						
							|  |  |  |           ? `${db.connection.getSchemaName()}.${referencedTable}` | 
					
						
							|  |  |  |           : referencedTable | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (onDelete) { | 
					
						
							|  |  |  |       constraint.onDelete(onDelete); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     if (onUpdate) { | 
					
						
							|  |  |  |       constraint.onUpdate(onUpdate); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |    * Drops a foreign key from a table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {ForeignKey} foreignKey | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   const dropForeignKey = (tableBuilder, foreignKey) => { | 
					
						
							|  |  |  |     const { name, columns } = foreignKey; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     tableBuilder.dropForeign(columns, name); | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   /** | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |    * Creates an index on a table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {Index} index | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   const createIndex = (tableBuilder, index) => { | 
					
						
							|  |  |  |     const { type, columns, name } = index; | 
					
						
							| 
									
										
										
										
											2021-08-06 11:19:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     switch (type) { | 
					
						
							|  |  |  |       case 'primary': { | 
					
						
							|  |  |  |         return tableBuilder.primary(columns, name); | 
					
						
							| 
									
										
										
										
											2021-08-06 11:19:17 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       case 'unique': { | 
					
						
							|  |  |  |         return tableBuilder.unique(columns, name); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: { | 
					
						
							|  |  |  |         return tableBuilder.index(columns, name, type); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Drops an index from table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {Index} index | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const dropIndex = (tableBuilder, index) => { | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |     if (!db.config.settings.forceMigration) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     const { type, columns, name } = index; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     switch (type) { | 
					
						
							|  |  |  |       case 'primary': { | 
					
						
							|  |  |  |         return tableBuilder.dropPrimary(name); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       case 'unique': { | 
					
						
							|  |  |  |         return tableBuilder.dropUnique(columns, name); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       default: { | 
					
						
							|  |  |  |         return tableBuilder.dropIndex(columns, name); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Creates a column in a table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {Column} column | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const createColumn = (tableBuilder, column) => { | 
					
						
							|  |  |  |     const { type, name, args = [], defaultTo, unsigned, notNullable } = column; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     const col = tableBuilder[type](name, ...args); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     if (unsigned === true) { | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       col.unsigned(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     if (!isNil(defaultTo)) { | 
					
						
							|  |  |  |       const [value, opts] = castArray(defaultTo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (prop('isRaw', opts)) { | 
					
						
							|  |  |  |         col.defaultTo(db.connection.raw(value), omit('isRaw', opts)); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         col.defaultTo(value, opts); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     if (notNullable === true) { | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       col.notNullable(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       col.nullable(); | 
					
						
							| 
									
										
										
										
											2021-06-02 15:53:22 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     return col; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Drops a column from a table | 
					
						
							|  |  |  |    * @param {Knex.TableBuilder} tableBuilder | 
					
						
							|  |  |  |    * @param {Column} column | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const dropColumn = (tableBuilder, column) => { | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |     if (!db.config.settings.forceMigration) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return tableBuilder.dropColumn(column.name); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Creates a table in a database | 
					
						
							|  |  |  |    * @param {SchemaBuilder} schemaBuilder | 
					
						
							|  |  |  |    * @param {Table} table | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const createTable = async (schemaBuilder, table) => { | 
					
						
							|  |  |  |     await schemaBuilder.createTable(table.name, tableBuilder => { | 
					
						
							|  |  |  |       // columns
 | 
					
						
							|  |  |  |       (table.columns || []).forEach(column => createColumn(tableBuilder, column)); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       // indexes
 | 
					
						
							|  |  |  |       (table.indexes || []).forEach(index => createIndex(tableBuilder, index)); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       // foreign keys
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |       if (!db.dialect.canAlterConstraints()) { | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         (table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   const alterTable = async (schemaBuilder, table) => { | 
					
						
							|  |  |  |     await schemaBuilder.alterTable(table.name, tableBuilder => { | 
					
						
							|  |  |  |       // Delete indexes / fks / columns
 | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const removedIndex of table.indexes.removed) { | 
					
						
							|  |  |  |         debug(`Dropping index ${removedIndex.name}`); | 
					
						
							|  |  |  |         dropIndex(tableBuilder, removedIndex); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const updateddIndex of table.indexes.updated) { | 
					
						
							|  |  |  |         debug(`Dropping updated index ${updateddIndex.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         dropIndex(tableBuilder, updateddIndex.object); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const removedForeignKey of table.foreignKeys.removed) { | 
					
						
							|  |  |  |         debug(`Dropping foreign key ${removedForeignKey.name}`); | 
					
						
							|  |  |  |         dropForeignKey(tableBuilder, removedForeignKey); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const updatedForeignKey of table.foreignKeys.updated) { | 
					
						
							|  |  |  |         debug(`Dropping updated foreign key ${updatedForeignKey.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         dropForeignKey(tableBuilder, updatedForeignKey.object); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const removedColumn of table.columns.removed) { | 
					
						
							|  |  |  |         debug(`Dropping column ${removedColumn.name}`); | 
					
						
							|  |  |  |         dropColumn(tableBuilder, removedColumn); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       // Update existing columns / foreign keys / indexes
 | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const updatedColumn of table.columns.updated) { | 
					
						
							|  |  |  |         debug(`Updating column ${updatedColumn.name}`); | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         const { object } = updatedColumn; | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |         createColumn(tableBuilder, object).alter(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const updatedForeignKey of table.foreignKeys.updated) { | 
					
						
							|  |  |  |         debug(`Recreating updated foreign key ${updatedForeignKey.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         createForeignKey(tableBuilder, updatedForeignKey.object); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const updatedIndex of table.indexes.updated) { | 
					
						
							|  |  |  |         debug(`Recreating updated index ${updatedIndex.name}`); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         createIndex(tableBuilder, updatedIndex.object); | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const addedColumn of table.columns.added) { | 
					
						
							|  |  |  |         debug(`Creating column ${addedColumn.name}`); | 
					
						
							|  |  |  |         createColumn(tableBuilder, addedColumn); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const addedForeignKey of table.foreignKeys.added) { | 
					
						
							|  |  |  |         debug(`Creating foreign keys ${addedForeignKey.name}`); | 
					
						
							|  |  |  |         createForeignKey(tableBuilder, addedForeignKey); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |       for (const addedIndex of table.indexes.added) { | 
					
						
							|  |  |  |         debug(`Creating index ${addedIndex.name}`); | 
					
						
							|  |  |  |         createIndex(tableBuilder, addedIndex); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-08-10 09:36:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Drops a table from a database | 
					
						
							|  |  |  |    * @param {Knex.SchemaBuilder} schemaBuilder | 
					
						
							|  |  |  |    * @param {Table} table | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |   const dropTable = (schemaBuilder, table) => { | 
					
						
							|  |  |  |     if (!db.config.settings.forceMigration) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return schemaBuilder.dropTableIfExists(table.name); | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Creates a table foreign keys constraints | 
					
						
							|  |  |  |    * @param {SchemaBuilder} schemaBuilder | 
					
						
							|  |  |  |    * @param {Table} table | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const createTableForeignKeys = async (schemaBuilder, table) => { | 
					
						
							|  |  |  |     // foreign keys
 | 
					
						
							|  |  |  |     await schemaBuilder.table(table.name, tableBuilder => { | 
					
						
							|  |  |  |       (table.foreignKeys || []).forEach(foreignKey => createForeignKey(tableBuilder, foreignKey)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Drops a table foreign keys constraints | 
					
						
							|  |  |  |    * @param {SchemaBuilder} schemaBuilder | 
					
						
							|  |  |  |    * @param {Table} table | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const dropTableForeignKeys = async (schemaBuilder, table) => { | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |     if (!db.config.settings.forceMigration) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 16:54:14 +02:00
										 |  |  |     // foreign keys
 | 
					
						
							|  |  |  |     await schemaBuilder.table(table.name, tableBuilder => { | 
					
						
							|  |  |  |       (table.foreignKeys || []).forEach(foreignKey => dropForeignKey(tableBuilder, foreignKey)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     createTable, | 
					
						
							|  |  |  |     alterTable, | 
					
						
							|  |  |  |     dropTable, | 
					
						
							|  |  |  |     createTableForeignKeys, | 
					
						
							|  |  |  |     dropTableForeignKeys, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-08-06 11:19:17 +02:00
										 |  |  | }; |