@contember/schema-migrations 2.1.0-alpha.2 → 2.1.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js +1 -1
- package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js +1 -1
- package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.cjs +5 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.js +5 -1
- package/dist/development/src/modifications/entities/RemoveEntityModification.js.map +1 -1
- package/dist/development/src/modifications/enums/UpdateEnumModification.cjs +36 -8
- package/dist/development/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
- package/dist/development/src/modifications/enums/UpdateEnumModification.js +34 -6
- package/dist/development/src/modifications/enums/UpdateEnumModification.js.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js +1 -1
- package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js +1 -1
- package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.cjs +5 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.js +5 -1
- package/dist/production/src/modifications/entities/RemoveEntityModification.js.map +1 -1
- package/dist/production/src/modifications/enums/UpdateEnumModification.cjs +36 -8
- package/dist/production/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
- package/dist/production/src/modifications/enums/UpdateEnumModification.js +34 -6
- package/dist/production/src/modifications/enums/UpdateEnumModification.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/modifications/columns/UpdateColumnDefinitionModification.d.ts.map +1 -1
- package/dist/types/modifications/entities/RemoveEntityModification.d.ts.map +1 -1
- package/dist/types/modifications/enums/UpdateEnumModification.d.ts +1 -0
- package/dist/types/modifications/enums/UpdateEnumModification.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/modifications/columns/UpdateColumnDefinitionModification.ts +3 -1
- package/src/modifications/constraints/CreateUniqueConstraintModification.ts +1 -1
- package/src/modifications/entities/RemoveEntityModification.ts +5 -1
- package/src/modifications/enums/UpdateEnumModification.ts +44 -7
- package/tests/cases/integration/createUnique.test.ts +1 -1
- package/tests/cases/integration/updateColumnDefinition.test.ts +28 -1
- package/tests/cases/integration/updateEnum.test.ts +43 -1
|
@@ -28,7 +28,7 @@ class UpdateColumnDefinitionModificationHandler {
|
|
|
28
28
|
const hasNewCollation = newColumn.collation !== oldColumn.collation;
|
|
29
29
|
const columnNameWrapped = dbHelpers.wrapIdentifier(oldColumn.columnName);
|
|
30
30
|
const isChangedToArray = !oldColumn.list && newColumn.list;
|
|
31
|
-
const usingCast =
|
|
31
|
+
const usingCast = isChangedToArray ? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? "NULL" : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END` : `${columnNameWrapped}::${columnType}`;
|
|
32
32
|
const seedExpression = columnUtils$1.formatSeedExpression({
|
|
33
33
|
model: this.schema.model,
|
|
34
34
|
entity,
|
package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateColumnDefinitionModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast = (isChangedToArray ? `ARRAY[${columnNameWrapped}]` : columnNameWrapped) + `::${columnType}`\n\n\t\tconst seedExpression = formatSeedExpression({\n\t\t\tmodel: this.schema.model,\n\t\t\tentity,\n\t\t\tcolumnType,\n\t\t\tfillValue: this.data.fillValue,\n\t\t\tcopyValue: this.data.copyValue,\n\t\t})\n\t\tconst hasSeed = seedExpression !== null\n\t\tconst migrateWithUsing = hasSeed && this.data.valueMigrationStrategy === 'using'\n\t\tconst migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'\n\n\t\tbuilder.alterColumn(entity.tableName, oldColumn.columnName, {\n\t\t\tcollation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,\n\t\t\ttype: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,\n\t\t\tnotNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,\n\t\t\tusing: (() => {\n\t\t\t\tif (hasNewSequence) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`\n\t\t\t\t}\n\t\t\t\tif (migrateWithUsing) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, ${seedExpression})`\n\t\t\t\t}\n\n\t\t\t\tif (hasNewType) {\n\t\t\t\t\treturn usingCast\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t})(),\n\t\t\tsequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),\n\t\t})\n\n\t\tif (migrateWithUpdate) {\n\t\t\tfillSeed({\n\t\t\t\tbuilder,\n\t\t\t\ttype: 'updating',\n\t\t\t\tentity,\n\t\t\t\tcolumnName: oldColumn.columnName,\n\t\t\t\tnullable: newColumn.nullable,\n\t\t\t\tseedExpression,\n\t\t\t})\n\t\t}\n\n\t\tconst seqAlter = []\n\t\tif (oldColumn.sequence && newColumn.sequence) {\n\t\t\tif (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {\n\t\t\t\tseqAlter.push(`SET GENERATED ${newColumn.sequence.precedence}`)\n\t\t\t}\n\t\t\tif (oldColumn.sequence.start !== newColumn.sequence.start && typeof newColumn.sequence.start == 'number') {\n\t\t\t\tseqAlter.push(`SET START WITH ${newColumn.sequence.start}`)\n\t\t\t}\n\t\t\tif (newColumn.sequence.restart) {\n\t\t\t\tseqAlter.push('RESTART')\n\t\t\t}\n\t\t}\n\t\tif (seqAlter.length > 0) {\n\t\t\tbuilder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} ALTER ${wrapIdentifier(oldColumn.columnName)} ${seqAlter.join(' ')}`)\n\t\t}\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(\n\t\t\t\tthis.data.entityName,\n\t\t\t\tupdateField<Model.AnyColumn>(this.data.fieldName, ({ field }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...this.data.definition,\n\t\t\t\t\t\tname: field.name,\n\t\t\t\t\t\tcolumnName: field.columnName,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst current = this.schema.model.entities[this.data.entityName].fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst changingToNotNull = current.nullable && !this.data.definition.nullable\n\t\tconst failureWarning = changingToNotNull ? 'Changing to not-null may fail in runtime.' : undefined\n\n\t\treturn {\n\t\t\tmessage: `Update column definition of field ${this.data.entityName}.${this.data.fieldName}`,\n\t\t\tfailureWarning,\n\t\t}\n\t}\n}\n\ntype SequenceDefinitionAlter =\n\t& Model.AnyColumn['sequence']\n\t& {\n\t\trestart?: boolean\n\t}\n\ntype ColumnDefinitionAlter =\n\t& Omit<Model.AnyColumn, 'sequence' | 'columnName' | 'name'>\n\t& {\n\t\tsequence?: SequenceDefinitionAlter\n\t}\n\nexport interface UpdateColumnDefinitionModificationData {\n\tentityName: string\n\tfieldName: string\n\tdefinition: ColumnDefinitionAlter\n\tfillValue?: JSONValue\n\tcopyValue?: string\n\tvalueMigrationStrategy?: 'using' | 'update'\n}\n\nexport const updateColumnDefinitionModification = createModificationType({\n\tid: 'updateColumnDefinition',\n\thandler: UpdateColumnDefinitionModificationHandler,\n})\n\nexport class UpdateColumnDefinitionDiffer implements Differ<UpdateColumnDefinitionModificationData> {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn updateColumns(originalSchema, updatedSchema, ({ originalColumn, updatedColumn, updatedEntity }) => {\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...updatedDefinition\n\t\t\t} = updatedColumn\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...originalDefinition\n\t\t\t} = originalColumn\n\t\t\tif (deepEqual(updatedDefinition, originalDefinition)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\n\t\t\treturn updateColumnDefinitionModification.createModification({\n\t\t\t\tentityName: updatedEntity.name,\n\t\t\t\tfieldName: updatedColumn.name,\n\t\t\t\tdefinition: updatedDefinition,\n\t\t\t})\n\t\t})\n\t}\n}\n"],"names":["getColumnSqlType","wrapIdentifier","formatSeedExpression","escapeValue","fillSeed","updateModel","updateEntity","updateField","createModificationType","updateColumns"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UpdateColumnDefinitionModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast = isChangedToArray\n\t\t\t? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? 'NULL' : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END`\n\t\t\t: `${columnNameWrapped}::${columnType}`\n\n\t\tconst seedExpression = formatSeedExpression({\n\t\t\tmodel: this.schema.model,\n\t\t\tentity,\n\t\t\tcolumnType,\n\t\t\tfillValue: this.data.fillValue,\n\t\t\tcopyValue: this.data.copyValue,\n\t\t})\n\t\tconst hasSeed = seedExpression !== null\n\t\tconst migrateWithUsing = hasSeed && this.data.valueMigrationStrategy === 'using'\n\t\tconst migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'\n\n\t\tbuilder.alterColumn(entity.tableName, oldColumn.columnName, {\n\t\t\tcollation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,\n\t\t\ttype: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,\n\t\t\tnotNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,\n\t\t\tusing: (() => {\n\t\t\t\tif (hasNewSequence) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`\n\t\t\t\t}\n\t\t\t\tif (migrateWithUsing) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, ${seedExpression})`\n\t\t\t\t}\n\n\t\t\t\tif (hasNewType) {\n\t\t\t\t\treturn usingCast\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t})(),\n\t\t\tsequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),\n\t\t})\n\n\t\tif (migrateWithUpdate) {\n\t\t\tfillSeed({\n\t\t\t\tbuilder,\n\t\t\t\ttype: 'updating',\n\t\t\t\tentity,\n\t\t\t\tcolumnName: oldColumn.columnName,\n\t\t\t\tnullable: newColumn.nullable,\n\t\t\t\tseedExpression,\n\t\t\t})\n\t\t}\n\n\t\tconst seqAlter = []\n\t\tif (oldColumn.sequence && newColumn.sequence) {\n\t\t\tif (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {\n\t\t\t\tseqAlter.push(`SET GENERATED ${newColumn.sequence.precedence}`)\n\t\t\t}\n\t\t\tif (oldColumn.sequence.start !== newColumn.sequence.start && typeof newColumn.sequence.start == 'number') {\n\t\t\t\tseqAlter.push(`SET START WITH ${newColumn.sequence.start}`)\n\t\t\t}\n\t\t\tif (newColumn.sequence.restart) {\n\t\t\t\tseqAlter.push('RESTART')\n\t\t\t}\n\t\t}\n\t\tif (seqAlter.length > 0) {\n\t\t\tbuilder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} ALTER ${wrapIdentifier(oldColumn.columnName)} ${seqAlter.join(' ')}`)\n\t\t}\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(\n\t\t\t\tthis.data.entityName,\n\t\t\t\tupdateField<Model.AnyColumn>(this.data.fieldName, ({ field }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...this.data.definition,\n\t\t\t\t\t\tname: field.name,\n\t\t\t\t\t\tcolumnName: field.columnName,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst current = this.schema.model.entities[this.data.entityName].fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst changingToNotNull = current.nullable && !this.data.definition.nullable\n\t\tconst failureWarning = changingToNotNull ? 'Changing to not-null may fail in runtime.' : undefined\n\n\t\treturn {\n\t\t\tmessage: `Update column definition of field ${this.data.entityName}.${this.data.fieldName}`,\n\t\t\tfailureWarning,\n\t\t}\n\t}\n}\n\ntype SequenceDefinitionAlter =\n\t& Model.AnyColumn['sequence']\n\t& {\n\t\trestart?: boolean\n\t}\n\ntype ColumnDefinitionAlter =\n\t& Omit<Model.AnyColumn, 'sequence' | 'columnName' | 'name'>\n\t& {\n\t\tsequence?: SequenceDefinitionAlter\n\t}\n\nexport interface UpdateColumnDefinitionModificationData {\n\tentityName: string\n\tfieldName: string\n\tdefinition: ColumnDefinitionAlter\n\tfillValue?: JSONValue\n\tcopyValue?: string\n\tvalueMigrationStrategy?: 'using' | 'update'\n}\n\nexport const updateColumnDefinitionModification = createModificationType({\n\tid: 'updateColumnDefinition',\n\thandler: UpdateColumnDefinitionModificationHandler,\n})\n\nexport class UpdateColumnDefinitionDiffer implements Differ<UpdateColumnDefinitionModificationData> {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn updateColumns(originalSchema, updatedSchema, ({ originalColumn, updatedColumn, updatedEntity }) => {\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...updatedDefinition\n\t\t\t} = updatedColumn\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...originalDefinition\n\t\t\t} = originalColumn\n\t\t\tif (deepEqual(updatedDefinition, originalDefinition)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\n\t\t\treturn updateColumnDefinitionModification.createModification({\n\t\t\t\tentityName: updatedEntity.name,\n\t\t\t\tfieldName: updatedColumn.name,\n\t\t\t\tdefinition: updatedDefinition,\n\t\t\t})\n\t\t})\n\t}\n}\n"],"names":["getColumnSqlType","wrapIdentifier","formatSeedExpression","escapeValue","fillSeed","updateModel","updateEntity","updateField","createModificationType","updateColumns"],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ class UpdateColumnDefinitionModificationHandler {
|
|
|
26
26
|
const hasNewCollation = newColumn.collation !== oldColumn.collation;
|
|
27
27
|
const columnNameWrapped = wrapIdentifier(oldColumn.columnName);
|
|
28
28
|
const isChangedToArray = !oldColumn.list && newColumn.list;
|
|
29
|
-
const usingCast =
|
|
29
|
+
const usingCast = isChangedToArray ? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? "NULL" : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END` : `${columnNameWrapped}::${columnType}`;
|
|
30
30
|
const seedExpression = formatSeedExpression({
|
|
31
31
|
model: this.schema.model,
|
|
32
32
|
entity,
|
package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateColumnDefinitionModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast =
|
|
1
|
+
{"version":3,"file":"UpdateColumnDefinitionModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast = isChangedToArray\n\t\t\t? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? 'NULL' : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END`\n\t\t\t: `${columnNameWrapped}::${columnType}`\n\n\t\tconst seedExpression = formatSeedExpression({\n\t\t\tmodel: this.schema.model,\n\t\t\tentity,\n\t\t\tcolumnType,\n\t\t\tfillValue: this.data.fillValue,\n\t\t\tcopyValue: this.data.copyValue,\n\t\t})\n\t\tconst hasSeed = seedExpression !== null\n\t\tconst migrateWithUsing = hasSeed && this.data.valueMigrationStrategy === 'using'\n\t\tconst migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'\n\n\t\tbuilder.alterColumn(entity.tableName, oldColumn.columnName, {\n\t\t\tcollation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,\n\t\t\ttype: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,\n\t\t\tnotNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,\n\t\t\tusing: (() => {\n\t\t\t\tif (hasNewSequence) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`\n\t\t\t\t}\n\t\t\t\tif (migrateWithUsing) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, ${seedExpression})`\n\t\t\t\t}\n\n\t\t\t\tif (hasNewType) {\n\t\t\t\t\treturn usingCast\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t})(),\n\t\t\tsequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),\n\t\t})\n\n\t\tif (migrateWithUpdate) {\n\t\t\tfillSeed({\n\t\t\t\tbuilder,\n\t\t\t\ttype: 'updating',\n\t\t\t\tentity,\n\t\t\t\tcolumnName: oldColumn.columnName,\n\t\t\t\tnullable: newColumn.nullable,\n\t\t\t\tseedExpression,\n\t\t\t})\n\t\t}\n\n\t\tconst seqAlter = []\n\t\tif (oldColumn.sequence && newColumn.sequence) {\n\t\t\tif (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {\n\t\t\t\tseqAlter.push(`SET GENERATED ${newColumn.sequence.precedence}`)\n\t\t\t}\n\t\t\tif (oldColumn.sequence.start !== newColumn.sequence.start && typeof newColumn.sequence.start == 'number') {\n\t\t\t\tseqAlter.push(`SET START WITH ${newColumn.sequence.start}`)\n\t\t\t}\n\t\t\tif (newColumn.sequence.restart) {\n\t\t\t\tseqAlter.push('RESTART')\n\t\t\t}\n\t\t}\n\t\tif (seqAlter.length > 0) {\n\t\t\tbuilder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} ALTER ${wrapIdentifier(oldColumn.columnName)} ${seqAlter.join(' ')}`)\n\t\t}\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(\n\t\t\t\tthis.data.entityName,\n\t\t\t\tupdateField<Model.AnyColumn>(this.data.fieldName, ({ field }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...this.data.definition,\n\t\t\t\t\t\tname: field.name,\n\t\t\t\t\t\tcolumnName: field.columnName,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst current = this.schema.model.entities[this.data.entityName].fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst changingToNotNull = current.nullable && !this.data.definition.nullable\n\t\tconst failureWarning = changingToNotNull ? 'Changing to not-null may fail in runtime.' : undefined\n\n\t\treturn {\n\t\t\tmessage: `Update column definition of field ${this.data.entityName}.${this.data.fieldName}`,\n\t\t\tfailureWarning,\n\t\t}\n\t}\n}\n\ntype SequenceDefinitionAlter =\n\t& Model.AnyColumn['sequence']\n\t& {\n\t\trestart?: boolean\n\t}\n\ntype ColumnDefinitionAlter =\n\t& Omit<Model.AnyColumn, 'sequence' | 'columnName' | 'name'>\n\t& {\n\t\tsequence?: SequenceDefinitionAlter\n\t}\n\nexport interface UpdateColumnDefinitionModificationData {\n\tentityName: string\n\tfieldName: string\n\tdefinition: ColumnDefinitionAlter\n\tfillValue?: JSONValue\n\tcopyValue?: string\n\tvalueMigrationStrategy?: 'using' | 'update'\n}\n\nexport const updateColumnDefinitionModification = createModificationType({\n\tid: 'updateColumnDefinition',\n\thandler: UpdateColumnDefinitionModificationHandler,\n})\n\nexport class UpdateColumnDefinitionDiffer implements Differ<UpdateColumnDefinitionModificationData> {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn updateColumns(originalSchema, updatedSchema, ({ originalColumn, updatedColumn, updatedEntity }) => {\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...updatedDefinition\n\t\t\t} = updatedColumn\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...originalDefinition\n\t\t\t} = originalColumn\n\t\t\tif (deepEqual(updatedDefinition, originalDefinition)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\n\t\t\treturn updateColumnDefinitionModification.createModification({\n\t\t\t\tentityName: updatedEntity.name,\n\t\t\t\tfieldName: updatedColumn.name,\n\t\t\t\tdefinition: updatedDefinition,\n\t\t\t})\n\t\t})\n\t}\n}\n"],"names":[],"mappings":"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"}
|
package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs
CHANGED
|
@@ -25,7 +25,7 @@ class CreateUniqueConstraintModificationHandler {
|
|
|
25
25
|
const tableNameId = dbHelpers.wrapIdentifier(entity.tableName);
|
|
26
26
|
const columnNameIds = columns.map(dbHelpers.wrapIdentifier);
|
|
27
27
|
if ("index" in this.data.unique && this.data.unique.index) {
|
|
28
|
-
const nulls = this.data.unique.nulls === "not distinct" ? " NULLS NOT DISTINCT" : "
|
|
28
|
+
const nulls = this.data.unique.nulls === "not distinct" ? " NULLS NOT DISTINCT" : "";
|
|
29
29
|
builder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(", ")})${nulls}`);
|
|
30
30
|
} else {
|
|
31
31
|
let checkModifier = "";
|
package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateUniqueConstraintModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/constraints/CreateUniqueConstraintModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler,\n\tModificationHandlerCreateSqlOptions,\n} from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getUniqueConstraintColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateUniqueConstraintModificationHandler implements ModificationHandler<CreateUniqueConstraintModificationData> {\n\tconstructor(private readonly data: CreateUniqueConstraintModificationData, private readonly schema: Schema) {\n\t}\n\n\tpublic createSql(builder: MigrationBuilder, { invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst shouldExecuteSql =\n\t\t\t!entity.view\n\t\t\t|| (this.data.unique.index && entity.view.materialized)\n\t\tif (!shouldExecuteSql) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.unique.fields\n\t\tconst columns = getUniqueConstraintColumns({\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t\tfields,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\n\t\tif ('index' in this.data.unique && this.data.unique.index) {\n\t\t\tconst nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : '
|
|
1
|
+
{"version":3,"file":"CreateUniqueConstraintModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/constraints/CreateUniqueConstraintModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler,\n\tModificationHandlerCreateSqlOptions,\n} from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getUniqueConstraintColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateUniqueConstraintModificationHandler implements ModificationHandler<CreateUniqueConstraintModificationData> {\n\tconstructor(private readonly data: CreateUniqueConstraintModificationData, private readonly schema: Schema) {\n\t}\n\n\tpublic createSql(builder: MigrationBuilder, { invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst shouldExecuteSql =\n\t\t\t!entity.view\n\t\t\t|| (this.data.unique.index && entity.view.materialized)\n\t\tif (!shouldExecuteSql) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.unique.fields\n\t\tconst columns = getUniqueConstraintColumns({\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t\tfields,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\n\t\tif ('index' in this.data.unique && this.data.unique.index) {\n\t\t\tconst nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : ''\n\t\t\tbuilder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(', ')})${nulls}`)\n\t\t} else {\n\t\t\tlet checkModifier = ''\n\t\t\tif (this.data.unique.timing === 'deferred') {\n\t\t\t\tcheckModifier = ' INITIALLY DEFERRED'\n\t\t\t} else if (this.data.unique.timing === 'deferrable') {\n\t\t\t\tcheckModifier = ' DEFERRABLE'\n\t\t\t}\n\n\t\t\tbuilder.sql(`ALTER TABLE ${tableNameId} ADD UNIQUE (${columnNameIds.join(', ')})${checkModifier}`)\n\t\t}\n\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tunique: [\n\t\t\t\t\t...entity.unique,\n\t\t\t\t\tthis.data.unique,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe({ createdEntities }: { createdEntities: string[] }) {\n\t\treturn {\n\t\t\tmessage: `Create unique ${this.data.unique.index ? 'index' : 'constraint'} (${this.data.unique.fields.join(', ')}) on entity ${this.data.entityName}`,\n\t\t\tfailureWarning: !createdEntities.includes(this.data.entityName)\n\t\t\t\t? 'Make sure no conflicting rows exists, otherwise this may fail in runtime.'\n\t\t\t\t: undefined,\n\t\t}\n\t}\n\n}\n\nexport const createUniqueConstraintModification = createModificationType({\n\tid: 'createUniqueConstraint',\n\thandler: CreateUniqueConstraintModificationHandler,\n})\n\nexport interface CreateUniqueConstraintModificationData {\n\tentityName: string\n\tunique: Model.UniqueConstraint | Model.UniqueIndex\n}\n\nexport class CreateUniqueConstraintDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.unique\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].unique.find(uniq => deepEqual(uniq.fields, it.fields)))\n\t\t\t\t.map(unique => createUniqueConstraintModification.createModification({\n\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\tunique,\n\t\t\t\t})),\n\t\t)\n\t}\n}\n"],"names":["getUniqueConstraintColumns","wrapIdentifier","updateModel","updateEntity","createModificationType"],"mappings":";;;;;;;AAaO,MAAM,0CAAiH;AAAA,EAC7H,YAA6B,MAA+D,QAAgB;AAA/E,SAAA,OAAA;AAA+D,SAAA,SAAA;AAAA,EAAA;AAAA,EAGrF,UAAU,SAA2B,EAAE,8BAAyE;AACtH,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AACxD,UAAA,mBACL,CAAC,OAAO,QACJ,KAAK,KAAK,OAAO,SAAS,OAAO,KAAK;AAC3C,QAAI,CAAC,kBAAkB;AACtB;AAAA,IAAA;AAEK,UAAA,SAAS,KAAK,KAAK,OAAO;AAChC,UAAM,UAAUA,MAAAA,2BAA2B;AAAA,MAC1C;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,MACnB;AAAA,IAAA,CACA;AAEK,UAAA,cAAcC,UAAAA,eAAe,OAAO,SAAS;AAC7C,UAAA,gBAAgB,QAAQ,IAAIA,wBAAc;AAEhD,QAAI,WAAW,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,OAAO;AAC1D,YAAM,QAAQ,KAAK,KAAK,OAAO,UAAU,iBAAiB,wBAAwB;AAC1E,cAAA,IAAI,0BAA0B,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC,IAAI,KAAK,EAAE;AAAA,IAAA,OACnF;AACN,UAAI,gBAAgB;AACpB,UAAI,KAAK,KAAK,OAAO,WAAW,YAAY;AAC3B,wBAAA;AAAA,MACN,WAAA,KAAK,KAAK,OAAO,WAAW,cAAc;AACpC,wBAAA;AAAA,MAAA;AAGT,cAAA,IAAI,eAAe,WAAW,gBAAgB,cAAc,KAAK,IAAI,CAAC,IAAI,aAAa,EAAE;AAAA,IAAA;AAIvE,+BAAA;AAAA,EAAA;AAAA,EAGrB,mBAAkC;AACjC,WAAAC,kBAAA;AAAA,MACNC,+BAAa,KAAK,KAAK,YAAY,CAAC,EAAE,cAAc;AAAA,QACnD,GAAG;AAAA,QACH,QAAQ;AAAA,UACP,GAAG,OAAO;AAAA,UACV,KAAK,KAAK;AAAA,QAAA;AAAA,MACX,EACC;AAAA,IACH;AAAA,EAAA;AAAA,EAGD,SAAS,EAAE,mBAAkD;AACrD,WAAA;AAAA,MACN,SAAS,iBAAiB,KAAK,KAAK,OAAO,QAAQ,UAAU,YAAY,KAAK,KAAK,KAAK,OAAO,OAAO,KAAK,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU;AAAA,MACnJ,gBAAgB,CAAC,gBAAgB,SAAS,KAAK,KAAK,UAAU,IAC3D,8EACA;AAAA,IACJ;AAAA,EAAA;AAGF;AAEO,MAAM,qCAAqCC,oBAAAA,uBAAuB;AAAA,EACxE,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAOM,MAAM,6BAA+C;AAAA,EAC3D,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,cAAc,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC1D,OAAO,OACL,OAAO,CAAA,OAAM,CAAC,eAAe,MAAM,SAAS,OAAO,IAAI,EAAE,OAAO,KAAK,CAAQ,SAAA,UAAU,KAAK,QAAQ,GAAG,MAAM,CAAC,CAAC,EAC/G,IAAI,CAAU,WAAA,mCAAmC,mBAAmB;AAAA,QACpE,YAAY,OAAO;AAAA,QACnB;AAAA,MAAA,CACA,CAAC;AAAA,IACJ;AAAA,EAAA;AAEF;;;;"}
|
package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js
CHANGED
|
@@ -23,7 +23,7 @@ class CreateUniqueConstraintModificationHandler {
|
|
|
23
23
|
const tableNameId = wrapIdentifier(entity.tableName);
|
|
24
24
|
const columnNameIds = columns.map(wrapIdentifier);
|
|
25
25
|
if ("index" in this.data.unique && this.data.unique.index) {
|
|
26
|
-
const nulls = this.data.unique.nulls === "not distinct" ? " NULLS NOT DISTINCT" : "
|
|
26
|
+
const nulls = this.data.unique.nulls === "not distinct" ? " NULLS NOT DISTINCT" : "";
|
|
27
27
|
builder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(", ")})${nulls}`);
|
|
28
28
|
} else {
|
|
29
29
|
let checkModifier = "";
|
package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateUniqueConstraintModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/constraints/CreateUniqueConstraintModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler,\n\tModificationHandlerCreateSqlOptions,\n} from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getUniqueConstraintColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateUniqueConstraintModificationHandler implements ModificationHandler<CreateUniqueConstraintModificationData> {\n\tconstructor(private readonly data: CreateUniqueConstraintModificationData, private readonly schema: Schema) {\n\t}\n\n\tpublic createSql(builder: MigrationBuilder, { invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst shouldExecuteSql =\n\t\t\t!entity.view\n\t\t\t|| (this.data.unique.index && entity.view.materialized)\n\t\tif (!shouldExecuteSql) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.unique.fields\n\t\tconst columns = getUniqueConstraintColumns({\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t\tfields,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\n\t\tif ('index' in this.data.unique && this.data.unique.index) {\n\t\t\tconst nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : '
|
|
1
|
+
{"version":3,"file":"CreateUniqueConstraintModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/constraints/CreateUniqueConstraintModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler,\n\tModificationHandlerCreateSqlOptions,\n} from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getUniqueConstraintColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateUniqueConstraintModificationHandler implements ModificationHandler<CreateUniqueConstraintModificationData> {\n\tconstructor(private readonly data: CreateUniqueConstraintModificationData, private readonly schema: Schema) {\n\t}\n\n\tpublic createSql(builder: MigrationBuilder, { invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst shouldExecuteSql =\n\t\t\t!entity.view\n\t\t\t|| (this.data.unique.index && entity.view.materialized)\n\t\tif (!shouldExecuteSql) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.unique.fields\n\t\tconst columns = getUniqueConstraintColumns({\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t\tfields,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\n\t\tif ('index' in this.data.unique && this.data.unique.index) {\n\t\t\tconst nulls = this.data.unique.nulls === 'not distinct' ? ' NULLS NOT DISTINCT' : ''\n\t\t\tbuilder.sql(`CREATE UNIQUE INDEX ON ${tableNameId} (${columnNameIds.join(', ')})${nulls}`)\n\t\t} else {\n\t\t\tlet checkModifier = ''\n\t\t\tif (this.data.unique.timing === 'deferred') {\n\t\t\t\tcheckModifier = ' INITIALLY DEFERRED'\n\t\t\t} else if (this.data.unique.timing === 'deferrable') {\n\t\t\t\tcheckModifier = ' DEFERRABLE'\n\t\t\t}\n\n\t\t\tbuilder.sql(`ALTER TABLE ${tableNameId} ADD UNIQUE (${columnNameIds.join(', ')})${checkModifier}`)\n\t\t}\n\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tunique: [\n\t\t\t\t\t...entity.unique,\n\t\t\t\t\tthis.data.unique,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe({ createdEntities }: { createdEntities: string[] }) {\n\t\treturn {\n\t\t\tmessage: `Create unique ${this.data.unique.index ? 'index' : 'constraint'} (${this.data.unique.fields.join(', ')}) on entity ${this.data.entityName}`,\n\t\t\tfailureWarning: !createdEntities.includes(this.data.entityName)\n\t\t\t\t? 'Make sure no conflicting rows exists, otherwise this may fail in runtime.'\n\t\t\t\t: undefined,\n\t\t}\n\t}\n\n}\n\nexport const createUniqueConstraintModification = createModificationType({\n\tid: 'createUniqueConstraint',\n\thandler: CreateUniqueConstraintModificationHandler,\n})\n\nexport interface CreateUniqueConstraintModificationData {\n\tentityName: string\n\tunique: Model.UniqueConstraint | Model.UniqueIndex\n}\n\nexport class CreateUniqueConstraintDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.unique\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].unique.find(uniq => deepEqual(uniq.fields, it.fields)))\n\t\t\t\t.map(unique => createUniqueConstraintModification.createModification({\n\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\tunique,\n\t\t\t\t})),\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAaO,MAAM,0CAAiH;AAAA,EAC7H,YAA6B,MAA+D,QAAgB;AAA/E,SAAA,OAAA;AAA+D,SAAA,SAAA;AAAA,EAAA;AAAA,EAGrF,UAAU,SAA2B,EAAE,8BAAyE;AACtH,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AACxD,UAAA,mBACL,CAAC,OAAO,QACJ,KAAK,KAAK,OAAO,SAAS,OAAO,KAAK;AAC3C,QAAI,CAAC,kBAAkB;AACtB;AAAA,IAAA;AAEK,UAAA,SAAS,KAAK,KAAK,OAAO;AAChC,UAAM,UAAU,2BAA2B;AAAA,MAC1C;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,MACnB;AAAA,IAAA,CACA;AAEK,UAAA,cAAc,eAAe,OAAO,SAAS;AAC7C,UAAA,gBAAgB,QAAQ,IAAI,cAAc;AAEhD,QAAI,WAAW,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,OAAO;AAC1D,YAAM,QAAQ,KAAK,KAAK,OAAO,UAAU,iBAAiB,wBAAwB;AAC1E,cAAA,IAAI,0BAA0B,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC,IAAI,KAAK,EAAE;AAAA,IAAA,OACnF;AACN,UAAI,gBAAgB;AACpB,UAAI,KAAK,KAAK,OAAO,WAAW,YAAY;AAC3B,wBAAA;AAAA,MACN,WAAA,KAAK,KAAK,OAAO,WAAW,cAAc;AACpC,wBAAA;AAAA,MAAA;AAGT,cAAA,IAAI,eAAe,WAAW,gBAAgB,cAAc,KAAK,IAAI,CAAC,IAAI,aAAa,EAAE;AAAA,IAAA;AAIvE,+BAAA;AAAA,EAAA;AAAA,EAGrB,mBAAkC;AACjC,WAAA;AAAA,MACN,aAAa,KAAK,KAAK,YAAY,CAAC,EAAE,cAAc;AAAA,QACnD,GAAG;AAAA,QACH,QAAQ;AAAA,UACP,GAAG,OAAO;AAAA,UACV,KAAK,KAAK;AAAA,QAAA;AAAA,MACX,EACC;AAAA,IACH;AAAA,EAAA;AAAA,EAGD,SAAS,EAAE,mBAAkD;AACrD,WAAA;AAAA,MACN,SAAS,iBAAiB,KAAK,KAAK,OAAO,QAAQ,UAAU,YAAY,KAAK,KAAK,KAAK,OAAO,OAAO,KAAK,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU;AAAA,MACnJ,gBAAgB,CAAC,gBAAgB,SAAS,KAAK,KAAK,UAAU,IAC3D,8EACA;AAAA,IACJ;AAAA,EAAA;AAGF;AAEO,MAAM,qCAAqC,uBAAuB;AAAA,EACxE,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAOM,MAAM,6BAA+C;AAAA,EAC3D,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,cAAc,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC1D,OAAO,OACL,OAAO,CAAA,OAAM,CAAC,eAAe,MAAM,SAAS,OAAO,IAAI,EAAE,OAAO,KAAK,CAAQ,SAAA,UAAU,KAAK,QAAQ,GAAG,MAAM,CAAC,CAAC,EAC/G,IAAI,CAAU,WAAA,mCAAmC,mBAAmB;AAAA,QACpE,YAAY,OAAO;AAAA,QACnB;AAAA,MAAA,CACA,CAAC;AAAA,IACJ;AAAA,EAAA;AAEF;"}
|
|
@@ -17,7 +17,11 @@ class RemoveEntityModificationHandler {
|
|
|
17
17
|
createSql(builder, options) {
|
|
18
18
|
const entity = this.schema.model.entities[this.data.entityName];
|
|
19
19
|
if (entity.view) {
|
|
20
|
-
|
|
20
|
+
if (entity.view.materialized) {
|
|
21
|
+
builder.dropMaterializedView(entity.tableName);
|
|
22
|
+
} else {
|
|
23
|
+
builder.dropView(entity.tableName);
|
|
24
|
+
}
|
|
21
25
|
return;
|
|
22
26
|
}
|
|
23
27
|
if (this.options.formatVersion >= ModificationVersions.VERSION_REMOVE_REFERENCING_RELATIONS) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoveEntityModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/entities/RemoveEntityModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Acl, Model, Schema } from '@contember/schema'\nimport {\n\tremoveField,\n\tSchemaUpdater,\n\tupdateAcl,\n\tupdateAclEntities,\n\tupdateAclEveryEntity,\n\tupdateAclEveryPredicate,\n\tupdateAclEveryRole,\n\tupdateModel,\n\tupdateSchema,\n} from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler, ModificationHandlerCreateSqlOptions,\n\tModificationHandlerOptions,\n} from '../ModificationHandler'\nimport { VERSION_ACL_PATCH, VERSION_REMOVE_REFERENCING_RELATIONS } from '../ModificationVersions'\nimport { acceptEveryFieldVisitor, isInverseRelation, isRelation, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { removeFieldModification } from '../fields'\n\nexport class RemoveEntityModificationHandler implements ModificationHandler<RemoveEntityModificationData> {\n\tconstructor(\n\t\tprivate readonly data: RemoveEntityModificationData,\n\t\tprivate readonly schema: Schema,\n\t\tprivate readonly options: ModificationHandlerOptions,\n\t) {}\n\n\tpublic createSql(builder: MigrationBuilder, options: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\tbuilder.dropView(entity.tableName)\n\t\t\treturn\n\t\t}\n\t\tif (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {\n\t\t\tthis.getFieldsToRemove(this.schema).forEach(([entityName, fieldName]) => {\n\t\t\t\tconst removeFieldHandler = removeFieldModification.createHandler({ entityName, fieldName }, this.schema, this.options)\n\t\t\t\tremoveFieldHandler.createSql(builder, options)\n\t\t\t})\n\t\t}\n\t\tacceptEveryFieldVisitor(this.schema.model, entity, {\n\t\t\tvisitManyHasManyOwning: ({ relation }) => {\n\t\t\t\tbuilder.dropTable(relation.joiningTable.tableName)\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitColumn: () => {},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\tvisitManyHasOne: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t})\n\t\tbuilder.dropTable(entity.tableName)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateSchema(\n\t\t\tthis.options.formatVersion >= VERSION_ACL_PATCH\n\t\t\t\t? updateAcl(\n\t\t\t\t\tupdateAclEveryRole(\n\t\t\t\t\t\t({ role }) => ({\n\t\t\t\t\t\t\t...role,\n\t\t\t\t\t\t\tvariables: Object.fromEntries(\n\t\t\t\t\t\t\t\tObject.entries(role.variables).filter(([, variable]) =>\n\t\t\t\t\t\t\t\t\tvariable.type !== Acl.VariableType.entity || variable.entityName !== this.data.entityName,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEntities(({ entities }) => {\n\t\t\t\t\t\t\tconst { [this.data.entityName]: removed, ...other } = entities\n\t\t\t\t\t\t\treturn other\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEveryEntity(\n\t\t\t\t\t\t\tupdateAclEveryPredicate(({ predicate, entityName, schema }) => {\n\t\t\t\t\t\t\t\tconst processor = new PredicateDefinitionProcessor(schema.model)\n\t\t\t\t\t\t\t\tconst currentEntity = schema.model.entities[entityName]\n\t\t\t\t\t\t\t\treturn processor.process(currentEntity, predicate, {\n\t\t\t\t\t\t\t\t\thandleColumn: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\thandleRelation: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t\tthis.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS\n\t\t\t\t? ({ schema }) => {\n\t\t\t\t\tconst fieldsToRemove = this.getFieldsToRemove(schema)\n\t\t\t\t\treturn fieldsToRemove.reduce(\n\t\t\t\t\t\t(schema, [entity, field]) => removeField(entity, field, this.options.formatVersion)({ schema }),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t)\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t\tupdateModel(({ model }) => {\n\t\t\t\tconst { [this.data.entityName]: removed, ...entities } = model.entities\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tentities: { ...entities },\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate getFieldsToRemove(schema: Schema): [entity: string, field: string][] {\n\t\treturn Object.values(schema.model.entities).flatMap(entity =>\n\t\t\tObject.values(entity.fields)\n\t\t\t\t.filter((field): field is Model.AnyRelation => isRelation(field) && field.target === this.data.entityName)\n\t\t\t\t.filter(field => !isInverseRelation(field) || entity.name !== this.data.entityName) // skip self-referencing inverse relations\n\t\t\t\t.map((field): [string, string] => [entity.name, field.name]),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\treturn { message: `Remove entity ${this.data.entityName}`, isDestructive: true }\n\t}\n\n}\n\nexport interface RemoveEntityModificationData {\n\tentityName: string\n}\n\nexport const removeEntityModification = createModificationType({\n\tid: 'removeEntity',\n\thandler: RemoveEntityModificationHandler,\n})\n\nexport class RemoveEntityDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.keys(originalSchema.model.entities)\n\t\t\t.filter(name => !updatedSchema.model.entities[name])\n\t\t\t.map(entityName => removeEntityModification.createModification({ entityName }))\n\t}\n}\n"],"names":["schema","VERSION_REMOVE_REFERENCING_RELATIONS","removeFieldModification","acceptEveryFieldVisitor","updateSchema","VERSION_ACL_PATCH","updateAcl","updateAclEveryRole","Acl","updateAclEntities","updateAclEveryEntity","updateAclEveryPredicate","PredicateDefinitionProcessor","removeField","updateModel","isRelation","isInverseRelation","createModificationType"],"mappings":";;;;;;;;;;AAuBO,MAAM,gCAA6F;AAAA,EACzG,YACkB,MACAA,SACA,SAChB;AAHgB,SAAA,OAAA;AACA,SAAA,SAAAA;AACA,SAAA,UAAA;AAAA,EAAA;AAAA,EAGX,UAAU,SAA2B,SAAoD;AAC/F,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,MAAM;
|
|
1
|
+
{"version":3,"file":"RemoveEntityModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/entities/RemoveEntityModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Acl, Model, Schema } from '@contember/schema'\nimport {\n\tremoveField,\n\tSchemaUpdater,\n\tupdateAcl,\n\tupdateAclEntities,\n\tupdateAclEveryEntity,\n\tupdateAclEveryPredicate,\n\tupdateAclEveryRole,\n\tupdateModel,\n\tupdateSchema,\n} from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler, ModificationHandlerCreateSqlOptions,\n\tModificationHandlerOptions,\n} from '../ModificationHandler'\nimport { VERSION_ACL_PATCH, VERSION_REMOVE_REFERENCING_RELATIONS } from '../ModificationVersions'\nimport { acceptEveryFieldVisitor, isInverseRelation, isRelation, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { removeFieldModification } from '../fields'\n\nexport class RemoveEntityModificationHandler implements ModificationHandler<RemoveEntityModificationData> {\n\tconstructor(\n\t\tprivate readonly data: RemoveEntityModificationData,\n\t\tprivate readonly schema: Schema,\n\t\tprivate readonly options: ModificationHandlerOptions,\n\t) {}\n\n\tpublic createSql(builder: MigrationBuilder, options: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\tif (entity.view.materialized) {\n\t\t\t\tbuilder.dropMaterializedView(entity.tableName)\n\t\t\t} else {\n\t\t\t\tbuilder.dropView(entity.tableName)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {\n\t\t\tthis.getFieldsToRemove(this.schema).forEach(([entityName, fieldName]) => {\n\t\t\t\tconst removeFieldHandler = removeFieldModification.createHandler({ entityName, fieldName }, this.schema, this.options)\n\t\t\t\tremoveFieldHandler.createSql(builder, options)\n\t\t\t})\n\t\t}\n\t\tacceptEveryFieldVisitor(this.schema.model, entity, {\n\t\t\tvisitManyHasManyOwning: ({ relation }) => {\n\t\t\t\tbuilder.dropTable(relation.joiningTable.tableName)\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitColumn: () => {},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\tvisitManyHasOne: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t})\n\t\tbuilder.dropTable(entity.tableName)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateSchema(\n\t\t\tthis.options.formatVersion >= VERSION_ACL_PATCH\n\t\t\t\t? updateAcl(\n\t\t\t\t\tupdateAclEveryRole(\n\t\t\t\t\t\t({ role }) => ({\n\t\t\t\t\t\t\t...role,\n\t\t\t\t\t\t\tvariables: Object.fromEntries(\n\t\t\t\t\t\t\t\tObject.entries(role.variables).filter(([, variable]) =>\n\t\t\t\t\t\t\t\t\tvariable.type !== Acl.VariableType.entity || variable.entityName !== this.data.entityName,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEntities(({ entities }) => {\n\t\t\t\t\t\t\tconst { [this.data.entityName]: removed, ...other } = entities\n\t\t\t\t\t\t\treturn other\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEveryEntity(\n\t\t\t\t\t\t\tupdateAclEveryPredicate(({ predicate, entityName, schema }) => {\n\t\t\t\t\t\t\t\tconst processor = new PredicateDefinitionProcessor(schema.model)\n\t\t\t\t\t\t\t\tconst currentEntity = schema.model.entities[entityName]\n\t\t\t\t\t\t\t\treturn processor.process(currentEntity, predicate, {\n\t\t\t\t\t\t\t\t\thandleColumn: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\thandleRelation: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t\tthis.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS\n\t\t\t\t? ({ schema }) => {\n\t\t\t\t\tconst fieldsToRemove = this.getFieldsToRemove(schema)\n\t\t\t\t\treturn fieldsToRemove.reduce(\n\t\t\t\t\t\t(schema, [entity, field]) => removeField(entity, field, this.options.formatVersion)({ schema }),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t)\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t\tupdateModel(({ model }) => {\n\t\t\t\tconst { [this.data.entityName]: removed, ...entities } = model.entities\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tentities: { ...entities },\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate getFieldsToRemove(schema: Schema): [entity: string, field: string][] {\n\t\treturn Object.values(schema.model.entities).flatMap(entity =>\n\t\t\tObject.values(entity.fields)\n\t\t\t\t.filter((field): field is Model.AnyRelation => isRelation(field) && field.target === this.data.entityName)\n\t\t\t\t.filter(field => !isInverseRelation(field) || entity.name !== this.data.entityName) // skip self-referencing inverse relations\n\t\t\t\t.map((field): [string, string] => [entity.name, field.name]),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\treturn { message: `Remove entity ${this.data.entityName}`, isDestructive: true }\n\t}\n\n}\n\nexport interface RemoveEntityModificationData {\n\tentityName: string\n}\n\nexport const removeEntityModification = createModificationType({\n\tid: 'removeEntity',\n\thandler: RemoveEntityModificationHandler,\n})\n\nexport class RemoveEntityDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.keys(originalSchema.model.entities)\n\t\t\t.filter(name => !updatedSchema.model.entities[name])\n\t\t\t.map(entityName => removeEntityModification.createModification({ entityName }))\n\t}\n}\n"],"names":["schema","VERSION_REMOVE_REFERENCING_RELATIONS","removeFieldModification","acceptEveryFieldVisitor","updateSchema","VERSION_ACL_PATCH","updateAcl","updateAclEveryRole","Acl","updateAclEntities","updateAclEveryEntity","updateAclEveryPredicate","PredicateDefinitionProcessor","removeField","updateModel","isRelation","isInverseRelation","createModificationType"],"mappings":"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"}
|
|
@@ -15,7 +15,11 @@ class RemoveEntityModificationHandler {
|
|
|
15
15
|
createSql(builder, options) {
|
|
16
16
|
const entity = this.schema.model.entities[this.data.entityName];
|
|
17
17
|
if (entity.view) {
|
|
18
|
-
|
|
18
|
+
if (entity.view.materialized) {
|
|
19
|
+
builder.dropMaterializedView(entity.tableName);
|
|
20
|
+
} else {
|
|
21
|
+
builder.dropView(entity.tableName);
|
|
22
|
+
}
|
|
19
23
|
return;
|
|
20
24
|
}
|
|
21
25
|
if (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoveEntityModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/entities/RemoveEntityModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Acl, Model, Schema } from '@contember/schema'\nimport {\n\tremoveField,\n\tSchemaUpdater,\n\tupdateAcl,\n\tupdateAclEntities,\n\tupdateAclEveryEntity,\n\tupdateAclEveryPredicate,\n\tupdateAclEveryRole,\n\tupdateModel,\n\tupdateSchema,\n} from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler, ModificationHandlerCreateSqlOptions,\n\tModificationHandlerOptions,\n} from '../ModificationHandler'\nimport { VERSION_ACL_PATCH, VERSION_REMOVE_REFERENCING_RELATIONS } from '../ModificationVersions'\nimport { acceptEveryFieldVisitor, isInverseRelation, isRelation, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { removeFieldModification } from '../fields'\n\nexport class RemoveEntityModificationHandler implements ModificationHandler<RemoveEntityModificationData> {\n\tconstructor(\n\t\tprivate readonly data: RemoveEntityModificationData,\n\t\tprivate readonly schema: Schema,\n\t\tprivate readonly options: ModificationHandlerOptions,\n\t) {}\n\n\tpublic createSql(builder: MigrationBuilder, options: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\tbuilder.dropView(entity.tableName)\n\t\t\treturn\n\t\t}\n\t\tif (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {\n\t\t\tthis.getFieldsToRemove(this.schema).forEach(([entityName, fieldName]) => {\n\t\t\t\tconst removeFieldHandler = removeFieldModification.createHandler({ entityName, fieldName }, this.schema, this.options)\n\t\t\t\tremoveFieldHandler.createSql(builder, options)\n\t\t\t})\n\t\t}\n\t\tacceptEveryFieldVisitor(this.schema.model, entity, {\n\t\t\tvisitManyHasManyOwning: ({ relation }) => {\n\t\t\t\tbuilder.dropTable(relation.joiningTable.tableName)\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitColumn: () => {},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\tvisitManyHasOne: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t})\n\t\tbuilder.dropTable(entity.tableName)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateSchema(\n\t\t\tthis.options.formatVersion >= VERSION_ACL_PATCH\n\t\t\t\t? updateAcl(\n\t\t\t\t\tupdateAclEveryRole(\n\t\t\t\t\t\t({ role }) => ({\n\t\t\t\t\t\t\t...role,\n\t\t\t\t\t\t\tvariables: Object.fromEntries(\n\t\t\t\t\t\t\t\tObject.entries(role.variables).filter(([, variable]) =>\n\t\t\t\t\t\t\t\t\tvariable.type !== Acl.VariableType.entity || variable.entityName !== this.data.entityName,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEntities(({ entities }) => {\n\t\t\t\t\t\t\tconst { [this.data.entityName]: removed, ...other } = entities\n\t\t\t\t\t\t\treturn other\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEveryEntity(\n\t\t\t\t\t\t\tupdateAclEveryPredicate(({ predicate, entityName, schema }) => {\n\t\t\t\t\t\t\t\tconst processor = new PredicateDefinitionProcessor(schema.model)\n\t\t\t\t\t\t\t\tconst currentEntity = schema.model.entities[entityName]\n\t\t\t\t\t\t\t\treturn processor.process(currentEntity, predicate, {\n\t\t\t\t\t\t\t\t\thandleColumn: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\thandleRelation: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t\tthis.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS\n\t\t\t\t? ({ schema }) => {\n\t\t\t\t\tconst fieldsToRemove = this.getFieldsToRemove(schema)\n\t\t\t\t\treturn fieldsToRemove.reduce(\n\t\t\t\t\t\t(schema, [entity, field]) => removeField(entity, field, this.options.formatVersion)({ schema }),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t)\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t\tupdateModel(({ model }) => {\n\t\t\t\tconst { [this.data.entityName]: removed, ...entities } = model.entities\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tentities: { ...entities },\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate getFieldsToRemove(schema: Schema): [entity: string, field: string][] {\n\t\treturn Object.values(schema.model.entities).flatMap(entity =>\n\t\t\tObject.values(entity.fields)\n\t\t\t\t.filter((field): field is Model.AnyRelation => isRelation(field) && field.target === this.data.entityName)\n\t\t\t\t.filter(field => !isInverseRelation(field) || entity.name !== this.data.entityName) // skip self-referencing inverse relations\n\t\t\t\t.map((field): [string, string] => [entity.name, field.name]),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\treturn { message: `Remove entity ${this.data.entityName}`, isDestructive: true }\n\t}\n\n}\n\nexport interface RemoveEntityModificationData {\n\tentityName: string\n}\n\nexport const removeEntityModification = createModificationType({\n\tid: 'removeEntity',\n\thandler: RemoveEntityModificationHandler,\n})\n\nexport class RemoveEntityDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.keys(originalSchema.model.entities)\n\t\t\t.filter(name => !updatedSchema.model.entities[name])\n\t\t\t.map(entityName => removeEntityModification.createModification({ entityName }))\n\t}\n}\n"],"names":["schema"],"mappings":";;;;;;;;AAuBO,MAAM,gCAA6F;AAAA,EACzG,YACkB,MACA,QACA,SAChB;AAHgB,SAAA,OAAA;AACA,SAAA,SAAA;AACA,SAAA,UAAA;AAAA,EAAA;AAAA,EAGX,UAAU,SAA2B,SAAoD;AAC/F,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,MAAM;
|
|
1
|
+
{"version":3,"file":"RemoveEntityModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/entities/RemoveEntityModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Acl, Model, Schema } from '@contember/schema'\nimport {\n\tremoveField,\n\tSchemaUpdater,\n\tupdateAcl,\n\tupdateAclEntities,\n\tupdateAclEveryEntity,\n\tupdateAclEveryPredicate,\n\tupdateAclEveryRole,\n\tupdateModel,\n\tupdateSchema,\n} from '../utils/schemaUpdateUtils'\nimport {\n\tcreateModificationType,\n\tDiffer,\n\tModificationHandler, ModificationHandlerCreateSqlOptions,\n\tModificationHandlerOptions,\n} from '../ModificationHandler'\nimport { VERSION_ACL_PATCH, VERSION_REMOVE_REFERENCING_RELATIONS } from '../ModificationVersions'\nimport { acceptEveryFieldVisitor, isInverseRelation, isRelation, PredicateDefinitionProcessor } from '@contember/schema-utils'\nimport { removeFieldModification } from '../fields'\n\nexport class RemoveEntityModificationHandler implements ModificationHandler<RemoveEntityModificationData> {\n\tconstructor(\n\t\tprivate readonly data: RemoveEntityModificationData,\n\t\tprivate readonly schema: Schema,\n\t\tprivate readonly options: ModificationHandlerOptions,\n\t) {}\n\n\tpublic createSql(builder: MigrationBuilder, options: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\tif (entity.view.materialized) {\n\t\t\t\tbuilder.dropMaterializedView(entity.tableName)\n\t\t\t} else {\n\t\t\t\tbuilder.dropView(entity.tableName)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif (this.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS) {\n\t\t\tthis.getFieldsToRemove(this.schema).forEach(([entityName, fieldName]) => {\n\t\t\t\tconst removeFieldHandler = removeFieldModification.createHandler({ entityName, fieldName }, this.schema, this.options)\n\t\t\t\tremoveFieldHandler.createSql(builder, options)\n\t\t\t})\n\t\t}\n\t\tacceptEveryFieldVisitor(this.schema.model, entity, {\n\t\t\tvisitManyHasManyOwning: ({ relation }) => {\n\t\t\t\tbuilder.dropTable(relation.joiningTable.tableName)\n\t\t\t},\n\t\t\tvisitManyHasManyInverse: () => {},\n\t\t\tvisitColumn: () => {},\n\t\t\tvisitOneHasOneInverse: () => {},\n\t\t\tvisitOneHasOneOwning: () => {},\n\t\t\tvisitManyHasOne: () => {},\n\t\t\tvisitOneHasMany: () => {},\n\t\t})\n\t\tbuilder.dropTable(entity.tableName)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateSchema(\n\t\t\tthis.options.formatVersion >= VERSION_ACL_PATCH\n\t\t\t\t? updateAcl(\n\t\t\t\t\tupdateAclEveryRole(\n\t\t\t\t\t\t({ role }) => ({\n\t\t\t\t\t\t\t...role,\n\t\t\t\t\t\t\tvariables: Object.fromEntries(\n\t\t\t\t\t\t\t\tObject.entries(role.variables).filter(([, variable]) =>\n\t\t\t\t\t\t\t\t\tvariable.type !== Acl.VariableType.entity || variable.entityName !== this.data.entityName,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEntities(({ entities }) => {\n\t\t\t\t\t\t\tconst { [this.data.entityName]: removed, ...other } = entities\n\t\t\t\t\t\t\treturn other\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tupdateAclEveryEntity(\n\t\t\t\t\t\t\tupdateAclEveryPredicate(({ predicate, entityName, schema }) => {\n\t\t\t\t\t\t\t\tconst processor = new PredicateDefinitionProcessor(schema.model)\n\t\t\t\t\t\t\t\tconst currentEntity = schema.model.entities[entityName]\n\t\t\t\t\t\t\t\treturn processor.process(currentEntity, predicate, {\n\t\t\t\t\t\t\t\t\thandleColumn: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\thandleRelation: ctx => {\n\t\t\t\t\t\t\t\t\t\treturn ctx.entity.name === this.data.entityName ? undefined : ctx.value\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t )\n\t\t\t\t: undefined,\n\t\t\tthis.options.formatVersion >= VERSION_REMOVE_REFERENCING_RELATIONS\n\t\t\t\t? ({ schema }) => {\n\t\t\t\t\tconst fieldsToRemove = this.getFieldsToRemove(schema)\n\t\t\t\t\treturn fieldsToRemove.reduce(\n\t\t\t\t\t\t(schema, [entity, field]) => removeField(entity, field, this.options.formatVersion)({ schema }),\n\t\t\t\t\t\tschema,\n\t\t\t\t\t)\n\t\t\t\t }\n\t\t\t\t: undefined,\n\t\t\tupdateModel(({ model }) => {\n\t\t\t\tconst { [this.data.entityName]: removed, ...entities } = model.entities\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tentities: { ...entities },\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tprivate getFieldsToRemove(schema: Schema): [entity: string, field: string][] {\n\t\treturn Object.values(schema.model.entities).flatMap(entity =>\n\t\t\tObject.values(entity.fields)\n\t\t\t\t.filter((field): field is Model.AnyRelation => isRelation(field) && field.target === this.data.entityName)\n\t\t\t\t.filter(field => !isInverseRelation(field) || entity.name !== this.data.entityName) // skip self-referencing inverse relations\n\t\t\t\t.map((field): [string, string] => [entity.name, field.name]),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\treturn { message: `Remove entity ${this.data.entityName}`, isDestructive: true }\n\t}\n\n}\n\nexport interface RemoveEntityModificationData {\n\tentityName: string\n}\n\nexport const removeEntityModification = createModificationType({\n\tid: 'removeEntity',\n\thandler: RemoveEntityModificationHandler,\n})\n\nexport class RemoveEntityDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.keys(originalSchema.model.entities)\n\t\t\t.filter(name => !updatedSchema.model.entities[name])\n\t\t\t.map(entityName => removeEntityModification.createModification({ entityName }))\n\t}\n}\n"],"names":["schema"],"mappings":";;;;;;;;AAuBO,MAAM,gCAA6F;AAAA,EACzG,YACkB,MACA,QACA,SAChB;AAHgB,SAAA,OAAA;AACA,SAAA,SAAA;AACA,SAAA,UAAA;AAAA,EAAA;AAAA,EAGX,UAAU,SAA2B,SAAoD;AAC/F,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,MAAM;AACZ,UAAA,OAAO,KAAK,cAAc;AACrB,gBAAA,qBAAqB,OAAO,SAAS;AAAA,MAAA,OACvC;AACE,gBAAA,SAAS,OAAO,SAAS;AAAA,MAAA;AAElC;AAAA,IAAA;AAEG,QAAA,KAAK,QAAQ,iBAAiB,sCAAsC;AAClE,WAAA,kBAAkB,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,YAAY,SAAS,MAAM;AAClE,cAAA,qBAAqB,wBAAwB,cAAc,EAAE,YAAY,UAAa,GAAA,KAAK,QAAQ,KAAK,OAAO;AAClG,2BAAA,UAAU,SAAS,OAAO;AAAA,MAAA,CAC7C;AAAA,IAAA;AAEsB,4BAAA,KAAK,OAAO,OAAO,QAAQ;AAAA,MAClD,wBAAwB,CAAC,EAAE,eAAe;AACjC,gBAAA,UAAU,SAAS,aAAa,SAAS;AAAA,MAClD;AAAA,MACA,yBAAyB,MAAM;AAAA,MAAC;AAAA,MAChC,aAAa,MAAM;AAAA,MAAC;AAAA,MACpB,uBAAuB,MAAM;AAAA,MAAC;AAAA,MAC9B,sBAAsB,MAAM;AAAA,MAAC;AAAA,MAC7B,iBAAiB,MAAM;AAAA,MAAC;AAAA,MACxB,iBAAiB,MAAM;AAAA,MAAA;AAAA,IAAC,CACxB;AACO,YAAA,UAAU,OAAO,SAAS;AAAA,EAAA;AAAA,EAG5B,mBAAkC;AACjC,WAAA;AAAA,MACN,KAAK,QAAQ,iBAAiB,oBAC3B;AAAA,QACD;AAAA,UACC,CAAC,EAAE,KAAA,OAAY;AAAA,YACd,GAAG;AAAA,YACH,WAAW,OAAO;AAAA,cACjB,OAAO,QAAQ,KAAK,SAAS,EAAE;AAAA,gBAAO,CAAC,GAAG,QAAQ,MACjD,SAAS,SAAS,IAAI,aAAa,UAAU,SAAS,eAAe,KAAK,KAAK;AAAA,cAAA;AAAA,YAChF;AAAA,UACD;AAAA,UAED,kBAAkB,CAAC,EAAE,eAAe;AAC7B,kBAAA,EAAE,CAAC,KAAK,KAAK,UAAU,GAAG,SAAS,GAAG,MAAA,IAAU;AAC/C,mBAAA;AAAA,UAAA,CACP;AAAA,UACD;AAAA,YACC,wBAAwB,CAAC,EAAE,WAAW,YAAY,aAAa;AAC9D,oBAAM,YAAY,IAAI,6BAA6B,OAAO,KAAK;AAC/D,oBAAM,gBAAgB,OAAO,MAAM,SAAS,UAAU;AAC/C,qBAAA,UAAU,QAAQ,eAAe,WAAW;AAAA,gBAClD,cAAc,CAAO,QAAA;AACpB,yBAAO,IAAI,OAAO,SAAS,KAAK,KAAK,aAAa,SAAY,IAAI;AAAA,gBACnE;AAAA,gBACA,gBAAgB,CAAO,QAAA;AACtB,yBAAO,IAAI,OAAO,SAAS,KAAK,KAAK,aAAa,SAAY,IAAI;AAAA,gBAAA;AAAA,cACnE,CACA;AAAA,YACD,CAAA;AAAA,UAAA;AAAA,QACF;AAAA,MAGA,IAAA;AAAA,MACH,KAAK,QAAQ,iBAAiB,uCAC3B,CAAC,EAAE,aAAa;AACX,cAAA,iBAAiB,KAAK,kBAAkB,MAAM;AACpD,eAAO,eAAe;AAAA,UACrB,CAACA,SAAQ,CAAC,QAAQ,KAAK,MAAM,YAAY,QAAQ,OAAO,KAAK,QAAQ,aAAa,EAAE,EAAE,QAAAA,SAAQ;AAAA,UAC9F;AAAA,QACD;AAAA,MAEC,IAAA;AAAA,MACH,YAAY,CAAC,EAAE,YAAY;AACpB,cAAA,EAAE,CAAC,KAAK,KAAK,UAAU,GAAG,SAAS,GAAG,aAAa,MAAM;AACxD,eAAA;AAAA,UACN,GAAG;AAAA,UACH,UAAU,EAAE,GAAG,SAAS;AAAA,QACzB;AAAA,MACA,CAAA;AAAA,IACF;AAAA,EAAA;AAAA,EAGO,kBAAkB,QAAmD;AAC5E,WAAO,OAAO,OAAO,OAAO,MAAM,QAAQ,EAAE;AAAA,MAAQ,YACnD,OAAO,OAAO,OAAO,MAAM,EACzB,OAAO,CAAC,UAAsC,WAAW,KAAK,KAAK,MAAM,WAAW,KAAK,KAAK,UAAU,EACxG,OAAO,CAAS,UAAA,CAAC,kBAAkB,KAAK,KAAK,OAAO,SAAS,KAAK,KAAK,UAAU,EACjF,IAAI,CAAC,UAA4B,CAAC,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC7D;AAAA,EAAA;AAAA,EAGD,WAAW;AACH,WAAA,EAAE,SAAS,iBAAiB,KAAK,KAAK,UAAU,IAAI,eAAe,KAAK;AAAA,EAAA;AAGjF;AAMO,MAAM,2BAA2B,uBAAuB;AAAA,EAC9D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAEM,MAAM,mBAAqC;AAAA,EACjD,WAAW,gBAAwB,eAAuB;AAClD,WAAA,OAAO,KAAK,eAAe,MAAM,QAAQ,EAC9C,OAAO,CAAQ,SAAA,CAAC,cAAc,MAAM,SAAS,IAAI,CAAC,EAClD,IAAI,CAAA,eAAc,yBAAyB,mBAAmB,EAAE,WAAW,CAAC,CAAC;AAAA,EAAA;AAEjF;"}
|
|
@@ -1,21 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const schema = require("@contember/schema");
|
|
3
4
|
const schemaUpdateUtils = require("../utils/schemaUpdateUtils.cjs");
|
|
4
5
|
const ModificationHandler = require("../ModificationHandler.cjs");
|
|
5
6
|
const deepEqual = require("fast-deep-equal");
|
|
6
7
|
const enumUtils = require("./enumUtils.cjs");
|
|
8
|
+
const columnUtils = require("../utils/columnUtils.cjs");
|
|
7
9
|
class UpdateEnumModificationHandler {
|
|
8
|
-
constructor(data,
|
|
10
|
+
constructor(data, schema2) {
|
|
9
11
|
this.data = data;
|
|
10
|
-
this.schema =
|
|
12
|
+
this.schema = schema2;
|
|
11
13
|
}
|
|
12
14
|
createSql(builder) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if (!this.requiresNewDomain()) {
|
|
16
|
+
builder.sql(`
|
|
17
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
18
|
+
DROP CONSTRAINT ${enumUtils.getConstraintName(this.data.enumName)}`);
|
|
19
|
+
builder.sql(`
|
|
20
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
21
|
+
ADD CONSTRAINT ${enumUtils.getConstraintName(this.data.enumName)} CHECK (${enumUtils.createCheck(this.data.values)})`);
|
|
22
|
+
} else {
|
|
23
|
+
const oldName = `${this.data.enumName}__old`;
|
|
24
|
+
builder.renameDomain(this.data.enumName, oldName);
|
|
25
|
+
builder.createDomain(this.data.enumName, "text", {
|
|
26
|
+
check: enumUtils.createCheck(this.data.values),
|
|
27
|
+
constraintName: enumUtils.getConstraintName(this.data.enumName)
|
|
28
|
+
});
|
|
29
|
+
for (const entity of Object.values(this.schema.model.entities)) {
|
|
30
|
+
for (const field of Object.values(entity.fields)) {
|
|
31
|
+
if (field.type === schema.Model.ColumnType.Enum && field.columnType === this.data.enumName) {
|
|
32
|
+
builder.alterColumn(entity.tableName, field.columnName, {
|
|
33
|
+
type: columnUtils.getColumnSqlType(field)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
builder.dropDomain(oldName);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
requiresNewDomain() {
|
|
42
|
+
return Object.values(this.schema.model.entities).some((it) => {
|
|
43
|
+
return Object.values(it.fields).some((field) => {
|
|
44
|
+
return field.type === schema.Model.ColumnType.Enum && field.columnType === this.data.enumName && field.list;
|
|
45
|
+
});
|
|
46
|
+
});
|
|
19
47
|
}
|
|
20
48
|
getSchemaUpdater() {
|
|
21
49
|
return schemaUpdateUtils.updateModel(({ model }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateEnumModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/enums/UpdateEnumModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Schema } from '@contember/schema'\nimport { SchemaUpdater, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { createCheck, getConstraintName } from './enumUtils'\n\nexport class UpdateEnumModificationHandler implements ModificationHandler<UpdateEnumModificationData> {\n\tconstructor(private readonly data: UpdateEnumModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tbuilder.sql(`\n\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\tDROP CONSTRAINT ${getConstraintName(this.data.enumName)}`)\n\t\tbuilder.sql(`\n\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\tADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(({ model }) => ({\n\t\t\t...model,\n\t\t\tenums: {\n\t\t\t\t...model.enums,\n\t\t\t\t[this.data.enumName]: this.data.values,\n\t\t\t},\n\t\t}))\n\t}\n\n\tdescribe() {\n\t\tconst currentValues = this.schema.model.enums[this.data.enumName]\n\t\tconst missingValues = currentValues.filter(it => !this.data.values.includes(it))\n\t\tconst failureWarning =\n\t\t\tmissingValues.length > 0\n\t\t\t\t? `Removing values (${missingValues.join(', ')}) from enum, this may fail in runtime`\n\t\t\t\t: undefined\n\t\treturn { message: `Update enum ${this.data.enumName}`, failureWarning }\n\t}\n}\n\nexport interface UpdateEnumModificationData {\n\tenumName: string\n\tvalues: readonly string[]\n}\n\nexport const updateEnumModification = createModificationType({\n\tid: 'updateEnum',\n\thandler: UpdateEnumModificationHandler,\n})\n\nexport class UpdateEnumDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.entries(updatedSchema.model.enums)\n\t\t\t.filter(\n\t\t\t\t([name]) =>\n\t\t\t\t\toriginalSchema.model.enums[name] &&\n\t\t\t\t\t!deepEqual(updatedSchema.model.enums[name], originalSchema.model.enums[name]),\n\t\t\t)\n\t\t\t.map(([enumName, values]) => updateEnumModification.createModification({ enumName, values }))\n\t}\n}\n"],"names":["getConstraintName","createCheck","updateModel","createModificationType"],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateEnumModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/enums/UpdateEnumModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { createCheck, getConstraintName } from './enumUtils'\nimport { getColumnSqlType } from '../utils/columnUtils'\n\nexport class UpdateEnumModificationHandler implements ModificationHandler<UpdateEnumModificationData> {\n\tconstructor(private readonly data: UpdateEnumModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tif (!this.requiresNewDomain()) {\n\t\t\tbuilder.sql(`\n\t\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\t\tDROP CONSTRAINT ${getConstraintName(this.data.enumName)}`)\n\t\t\tbuilder.sql(`\n\t\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\t\tADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`)\n\t\t} else {\n\t\t\t/**\n\t\t\t * Because postgres does not support altering domain constrains\n\t\t\t * when used in composite types (like arrays) we need to:\n\t\t\t * - create a new domain with the new constraint\n\t\t\t * - update all the columns using the old domain to use the new domain\n\t\t\t * - drop the old domain and rename the new domain to the old name\n\t\t\t */\n\t\t\tconst oldName = `${this.data.enumName}__old`\n\t\t\tbuilder.renameDomain(this.data.enumName, oldName)\n\n\t\t\tbuilder.createDomain(this.data.enumName, 'text', {\n\t\t\t\tcheck: createCheck(this.data.values),\n\t\t\t\tconstraintName: getConstraintName(this.data.enumName),\n\t\t\t})\n\t\t\tfor (const entity of Object.values(this.schema.model.entities)) {\n\t\t\t\tfor (const field of Object.values(entity.fields)) {\n\t\t\t\t\tif (field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName) {\n\t\t\t\t\t\tbuilder.alterColumn(entity.tableName, field.columnName, {\n\t\t\t\t\t\t\ttype: getColumnSqlType(field),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbuilder.dropDomain(oldName)\n\t\t}\n\t}\n\n\tprivate requiresNewDomain(): boolean {\n\t\treturn Object.values(this.schema.model.entities).some(it => {\n\t\t\treturn Object.values(it.fields).some(field => {\n\t\t\t\treturn field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName && field.list\n\t\t\t})\n\t\t})\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(({ model }) => ({\n\t\t\t...model,\n\t\t\tenums: {\n\t\t\t\t...model.enums,\n\t\t\t\t[this.data.enumName]: this.data.values,\n\t\t\t},\n\t\t}))\n\t}\n\n\tdescribe() {\n\t\tconst currentValues = this.schema.model.enums[this.data.enumName]\n\t\tconst missingValues = currentValues.filter(it => !this.data.values.includes(it))\n\t\tconst failureWarning =\n\t\t\tmissingValues.length > 0\n\t\t\t\t? `Removing values (${missingValues.join(', ')}) from enum, this may fail in runtime`\n\t\t\t\t: undefined\n\t\treturn { message: `Update enum ${this.data.enumName}`, failureWarning }\n\t}\n}\n\nexport interface UpdateEnumModificationData {\n\tenumName: string\n\tvalues: readonly string[]\n}\n\nexport const updateEnumModification = createModificationType({\n\tid: 'updateEnum',\n\thandler: UpdateEnumModificationHandler,\n})\n\nexport class UpdateEnumDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.entries(updatedSchema.model.enums)\n\t\t\t.filter(\n\t\t\t\t([name]) =>\n\t\t\t\t\toriginalSchema.model.enums[name] &&\n\t\t\t\t\t!deepEqual(updatedSchema.model.enums[name], originalSchema.model.enums[name]),\n\t\t\t)\n\t\t\t.map(([enumName, values]) => updateEnumModification.createModification({ enumName, values }))\n\t}\n}\n"],"names":["schema","getConstraintName","createCheck","Model","getColumnSqlType","updateModel","createModificationType"],"mappings":";;;;;;;;AAQO,MAAM,8BAAyF;AAAA,EACrG,YAA6B,MAAmDA,SAAgB;AAAnE,SAAA,OAAA;AAAmD,SAAA,SAAAA;AAAA,EAAA;AAAA,EAEzE,UAAU,SAAiC;AAC7C,QAAA,CAAC,KAAK,qBAAqB;AAC9B,cAAQ,IAAI;AAAA,oBACK,KAAK,KAAK,QAAQ;AAAA,sBAChBC,UAAkB,kBAAA,KAAK,KAAK,QAAQ,CAAC,EAAE;AAC1D,cAAQ,IAAI;AAAA,oBACK,KAAK,KAAK,QAAQ;AAAA,qBACjBA,4BAAkB,KAAK,KAAK,QAAQ,CAAC,WAAWC,UAAA,YAAY,KAAK,KAAK,MAAM,CAAC,GAAG;AAAA,IAAA,OAC5F;AAQN,YAAM,UAAU,GAAG,KAAK,KAAK,QAAQ;AACrC,cAAQ,aAAa,KAAK,KAAK,UAAU,OAAO;AAEhD,cAAQ,aAAa,KAAK,KAAK,UAAU,QAAQ;AAAA,QAChD,OAAOA,UAAA,YAAY,KAAK,KAAK,MAAM;AAAA,QACnC,gBAAgBD,UAAA,kBAAkB,KAAK,KAAK,QAAQ;AAAA,MAAA,CACpD;AACD,iBAAW,UAAU,OAAO,OAAO,KAAK,OAAO,MAAM,QAAQ,GAAG;AAC/D,mBAAW,SAAS,OAAO,OAAO,OAAO,MAAM,GAAG;AAC7C,cAAA,MAAM,SAASE,OAAM,MAAA,WAAW,QAAQ,MAAM,eAAe,KAAK,KAAK,UAAU;AACpF,oBAAQ,YAAY,OAAO,WAAW,MAAM,YAAY;AAAA,cACvD,MAAMC,6BAAiB,KAAK;AAAA,YAAA,CAC5B;AAAA,UAAA;AAAA,QACF;AAAA,MACD;AAGD,cAAQ,WAAW,OAAO;AAAA,IAAA;AAAA,EAC3B;AAAA,EAGO,oBAA6B;AAC7B,WAAA,OAAO,OAAO,KAAK,OAAO,MAAM,QAAQ,EAAE,KAAK,CAAM,OAAA;AAC3D,aAAO,OAAO,OAAO,GAAG,MAAM,EAAE,KAAK,CAAS,UAAA;AACtC,eAAA,MAAM,SAASD,OAAA,MAAM,WAAW,QAAQ,MAAM,eAAe,KAAK,KAAK,YAAY,MAAM;AAAA,MAAA,CAChG;AAAA,IAAA,CACD;AAAA,EAAA;AAAA,EAGK,mBAAkC;AACxC,WAAOE,kBAAY,YAAA,CAAC,EAAE,aAAa;AAAA,MAClC,GAAG;AAAA,MACH,OAAO;AAAA,QACN,GAAG,MAAM;AAAA,QACT,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK;AAAA,MAAA;AAAA,IACjC,EACC;AAAA,EAAA;AAAA,EAGH,WAAW;AACV,UAAM,gBAAgB,KAAK,OAAO,MAAM,MAAM,KAAK,KAAK,QAAQ;AAC1D,UAAA,gBAAgB,cAAc,OAAO,CAAM,OAAA,CAAC,KAAK,KAAK,OAAO,SAAS,EAAE,CAAC;AACzE,UAAA,iBACL,cAAc,SAAS,IACpB,oBAAoB,cAAc,KAAK,IAAI,CAAC,0CAC5C;AACJ,WAAO,EAAE,SAAS,eAAe,KAAK,KAAK,QAAQ,IAAI,eAAe;AAAA,EAAA;AAExE;AAOO,MAAM,yBAAyBC,oBAAAA,uBAAuB;AAAA,EAC5D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAEM,MAAM,iBAAmC;AAAA,EAC/C,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,QAAQ,cAAc,MAAM,KAAK,EAC7C;AAAA,MACA,CAAC,CAAC,IAAI,MACL,eAAe,MAAM,MAAM,IAAI,KAC/B,CAAC,UAAU,cAAc,MAAM,MAAM,IAAI,GAAG,eAAe,MAAM,MAAM,IAAI,CAAC;AAAA,IAE7E,EAAA,IAAI,CAAC,CAAC,UAAU,MAAM,MAAM,uBAAuB,mBAAmB,EAAE,UAAU,OAAA,CAAQ,CAAC;AAAA,EAAA;AAE/F;;;;"}
|
|
@@ -1,19 +1,47 @@
|
|
|
1
|
+
import { Model } from "@contember/schema";
|
|
1
2
|
import { updateModel } from "../utils/schemaUpdateUtils.js";
|
|
2
3
|
import { createModificationType } from "../ModificationHandler.js";
|
|
3
4
|
import deepEqual from "fast-deep-equal";
|
|
4
5
|
import { getConstraintName, createCheck } from "./enumUtils.js";
|
|
6
|
+
import { getColumnSqlType } from "../utils/columnUtils.js";
|
|
5
7
|
class UpdateEnumModificationHandler {
|
|
6
8
|
constructor(data, schema) {
|
|
7
9
|
this.data = data;
|
|
8
10
|
this.schema = schema;
|
|
9
11
|
}
|
|
10
12
|
createSql(builder) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
if (!this.requiresNewDomain()) {
|
|
14
|
+
builder.sql(`
|
|
15
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
16
|
+
DROP CONSTRAINT ${getConstraintName(this.data.enumName)}`);
|
|
17
|
+
builder.sql(`
|
|
18
|
+
ALTER DOMAIN "${this.data.enumName}"
|
|
19
|
+
ADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`);
|
|
20
|
+
} else {
|
|
21
|
+
const oldName = `${this.data.enumName}__old`;
|
|
22
|
+
builder.renameDomain(this.data.enumName, oldName);
|
|
23
|
+
builder.createDomain(this.data.enumName, "text", {
|
|
24
|
+
check: createCheck(this.data.values),
|
|
25
|
+
constraintName: getConstraintName(this.data.enumName)
|
|
26
|
+
});
|
|
27
|
+
for (const entity of Object.values(this.schema.model.entities)) {
|
|
28
|
+
for (const field of Object.values(entity.fields)) {
|
|
29
|
+
if (field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName) {
|
|
30
|
+
builder.alterColumn(entity.tableName, field.columnName, {
|
|
31
|
+
type: getColumnSqlType(field)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
builder.dropDomain(oldName);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
requiresNewDomain() {
|
|
40
|
+
return Object.values(this.schema.model.entities).some((it) => {
|
|
41
|
+
return Object.values(it.fields).some((field) => {
|
|
42
|
+
return field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName && field.list;
|
|
43
|
+
});
|
|
44
|
+
});
|
|
17
45
|
}
|
|
18
46
|
getSchemaUpdater() {
|
|
19
47
|
return updateModel(({ model }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateEnumModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/enums/UpdateEnumModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Schema } from '@contember/schema'\nimport { SchemaUpdater, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { createCheck, getConstraintName } from './enumUtils'\n\nexport class UpdateEnumModificationHandler implements ModificationHandler<UpdateEnumModificationData> {\n\tconstructor(private readonly data: UpdateEnumModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tbuilder.sql(`\n\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\tDROP CONSTRAINT ${getConstraintName(this.data.enumName)}`)\n\t\tbuilder.sql(`\n\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\tADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`)\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(({ model }) => ({\n\t\t\t...model,\n\t\t\tenums: {\n\t\t\t\t...model.enums,\n\t\t\t\t[this.data.enumName]: this.data.values,\n\t\t\t},\n\t\t}))\n\t}\n\n\tdescribe() {\n\t\tconst currentValues = this.schema.model.enums[this.data.enumName]\n\t\tconst missingValues = currentValues.filter(it => !this.data.values.includes(it))\n\t\tconst failureWarning =\n\t\t\tmissingValues.length > 0\n\t\t\t\t? `Removing values (${missingValues.join(', ')}) from enum, this may fail in runtime`\n\t\t\t\t: undefined\n\t\treturn { message: `Update enum ${this.data.enumName}`, failureWarning }\n\t}\n}\n\nexport interface UpdateEnumModificationData {\n\tenumName: string\n\tvalues: readonly string[]\n}\n\nexport const updateEnumModification = createModificationType({\n\tid: 'updateEnum',\n\thandler: UpdateEnumModificationHandler,\n})\n\nexport class UpdateEnumDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.entries(updatedSchema.model.enums)\n\t\t\t.filter(\n\t\t\t\t([name]) =>\n\t\t\t\t\toriginalSchema.model.enums[name] &&\n\t\t\t\t\t!deepEqual(updatedSchema.model.enums[name], originalSchema.model.enums[name]),\n\t\t\t)\n\t\t\t.map(([enumName, values]) => updateEnumModification.createModification({ enumName, values }))\n\t}\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateEnumModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/enums/UpdateEnumModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { createCheck, getConstraintName } from './enumUtils'\nimport { getColumnSqlType } from '../utils/columnUtils'\n\nexport class UpdateEnumModificationHandler implements ModificationHandler<UpdateEnumModificationData> {\n\tconstructor(private readonly data: UpdateEnumModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tif (!this.requiresNewDomain()) {\n\t\t\tbuilder.sql(`\n\t\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\t\tDROP CONSTRAINT ${getConstraintName(this.data.enumName)}`)\n\t\t\tbuilder.sql(`\n\t\t\t\tALTER DOMAIN \"${this.data.enumName}\"\n\t\t\t\tADD CONSTRAINT ${getConstraintName(this.data.enumName)} CHECK (${createCheck(this.data.values)})`)\n\t\t} else {\n\t\t\t/**\n\t\t\t * Because postgres does not support altering domain constrains\n\t\t\t * when used in composite types (like arrays) we need to:\n\t\t\t * - create a new domain with the new constraint\n\t\t\t * - update all the columns using the old domain to use the new domain\n\t\t\t * - drop the old domain and rename the new domain to the old name\n\t\t\t */\n\t\t\tconst oldName = `${this.data.enumName}__old`\n\t\t\tbuilder.renameDomain(this.data.enumName, oldName)\n\n\t\t\tbuilder.createDomain(this.data.enumName, 'text', {\n\t\t\t\tcheck: createCheck(this.data.values),\n\t\t\t\tconstraintName: getConstraintName(this.data.enumName),\n\t\t\t})\n\t\t\tfor (const entity of Object.values(this.schema.model.entities)) {\n\t\t\t\tfor (const field of Object.values(entity.fields)) {\n\t\t\t\t\tif (field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName) {\n\t\t\t\t\t\tbuilder.alterColumn(entity.tableName, field.columnName, {\n\t\t\t\t\t\t\ttype: getColumnSqlType(field),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbuilder.dropDomain(oldName)\n\t\t}\n\t}\n\n\tprivate requiresNewDomain(): boolean {\n\t\treturn Object.values(this.schema.model.entities).some(it => {\n\t\t\treturn Object.values(it.fields).some(field => {\n\t\t\t\treturn field.type === Model.ColumnType.Enum && field.columnType === this.data.enumName && field.list\n\t\t\t})\n\t\t})\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(({ model }) => ({\n\t\t\t...model,\n\t\t\tenums: {\n\t\t\t\t...model.enums,\n\t\t\t\t[this.data.enumName]: this.data.values,\n\t\t\t},\n\t\t}))\n\t}\n\n\tdescribe() {\n\t\tconst currentValues = this.schema.model.enums[this.data.enumName]\n\t\tconst missingValues = currentValues.filter(it => !this.data.values.includes(it))\n\t\tconst failureWarning =\n\t\t\tmissingValues.length > 0\n\t\t\t\t? `Removing values (${missingValues.join(', ')}) from enum, this may fail in runtime`\n\t\t\t\t: undefined\n\t\treturn { message: `Update enum ${this.data.enumName}`, failureWarning }\n\t}\n}\n\nexport interface UpdateEnumModificationData {\n\tenumName: string\n\tvalues: readonly string[]\n}\n\nexport const updateEnumModification = createModificationType({\n\tid: 'updateEnum',\n\thandler: UpdateEnumModificationHandler,\n})\n\nexport class UpdateEnumDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.entries(updatedSchema.model.enums)\n\t\t\t.filter(\n\t\t\t\t([name]) =>\n\t\t\t\t\toriginalSchema.model.enums[name] &&\n\t\t\t\t\t!deepEqual(updatedSchema.model.enums[name], originalSchema.model.enums[name]),\n\t\t\t)\n\t\t\t.map(([enumName, values]) => updateEnumModification.createModification({ enumName, values }))\n\t}\n}\n"],"names":[],"mappings":";;;;;;AAQO,MAAM,8BAAyF;AAAA,EACrG,YAA6B,MAAmD,QAAgB;AAAnE,SAAA,OAAA;AAAmD,SAAA,SAAA;AAAA,EAAA;AAAA,EAEzE,UAAU,SAAiC;AAC7C,QAAA,CAAC,KAAK,qBAAqB;AAC9B,cAAQ,IAAI;AAAA,oBACK,KAAK,KAAK,QAAQ;AAAA,sBAChB,kBAAkB,KAAK,KAAK,QAAQ,CAAC,EAAE;AAC1D,cAAQ,IAAI;AAAA,oBACK,KAAK,KAAK,QAAQ;AAAA,qBACjB,kBAAkB,KAAK,KAAK,QAAQ,CAAC,WAAW,YAAY,KAAK,KAAK,MAAM,CAAC,GAAG;AAAA,IAAA,OAC5F;AAQN,YAAM,UAAU,GAAG,KAAK,KAAK,QAAQ;AACrC,cAAQ,aAAa,KAAK,KAAK,UAAU,OAAO;AAEhD,cAAQ,aAAa,KAAK,KAAK,UAAU,QAAQ;AAAA,QAChD,OAAO,YAAY,KAAK,KAAK,MAAM;AAAA,QACnC,gBAAgB,kBAAkB,KAAK,KAAK,QAAQ;AAAA,MAAA,CACpD;AACD,iBAAW,UAAU,OAAO,OAAO,KAAK,OAAO,MAAM,QAAQ,GAAG;AAC/D,mBAAW,SAAS,OAAO,OAAO,OAAO,MAAM,GAAG;AAC7C,cAAA,MAAM,SAAS,MAAM,WAAW,QAAQ,MAAM,eAAe,KAAK,KAAK,UAAU;AACpF,oBAAQ,YAAY,OAAO,WAAW,MAAM,YAAY;AAAA,cACvD,MAAM,iBAAiB,KAAK;AAAA,YAAA,CAC5B;AAAA,UAAA;AAAA,QACF;AAAA,MACD;AAGD,cAAQ,WAAW,OAAO;AAAA,IAAA;AAAA,EAC3B;AAAA,EAGO,oBAA6B;AAC7B,WAAA,OAAO,OAAO,KAAK,OAAO,MAAM,QAAQ,EAAE,KAAK,CAAM,OAAA;AAC3D,aAAO,OAAO,OAAO,GAAG,MAAM,EAAE,KAAK,CAAS,UAAA;AACtC,eAAA,MAAM,SAAS,MAAM,WAAW,QAAQ,MAAM,eAAe,KAAK,KAAK,YAAY,MAAM;AAAA,MAAA,CAChG;AAAA,IAAA,CACD;AAAA,EAAA;AAAA,EAGK,mBAAkC;AACxC,WAAO,YAAY,CAAC,EAAE,aAAa;AAAA,MAClC,GAAG;AAAA,MACH,OAAO;AAAA,QACN,GAAG,MAAM;AAAA,QACT,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK;AAAA,MAAA;AAAA,IACjC,EACC;AAAA,EAAA;AAAA,EAGH,WAAW;AACV,UAAM,gBAAgB,KAAK,OAAO,MAAM,MAAM,KAAK,KAAK,QAAQ;AAC1D,UAAA,gBAAgB,cAAc,OAAO,CAAM,OAAA,CAAC,KAAK,KAAK,OAAO,SAAS,EAAE,CAAC;AACzE,UAAA,iBACL,cAAc,SAAS,IACpB,oBAAoB,cAAc,KAAK,IAAI,CAAC,0CAC5C;AACJ,WAAO,EAAE,SAAS,eAAe,KAAK,KAAK,QAAQ,IAAI,eAAe;AAAA,EAAA;AAExE;AAOO,MAAM,yBAAyB,uBAAuB;AAAA,EAC5D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAEM,MAAM,iBAAmC;AAAA,EAC/C,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,QAAQ,cAAc,MAAM,KAAK,EAC7C;AAAA,MACA,CAAC,CAAC,IAAI,MACL,eAAe,MAAM,MAAM,IAAI,KAC/B,CAAC,UAAU,cAAc,MAAM,MAAM,IAAI,GAAG,eAAe,MAAM,MAAM,IAAI,CAAC;AAAA,IAE7E,EAAA,IAAI,CAAC,CAAC,UAAU,MAAM,MAAM,uBAAuB,mBAAmB,EAAE,UAAU,OAAA,CAAQ,CAAC;AAAA,EAAA;AAE/F;"}
|
|
@@ -28,7 +28,7 @@ class UpdateColumnDefinitionModificationHandler {
|
|
|
28
28
|
const hasNewCollation = newColumn.collation !== oldColumn.collation;
|
|
29
29
|
const columnNameWrapped = dbHelpers.wrapIdentifier(oldColumn.columnName);
|
|
30
30
|
const isChangedToArray = !oldColumn.list && newColumn.list;
|
|
31
|
-
const usingCast =
|
|
31
|
+
const usingCast = isChangedToArray ? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? "NULL" : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END` : `${columnNameWrapped}::${columnType}`;
|
|
32
32
|
const seedExpression = columnUtils$1.formatSeedExpression({
|
|
33
33
|
model: this.schema.model,
|
|
34
34
|
entity,
|
package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateColumnDefinitionModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast = (isChangedToArray ? `ARRAY[${columnNameWrapped}]` : columnNameWrapped) + `::${columnType}`\n\n\t\tconst seedExpression = formatSeedExpression({\n\t\t\tmodel: this.schema.model,\n\t\t\tentity,\n\t\t\tcolumnType,\n\t\t\tfillValue: this.data.fillValue,\n\t\t\tcopyValue: this.data.copyValue,\n\t\t})\n\t\tconst hasSeed = seedExpression !== null\n\t\tconst migrateWithUsing = hasSeed && this.data.valueMigrationStrategy === 'using'\n\t\tconst migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'\n\n\t\tbuilder.alterColumn(entity.tableName, oldColumn.columnName, {\n\t\t\tcollation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,\n\t\t\ttype: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,\n\t\t\tnotNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,\n\t\t\tusing: (() => {\n\t\t\t\tif (hasNewSequence) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`\n\t\t\t\t}\n\t\t\t\tif (migrateWithUsing) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, ${seedExpression})`\n\t\t\t\t}\n\n\t\t\t\tif (hasNewType) {\n\t\t\t\t\treturn usingCast\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t})(),\n\t\t\tsequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),\n\t\t})\n\n\t\tif (migrateWithUpdate) {\n\t\t\tfillSeed({\n\t\t\t\tbuilder,\n\t\t\t\ttype: 'updating',\n\t\t\t\tentity,\n\t\t\t\tcolumnName: oldColumn.columnName,\n\t\t\t\tnullable: newColumn.nullable,\n\t\t\t\tseedExpression,\n\t\t\t})\n\t\t}\n\n\t\tconst seqAlter = []\n\t\tif (oldColumn.sequence && newColumn.sequence) {\n\t\t\tif (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {\n\t\t\t\tseqAlter.push(`SET GENERATED ${newColumn.sequence.precedence}`)\n\t\t\t}\n\t\t\tif (oldColumn.sequence.start !== newColumn.sequence.start && typeof newColumn.sequence.start == 'number') {\n\t\t\t\tseqAlter.push(`SET START WITH ${newColumn.sequence.start}`)\n\t\t\t}\n\t\t\tif (newColumn.sequence.restart) {\n\t\t\t\tseqAlter.push('RESTART')\n\t\t\t}\n\t\t}\n\t\tif (seqAlter.length > 0) {\n\t\t\tbuilder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} ALTER ${wrapIdentifier(oldColumn.columnName)} ${seqAlter.join(' ')}`)\n\t\t}\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(\n\t\t\t\tthis.data.entityName,\n\t\t\t\tupdateField<Model.AnyColumn>(this.data.fieldName, ({ field }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...this.data.definition,\n\t\t\t\t\t\tname: field.name,\n\t\t\t\t\t\tcolumnName: field.columnName,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst current = this.schema.model.entities[this.data.entityName].fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst changingToNotNull = current.nullable && !this.data.definition.nullable\n\t\tconst failureWarning = changingToNotNull ? 'Changing to not-null may fail in runtime.' : undefined\n\n\t\treturn {\n\t\t\tmessage: `Update column definition of field ${this.data.entityName}.${this.data.fieldName}`,\n\t\t\tfailureWarning,\n\t\t}\n\t}\n}\n\ntype SequenceDefinitionAlter =\n\t& Model.AnyColumn['sequence']\n\t& {\n\t\trestart?: boolean\n\t}\n\ntype ColumnDefinitionAlter =\n\t& Omit<Model.AnyColumn, 'sequence' | 'columnName' | 'name'>\n\t& {\n\t\tsequence?: SequenceDefinitionAlter\n\t}\n\nexport interface UpdateColumnDefinitionModificationData {\n\tentityName: string\n\tfieldName: string\n\tdefinition: ColumnDefinitionAlter\n\tfillValue?: JSONValue\n\tcopyValue?: string\n\tvalueMigrationStrategy?: 'using' | 'update'\n}\n\nexport const updateColumnDefinitionModification = createModificationType({\n\tid: 'updateColumnDefinition',\n\thandler: UpdateColumnDefinitionModificationHandler,\n})\n\nexport class UpdateColumnDefinitionDiffer implements Differ<UpdateColumnDefinitionModificationData> {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn updateColumns(originalSchema, updatedSchema, ({ originalColumn, updatedColumn, updatedEntity }) => {\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...updatedDefinition\n\t\t\t} = updatedColumn\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...originalDefinition\n\t\t\t} = originalColumn\n\t\t\tif (deepEqual(updatedDefinition, originalDefinition)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\n\t\t\treturn updateColumnDefinitionModification.createModification({\n\t\t\t\tentityName: updatedEntity.name,\n\t\t\t\tfieldName: updatedColumn.name,\n\t\t\t\tdefinition: updatedDefinition,\n\t\t\t})\n\t\t})\n\t}\n}\n"],"names":["getColumnSqlType","wrapIdentifier","formatSeedExpression","escapeValue","fillSeed","updateModel","updateEntity","updateField","createModificationType","updateColumns"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UpdateColumnDefinitionModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/columns/UpdateColumnDefinitionModification.ts"],"sourcesContent":["import { escapeValue, MigrationBuilder } from '@contember/database-migrations'\nimport { JSONValue, Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateField, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { updateColumns } from '../utils/diffUtils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getColumnSqlType } from '../utils/columnUtils'\nimport { fillSeed, formatSeedExpression } from './columnUtils'\n\nexport class UpdateColumnDefinitionModificationHandler implements ModificationHandler<UpdateColumnDefinitionModificationData> {\n\tconstructor(private readonly data: UpdateColumnDefinitionModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view) {\n\t\t\treturn\n\t\t}\n\t\tconst oldColumn = entity.fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst newColumn = this.data.definition\n\n\t\tconst hasNewSequence = !oldColumn.sequence && newColumn.sequence\n\t\tconst oldColumnType = getColumnSqlType(oldColumn)\n\t\tconst columnType = getColumnSqlType(newColumn)\n\t\tconst hasNewType = columnType !== oldColumnType\n\t\tconst hasNullableChanged = oldColumn.nullable !== newColumn.nullable\n\t\tconst hasNewCollation = newColumn.collation !== oldColumn.collation\n\n\t\tconst columnNameWrapped = wrapIdentifier(oldColumn.columnName)\n\t\tconst isChangedToArray = !oldColumn.list && newColumn.list\n\t\tconst usingCast = isChangedToArray\n\t\t\t? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? 'NULL' : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END`\n\t\t\t: `${columnNameWrapped}::${columnType}`\n\n\t\tconst seedExpression = formatSeedExpression({\n\t\t\tmodel: this.schema.model,\n\t\t\tentity,\n\t\t\tcolumnType,\n\t\t\tfillValue: this.data.fillValue,\n\t\t\tcopyValue: this.data.copyValue,\n\t\t})\n\t\tconst hasSeed = seedExpression !== null\n\t\tconst migrateWithUsing = hasSeed && this.data.valueMigrationStrategy === 'using'\n\t\tconst migrateWithUpdate = hasSeed && this.data.valueMigrationStrategy !== 'using'\n\n\t\tbuilder.alterColumn(entity.tableName, oldColumn.columnName, {\n\t\t\tcollation: hasNewCollation ? wrapIdentifier(newColumn.collation || 'default') : undefined,\n\t\t\ttype: hasNewCollation || hasNewSequence || hasNewType || migrateWithUsing ? columnType : undefined,\n\t\t\tnotNull: hasNullableChanged && (!migrateWithUpdate || newColumn.nullable) ? !newColumn.nullable : undefined,\n\t\t\tusing: (() => {\n\t\t\t\tif (hasNewSequence) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, nextval(PG_GET_SERIAL_SEQUENCE(${escapeValue(entity.tableName)}, ${escapeValue(oldColumn.columnName)})))`\n\t\t\t\t}\n\t\t\t\tif (migrateWithUsing) {\n\t\t\t\t\treturn `COALESCE(${usingCast}, ${seedExpression})`\n\t\t\t\t}\n\n\t\t\t\tif (hasNewType) {\n\t\t\t\t\treturn usingCast\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t})(),\n\t\t\tsequenceGenerated: oldColumn.sequence && !newColumn.sequence ? false : (!oldColumn.sequence ? newColumn.sequence : undefined),\n\t\t})\n\n\t\tif (migrateWithUpdate) {\n\t\t\tfillSeed({\n\t\t\t\tbuilder,\n\t\t\t\ttype: 'updating',\n\t\t\t\tentity,\n\t\t\t\tcolumnName: oldColumn.columnName,\n\t\t\t\tnullable: newColumn.nullable,\n\t\t\t\tseedExpression,\n\t\t\t})\n\t\t}\n\n\t\tconst seqAlter = []\n\t\tif (oldColumn.sequence && newColumn.sequence) {\n\t\t\tif (oldColumn.sequence.precedence !== newColumn.sequence.precedence) {\n\t\t\t\tseqAlter.push(`SET GENERATED ${newColumn.sequence.precedence}`)\n\t\t\t}\n\t\t\tif (oldColumn.sequence.start !== newColumn.sequence.start && typeof newColumn.sequence.start == 'number') {\n\t\t\t\tseqAlter.push(`SET START WITH ${newColumn.sequence.start}`)\n\t\t\t}\n\t\t\tif (newColumn.sequence.restart) {\n\t\t\t\tseqAlter.push('RESTART')\n\t\t\t}\n\t\t}\n\t\tif (seqAlter.length > 0) {\n\t\t\tbuilder.sql(`ALTER TABLE ${wrapIdentifier(entity.tableName)} ALTER ${wrapIdentifier(oldColumn.columnName)} ${seqAlter.join(' ')}`)\n\t\t}\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(\n\t\t\t\tthis.data.entityName,\n\t\t\t\tupdateField<Model.AnyColumn>(this.data.fieldName, ({ field }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...this.data.definition,\n\t\t\t\t\t\tname: field.name,\n\t\t\t\t\t\tcolumnName: field.columnName,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst current = this.schema.model.entities[this.data.entityName].fields[this.data.fieldName] as Model.AnyColumn\n\t\tconst changingToNotNull = current.nullable && !this.data.definition.nullable\n\t\tconst failureWarning = changingToNotNull ? 'Changing to not-null may fail in runtime.' : undefined\n\n\t\treturn {\n\t\t\tmessage: `Update column definition of field ${this.data.entityName}.${this.data.fieldName}`,\n\t\t\tfailureWarning,\n\t\t}\n\t}\n}\n\ntype SequenceDefinitionAlter =\n\t& Model.AnyColumn['sequence']\n\t& {\n\t\trestart?: boolean\n\t}\n\ntype ColumnDefinitionAlter =\n\t& Omit<Model.AnyColumn, 'sequence' | 'columnName' | 'name'>\n\t& {\n\t\tsequence?: SequenceDefinitionAlter\n\t}\n\nexport interface UpdateColumnDefinitionModificationData {\n\tentityName: string\n\tfieldName: string\n\tdefinition: ColumnDefinitionAlter\n\tfillValue?: JSONValue\n\tcopyValue?: string\n\tvalueMigrationStrategy?: 'using' | 'update'\n}\n\nexport const updateColumnDefinitionModification = createModificationType({\n\tid: 'updateColumnDefinition',\n\thandler: UpdateColumnDefinitionModificationHandler,\n})\n\nexport class UpdateColumnDefinitionDiffer implements Differ<UpdateColumnDefinitionModificationData> {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn updateColumns(originalSchema, updatedSchema, ({ originalColumn, updatedColumn, updatedEntity }) => {\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...updatedDefinition\n\t\t\t} = updatedColumn\n\t\t\tconst {\n\t\t\t\tname: {},\n\t\t\t\tcolumnName: {},\n\t\t\t\t...originalDefinition\n\t\t\t} = originalColumn\n\t\t\tif (deepEqual(updatedDefinition, originalDefinition)) {\n\t\t\t\treturn undefined\n\t\t\t}\n\n\t\t\treturn updateColumnDefinitionModification.createModification({\n\t\t\t\tentityName: updatedEntity.name,\n\t\t\t\tfieldName: updatedColumn.name,\n\t\t\t\tdefinition: updatedDefinition,\n\t\t\t})\n\t\t})\n\t}\n}\n"],"names":["getColumnSqlType","wrapIdentifier","formatSeedExpression","escapeValue","fillSeed","updateModel","updateEntity","updateField","createModificationType","updateColumns"],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ class UpdateColumnDefinitionModificationHandler {
|
|
|
26
26
|
const hasNewCollation = newColumn.collation !== oldColumn.collation;
|
|
27
27
|
const columnNameWrapped = wrapIdentifier(oldColumn.columnName);
|
|
28
28
|
const isChangedToArray = !oldColumn.list && newColumn.list;
|
|
29
|
-
const usingCast =
|
|
29
|
+
const usingCast = isChangedToArray ? `CASE WHEN ${columnNameWrapped} IS NULL THEN ${newColumn.nullable ? "NULL" : `ARRAY[]::${columnType}`} ELSE ARRAY[${columnNameWrapped}]::${columnType} END` : `${columnNameWrapped}::${columnType}`;
|
|
30
30
|
const seedExpression = formatSeedExpression({
|
|
31
31
|
model: this.schema.model,
|
|
32
32
|
entity,
|