| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const _ = require('lodash/fp'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  | const RESERVED_TABLE_NAMES = ['strapi_migrations', 'strapi_database_schema']; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | const statuses = { | 
					
						
							|  |  |  |   CHANGED: 'CHANGED', | 
					
						
							|  |  |  |   UNCHANGED: 'UNCHANGED', | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NOTE:We could move the schema to use maps of tables & columns instead of arrays to make it easier to diff
 | 
					
						
							|  |  |  | // => this will make the creation a bit more complicated (ordering, Object.values(tables | columns)) -> not a big pbl
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const helpers = { | 
					
						
							|  |  |  |   hasTable(schema, tableName) { | 
					
						
							|  |  |  |     return schema.tables.findIndex(table => table.name === tableName) !== -1; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   findTable(schema, tableName) { | 
					
						
							|  |  |  |     return schema.tables.find(table => table.name === tableName); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasColumn(table, columnName) { | 
					
						
							|  |  |  |     return table.columns.findIndex(column => column.name === columnName) !== -1; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   findColumn(table, columnName) { | 
					
						
							|  |  |  |     return table.columns.find(column => column.name === columnName); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasIndex(table, columnName) { | 
					
						
							|  |  |  |     return table.indexes.findIndex(column => column.name === columnName) !== -1; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   findIndex(table, columnName) { | 
					
						
							|  |  |  |     return table.indexes.find(column => column.name === columnName); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hasForeignKey(table, columnName) { | 
					
						
							|  |  |  |     return table.foreignKeys.findIndex(column => column.name === columnName) !== -1; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   findForeignKey(table, columnName) { | 
					
						
							|  |  |  |     return table.foreignKeys.find(column => column.name === columnName); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | module.exports = db => { | 
					
						
							|  |  |  |   const hasChangedStatus = diff => diff.status === statuses.CHANGED; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Compares two indexes info | 
					
						
							|  |  |  |    * @param {Object} oldIndex - index info read from DB | 
					
						
							|  |  |  |    * @param {Object} index - newly generate index info | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const diffIndexes = (oldIndex, index) => { | 
					
						
							|  |  |  |     const changes = []; | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     if (_.difference(oldIndex.columns, index.columns).length > 0) { | 
					
						
							|  |  |  |       changes.push('columns'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     if (_.toLower(oldIndex.type) !== _.toLower(index.type)) { | 
					
						
							|  |  |  |       changes.push('type'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     return { | 
					
						
							|  |  |  |       status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         name: index.name, | 
					
						
							|  |  |  |         object: index, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Compares two foreign keys info | 
					
						
							|  |  |  |    * @param {Object} oldForeignKey - foreignKey info read from DB | 
					
						
							|  |  |  |    * @param {Object} foreignKey - newly generate foreignKey info | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const diffForeignKeys = (oldForeignKey, foreignKey) => { | 
					
						
							|  |  |  |     const changes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_.difference(oldForeignKey.columns, foreignKey.columns).length > 0) { | 
					
						
							|  |  |  |       changes.push('columns'); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     if (_.difference(oldForeignKey.referencedColumns, foreignKey.referencedColumns).length > 0) { | 
					
						
							|  |  |  |       changes.push('referencedColumns'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     if (oldForeignKey.referencedTable !== foreignKey.referencedTable) { | 
					
						
							|  |  |  |       changes.push('referencedTable'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_.isNil(oldForeignKey.onDelete) || _.toUpper(oldForeignKey.onDelete) === 'NO ACTION') { | 
					
						
							|  |  |  |       if (!_.isNil(foreignKey.onDelete) && _.toUpper(oldForeignKey.onDelete) !== 'NO ACTION') { | 
					
						
							|  |  |  |         changes.push('onDelete'); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     } else if (_.toUpper(oldForeignKey.onDelete) !== _.toUpper(foreignKey.onDelete)) { | 
					
						
							|  |  |  |       changes.push('onDelete'); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     if (_.isNil(oldForeignKey.onUpdate) || _.toUpper(oldForeignKey.onUpdate) === 'NO ACTION') { | 
					
						
							|  |  |  |       if (!_.isNil(foreignKey.onUpdate) && _.toUpper(oldForeignKey.onUpdate) !== 'NO ACTION') { | 
					
						
							|  |  |  |         changes.push('onUpdate'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (_.toUpper(oldForeignKey.onUpdate) !== _.toUpper(foreignKey.onUpdate)) { | 
					
						
							|  |  |  |       changes.push('onUpdate'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |       status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |       diff: { | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |         name: foreignKey.name, | 
					
						
							|  |  |  |         object: foreignKey, | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const diffDefault = (oldColumn, column) => { | 
					
						
							|  |  |  |     const oldDefaultTo = oldColumn.defaultTo; | 
					
						
							|  |  |  |     const defaultTo = column.defaultTo; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     if (oldDefaultTo === null || _.toLower(oldDefaultTo) === 'null') { | 
					
						
							|  |  |  |       return _.isNil(defaultTo) || _.toLower(defaultTo) === 'null'; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |     return ( | 
					
						
							|  |  |  |       _.toLower(oldDefaultTo) === _.toLower(column.defaultTo) || | 
					
						
							|  |  |  |       _.toLower(oldDefaultTo) === _.toLower(`'${column.defaultTo}'`) | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Compares two columns info | 
					
						
							|  |  |  |    * @param {Object} oldColumn - column info read from DB | 
					
						
							|  |  |  |    * @param {Object} column - newly generate column info | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   const diffColumns = (oldColumn, column) => { | 
					
						
							|  |  |  |     const changes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 15:02:40 -07:00
										 |  |  |     const isIgnoredType = ['increments'].includes(column.type); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const oldType = oldColumn.type; | 
					
						
							|  |  |  |     const type = db.dialect.getSqlType(column.type); | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (oldType !== type && !isIgnoredType) { | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |       changes.push('type'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |     // NOTE: compare args at some point and split them into specific properties instead
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (oldColumn.notNullable !== column.notNullable) { | 
					
						
							|  |  |  |       changes.push('notNullable'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const hasSameDefault = diffDefault(oldColumn, column); | 
					
						
							|  |  |  |     if (!hasSameDefault) { | 
					
						
							|  |  |  |       changes.push('defaultTo'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (oldColumn.unsigned !== column.unsigned && db.dialect.supportsUnsigned()) { | 
					
						
							|  |  |  |       changes.push('unsigned'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     return { | 
					
						
							|  |  |  |       status: changes.length > 0 ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         name: column.name, | 
					
						
							|  |  |  |         object: column, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   const diffTableColumns = (srcTable, destTable) => { | 
					
						
							|  |  |  |     const addedColumns = []; | 
					
						
							|  |  |  |     const updatedColumns = []; | 
					
						
							|  |  |  |     const unchangedColumns = []; | 
					
						
							|  |  |  |     const removedColumns = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const destColumn of destTable.columns) { | 
					
						
							|  |  |  |       if (!helpers.hasColumn(srcTable, destColumn.name)) { | 
					
						
							|  |  |  |         addedColumns.push(destColumn); | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const srcColumn = helpers.findColumn(srcTable, destColumn.name); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |       const { status, diff } = diffColumns(srcColumn, destColumn); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (status === statuses.CHANGED) { | 
					
						
							|  |  |  |         updatedColumns.push(diff); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         unchangedColumns.push(srcColumn); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     for (const srcColumn of srcTable.columns) { | 
					
						
							|  |  |  |       if (!helpers.hasColumn(destTable, srcColumn.name)) { | 
					
						
							|  |  |  |         removedColumns.push(srcColumn); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const hasChanged = [addedColumns, updatedColumns, removedColumns].some(arr => arr.length > 0); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     return { | 
					
						
							|  |  |  |       status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         added: addedColumns, | 
					
						
							|  |  |  |         updated: updatedColumns, | 
					
						
							|  |  |  |         unchanged: unchangedColumns, | 
					
						
							|  |  |  |         removed: removedColumns, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   const diffTableIndexes = (srcTable, destTable) => { | 
					
						
							|  |  |  |     const addedIndexes = []; | 
					
						
							|  |  |  |     const updatedIndexes = []; | 
					
						
							|  |  |  |     const unchangedIndexes = []; | 
					
						
							|  |  |  |     const removedIndexes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const destIndex of destTable.indexes) { | 
					
						
							|  |  |  |       if (helpers.hasIndex(srcTable, destIndex.name)) { | 
					
						
							|  |  |  |         const srcIndex = helpers.findIndex(srcTable, destIndex.name); | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |         const { status, diff } = diffIndexes(srcIndex, destIndex); | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (status === statuses.CHANGED) { | 
					
						
							|  |  |  |           updatedIndexes.push(diff); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           unchangedIndexes.push(srcIndex); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         addedIndexes.push(destIndex); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     for (const srcIndex of srcTable.indexes) { | 
					
						
							|  |  |  |       if (!helpers.hasIndex(destTable, srcIndex.name)) { | 
					
						
							|  |  |  |         removedIndexes.push(srcIndex); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const hasChanged = [addedIndexes, updatedIndexes, removedIndexes].some(arr => arr.length > 0); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     return { | 
					
						
							|  |  |  |       status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         added: addedIndexes, | 
					
						
							|  |  |  |         updated: updatedIndexes, | 
					
						
							|  |  |  |         unchanged: unchangedIndexes, | 
					
						
							|  |  |  |         removed: removedIndexes, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   const diffTableForeignKeys = (srcTable, destTable) => { | 
					
						
							|  |  |  |     const addedForeignKeys = []; | 
					
						
							|  |  |  |     const updatedForeignKeys = []; | 
					
						
							|  |  |  |     const unchangedForeignKeys = []; | 
					
						
							|  |  |  |     const removedForeignKeys = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!db.dialect.usesForeignKeys()) { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         status: statuses.UNCHANGED, | 
					
						
							|  |  |  |         diff: { | 
					
						
							|  |  |  |           added: addedForeignKeys, | 
					
						
							|  |  |  |           updated: updatedForeignKeys, | 
					
						
							|  |  |  |           unchanged: unchangedForeignKeys, | 
					
						
							|  |  |  |           removed: removedForeignKeys, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const destForeignKey of destTable.foreignKeys) { | 
					
						
							|  |  |  |       if (helpers.hasForeignKey(srcTable, destForeignKey.name)) { | 
					
						
							|  |  |  |         const srcForeignKey = helpers.findForeignKey(srcTable, destForeignKey.name); | 
					
						
							| 
									
										
										
										
											2021-09-16 11:37:44 +02:00
										 |  |  |         const { status, diff } = diffForeignKeys(srcForeignKey, destForeignKey); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         if (status === statuses.CHANGED) { | 
					
						
							|  |  |  |           updatedForeignKeys.push(diff); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           unchangedForeignKeys.push(srcForeignKey); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         addedForeignKeys.push(destForeignKey); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     for (const srcForeignKey of srcTable.foreignKeys) { | 
					
						
							|  |  |  |       if (!helpers.hasForeignKey(destTable, srcForeignKey.name)) { | 
					
						
							|  |  |  |         removedForeignKeys.push(srcForeignKey); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const hasChanged = [addedForeignKeys, updatedForeignKeys, removedForeignKeys].some( | 
					
						
							|  |  |  |       arr => arr.length > 0 | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         added: addedForeignKeys, | 
					
						
							|  |  |  |         updated: updatedForeignKeys, | 
					
						
							|  |  |  |         unchanged: unchangedForeignKeys, | 
					
						
							|  |  |  |         removed: removedForeignKeys, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   const diffTables = (srcTable, destTable) => { | 
					
						
							|  |  |  |     const columnsDiff = diffTableColumns(srcTable, destTable); | 
					
						
							|  |  |  |     const indexesDiff = diffTableIndexes(srcTable, destTable); | 
					
						
							|  |  |  |     const foreignKeysDiff = diffTableForeignKeys(srcTable, destTable); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const hasChanged = [columnsDiff, indexesDiff, foreignKeysDiff].some(hasChangedStatus); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     return { | 
					
						
							|  |  |  |       status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         name: srcTable.name, | 
					
						
							|  |  |  |         indexes: indexesDiff.diff, | 
					
						
							|  |  |  |         foreignKeys: foreignKeysDiff.diff, | 
					
						
							|  |  |  |         columns: columnsDiff.diff, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   const diffSchemas = (srcSchema, destSchema) => { | 
					
						
							|  |  |  |     const addedTables = []; | 
					
						
							|  |  |  |     const updatedTables = []; | 
					
						
							|  |  |  |     const unchangedTables = []; | 
					
						
							|  |  |  |     const removedTables = []; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     for (const destTable of destSchema.tables) { | 
					
						
							|  |  |  |       if (helpers.hasTable(srcSchema, destTable.name)) { | 
					
						
							|  |  |  |         const srcTable = helpers.findTable(srcSchema, destTable.name); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         const { status, diff } = diffTables(srcTable, destTable); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         if (status === statuses.CHANGED) { | 
					
						
							|  |  |  |           updatedTables.push(diff); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           unchangedTables.push(srcTable); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         addedTables.push(destTable); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     for (const srcTable of srcSchema.tables) { | 
					
						
							| 
									
										
										
										
											2021-09-17 12:00:14 +02:00
										 |  |  |       if ( | 
					
						
							|  |  |  |         !helpers.hasTable(destSchema, srcTable.name) && | 
					
						
							|  |  |  |         !RESERVED_TABLE_NAMES.includes(srcTable.name) | 
					
						
							|  |  |  |       ) { | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |         removedTables.push(srcTable); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     const hasChanged = [addedTables, updatedTables, removedTables].some(arr => arr.length > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED, | 
					
						
							|  |  |  |       diff: { | 
					
						
							|  |  |  |         tables: { | 
					
						
							|  |  |  |           added: addedTables, | 
					
						
							|  |  |  |           updated: updatedTables, | 
					
						
							|  |  |  |           unchanged: unchangedTables, | 
					
						
							|  |  |  |           removed: removedTables, | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:25:09 +02:00
										 |  |  |   return { | 
					
						
							|  |  |  |     diff: diffSchemas, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | }; |