orchid-orm 1.32.6 → 1.32.8
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/migrations.js +166 -146
- package/dist/migrations.js.map +1 -1
- package/dist/migrations.mjs +167 -147
- package/dist/migrations.mjs.map +1 -1
- package/package.json +5 -5
package/dist/migrations.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { promptSelect, colors, getSchemaAndTableFromName, getDbTableColumnsChecks, dbColumnToAst, instantiateDbColumn, concatSchemaAndName, encodeColumnDefault, getIndexName, getConstraintName, tableToAst, getDbStructureTableData, makeDomainsMap, astToMigration, createMigrationInterface, introspectDbSchema, exhaustive, pluralize, makeStructureToAstCtx, makeFileVersion, writeMigrationFile, migrate, structureToAst, saveMigratedVersion, rakeDbCommands } from 'rake-db';
|
|
2
2
|
export * from 'rake-db';
|
|
3
3
|
import { toSnakeCase, deepCompare, toArray, columnToCode, addCode, codeToString, toCamelCase, toPascalCase, getImportPath, singleQuote, quoteObjectKey, pathToLog } from 'orchid-core';
|
|
4
|
-
import { EnumColumn, DomainColumn, RawSQL,
|
|
4
|
+
import { EnumColumn, ArrayColumn, DomainColumn, RawSQL, VirtualColumn, UnknownColumn, defaultSchemaConfig, columnsShapeToCode, pushTableDataCode, Adapter } from 'pqb';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { pathToFileURL } from 'url';
|
|
7
7
|
import fs from 'fs/promises';
|
|
@@ -396,172 +396,190 @@ const dropColumns = ({ changeTableAst: { shape } }, columnsToDrop) => {
|
|
|
396
396
|
}
|
|
397
397
|
};
|
|
398
398
|
const changeColumns = async (adapter, config, structureToAstCtx, dbStructure, domainsMap, ast, currentSchema, dbColumns, columnsToChange, compareSql, changeTableData, typeCastsCache, verifying) => {
|
|
399
|
-
var _a
|
|
399
|
+
var _a;
|
|
400
400
|
for (const [
|
|
401
401
|
key,
|
|
402
402
|
{ key: codeKey, dbName, column: codeColumn }
|
|
403
403
|
] of columnsToChange) {
|
|
404
404
|
const dbColumnStructure = dbColumns[dbName];
|
|
405
405
|
const { shape } = changeTableData.changeTableAst;
|
|
406
|
-
let changed = false;
|
|
407
406
|
const dbColumn = instantiateDbColumn(
|
|
408
407
|
structureToAstCtx,
|
|
409
408
|
dbStructure,
|
|
410
409
|
domainsMap,
|
|
411
410
|
dbColumnStructure
|
|
412
411
|
);
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
412
|
+
const action = await compareColumns(
|
|
413
|
+
adapter,
|
|
414
|
+
domainsMap,
|
|
415
|
+
ast,
|
|
416
|
+
currentSchema,
|
|
417
|
+
compareSql,
|
|
418
|
+
changeTableData,
|
|
419
|
+
typeCastsCache,
|
|
420
|
+
verifying,
|
|
421
|
+
key,
|
|
422
|
+
dbColumn,
|
|
423
|
+
codeColumn
|
|
424
|
+
);
|
|
425
|
+
if (action === "change") {
|
|
426
|
+
changeColumn(shape, key, dbColumn, codeColumn);
|
|
427
|
+
} else if (action === "recreate") {
|
|
428
|
+
changeTableData.changeTableAst.shape[key] = [
|
|
429
|
+
{
|
|
430
|
+
type: "drop",
|
|
431
|
+
item: dbColumn
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
type: "add",
|
|
435
|
+
item: codeColumn
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
} else if (action !== "recreate") {
|
|
439
|
+
const to = (_a = codeColumn.data.name) != null ? _a : codeKey;
|
|
440
|
+
if (dbName !== to) {
|
|
441
|
+
shape[config.snakeCase ? dbName === toSnakeCase(codeKey) ? codeKey : dbName : dbName] = {
|
|
442
|
+
type: "rename",
|
|
443
|
+
name: config.snakeCase ? to === toSnakeCase(codeKey) ? codeKey : to : to
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
const compareColumns = async (adapter, domainsMap, ast, currentSchema, compareSql, changeTableData, typeCastsCache, verifying, key, dbColumn, codeColumn) => {
|
|
450
|
+
var _a, _b, _c, _d;
|
|
451
|
+
const dbType = getColumnDbType(dbColumn, currentSchema);
|
|
452
|
+
const codeType = getColumnDbType(codeColumn, currentSchema);
|
|
453
|
+
if (dbColumn instanceof ArrayColumn && codeColumn instanceof ArrayColumn) {
|
|
454
|
+
dbColumn = dbColumn.data.item;
|
|
455
|
+
codeColumn = codeColumn.data.item;
|
|
456
|
+
}
|
|
457
|
+
if (dbType !== codeType) {
|
|
458
|
+
let typeCasts = typeCastsCache.value;
|
|
459
|
+
if (!typeCasts) {
|
|
460
|
+
const { rows } = await adapter.arrays(`SELECT s.typname, t.typname
|
|
419
461
|
FROM pg_cast
|
|
420
462
|
JOIN pg_type AS s ON s.oid = castsource
|
|
421
463
|
JOIN pg_type AS t ON t.oid = casttarget`);
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
typeCasts = /* @__PURE__ */ new Map();
|
|
432
|
-
for (const [type, directSet] of directTypeCasts.entries()) {
|
|
433
|
-
const set = new Set(directSet);
|
|
434
|
-
typeCasts.set(type, set);
|
|
435
|
-
for (const subtype of directSet) {
|
|
436
|
-
const subset = directTypeCasts.get(subtype);
|
|
437
|
-
if (subset) {
|
|
438
|
-
for (const type2 of subset) {
|
|
439
|
-
set.add(type2);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
464
|
+
const directTypeCasts = /* @__PURE__ */ new Map();
|
|
465
|
+
for (const [source, target] of rows) {
|
|
466
|
+
const set = directTypeCasts.get(source);
|
|
467
|
+
if (set) {
|
|
468
|
+
set.add(target);
|
|
469
|
+
} else {
|
|
470
|
+
directTypeCasts.set(source, /* @__PURE__ */ new Set([target]));
|
|
443
471
|
}
|
|
444
|
-
typeCastsCache.value = typeCasts;
|
|
445
472
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
options: [
|
|
456
|
-
`${colors.yellowBold(
|
|
457
|
-
`-/+`
|
|
458
|
-
)} recreate the column, existing data will be ${colors.red(
|
|
459
|
-
"lost"
|
|
460
|
-
)}`,
|
|
461
|
-
`write migration manually`
|
|
462
|
-
]
|
|
463
|
-
});
|
|
464
|
-
if (abort) {
|
|
465
|
-
throw new AbortSignal();
|
|
466
|
-
}
|
|
467
|
-
dbColumn.data.name = codeColumn.data.name;
|
|
468
|
-
shape[key] = [
|
|
469
|
-
{
|
|
470
|
-
type: "drop",
|
|
471
|
-
item: dbColumn
|
|
472
|
-
},
|
|
473
|
-
{
|
|
474
|
-
type: "add",
|
|
475
|
-
item: codeColumn
|
|
473
|
+
typeCasts = /* @__PURE__ */ new Map();
|
|
474
|
+
for (const [type, directSet] of directTypeCasts.entries()) {
|
|
475
|
+
const set = new Set(directSet);
|
|
476
|
+
typeCasts.set(type, set);
|
|
477
|
+
for (const subtype of directSet) {
|
|
478
|
+
const subset = directTypeCasts.get(subtype);
|
|
479
|
+
if (subset) {
|
|
480
|
+
for (const type2 of subset) {
|
|
481
|
+
set.add(type2);
|
|
476
482
|
}
|
|
477
|
-
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
changed = true;
|
|
482
|
-
}
|
|
483
|
-
const dbData = dbColumn.data;
|
|
484
|
-
const codeData = codeColumn.data;
|
|
485
|
-
if (!changed) {
|
|
486
|
-
if (!dbData.isNullable)
|
|
487
|
-
dbData.isNullable = void 0;
|
|
488
|
-
for (const key2 of ["isNullable", "comment"]) {
|
|
489
|
-
if (dbData[key2] !== codeData[key2]) {
|
|
490
|
-
changed = true;
|
|
491
|
-
break;
|
|
483
|
+
}
|
|
492
484
|
}
|
|
493
485
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
486
|
+
typeCastsCache.value = typeCasts;
|
|
487
|
+
}
|
|
488
|
+
const dbBaseType = dbColumn instanceof DomainColumn ? (_a = domainsMap[dbColumn.dataType]) == null ? void 0 : _a.dataType : dbType;
|
|
489
|
+
const codeBaseType = codeColumn instanceof DomainColumn ? (_b = domainsMap[codeColumn.dataType]) == null ? void 0 : _b.dataType : codeType;
|
|
490
|
+
if (!((_c = typeCasts.get(dbBaseType)) == null ? void 0 : _c.has(codeBaseType))) {
|
|
491
|
+
if (!(dbColumn instanceof EnumColumn) || !(codeColumn instanceof EnumColumn) || !deepCompare(dbColumn.options, codeColumn.options)) {
|
|
492
|
+
if (verifying)
|
|
493
|
+
throw new AbortSignal();
|
|
494
|
+
const tableName = concatSchemaAndName(changeTableData.changeTableAst);
|
|
495
|
+
const abort = await promptSelect({
|
|
496
|
+
message: `Cannot cast type of ${tableName}'s column ${key} from ${dbType} to ${codeType}`,
|
|
497
|
+
options: [
|
|
498
|
+
`${colors.yellowBold(
|
|
499
|
+
`-/+`
|
|
500
|
+
)} recreate the column, existing data will be ${colors.red(
|
|
501
|
+
"lost"
|
|
502
|
+
)}`,
|
|
503
|
+
`write migration manually`
|
|
504
|
+
]
|
|
505
|
+
});
|
|
506
|
+
if (abort) {
|
|
507
|
+
throw new AbortSignal();
|
|
507
508
|
}
|
|
509
|
+
dbColumn.data.name = codeColumn.data.name;
|
|
510
|
+
return "recreate";
|
|
508
511
|
}
|
|
509
512
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
513
|
+
return "change";
|
|
514
|
+
}
|
|
515
|
+
const dbData = dbColumn.data;
|
|
516
|
+
const codeData = codeColumn.data;
|
|
517
|
+
for (const key2 of ["isNullable", "comment"]) {
|
|
518
|
+
if (dbData[key2] !== codeData[key2]) {
|
|
519
|
+
return "change";
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
for (const key2 of [
|
|
523
|
+
"maxChars",
|
|
524
|
+
"collation",
|
|
525
|
+
"compression",
|
|
526
|
+
"numericPrecision",
|
|
527
|
+
"numericScale",
|
|
528
|
+
"dateTimePrecision"
|
|
529
|
+
]) {
|
|
530
|
+
if (key2 in codeData && dbData[key2] !== codeData[key2]) {
|
|
531
|
+
return "change";
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (!deepCompare(
|
|
535
|
+
dbData.identity,
|
|
536
|
+
codeData.identity ? __spreadValues$6({
|
|
537
|
+
always: false,
|
|
538
|
+
start: 1,
|
|
539
|
+
increment: 1,
|
|
540
|
+
cache: 1,
|
|
541
|
+
cycle: false
|
|
542
|
+
}, (_d = codeData.identity) != null ? _d : {}) : void 0
|
|
543
|
+
)) {
|
|
544
|
+
return "change";
|
|
545
|
+
}
|
|
546
|
+
if (dbData.default !== void 0 && dbData.default !== null && codeData.default !== void 0 && codeData.default !== null) {
|
|
547
|
+
const valuesBeforeLen = compareSql.values.length;
|
|
548
|
+
const dbDefault = encodeColumnDefault(
|
|
549
|
+
dbData.default,
|
|
550
|
+
compareSql.values,
|
|
551
|
+
dbColumn
|
|
552
|
+
);
|
|
553
|
+
const dbValues = compareSql.values.slice(valuesBeforeLen);
|
|
554
|
+
const codeDefault = encodeColumnDefault(
|
|
555
|
+
codeData.default,
|
|
556
|
+
compareSql.values,
|
|
557
|
+
codeColumn
|
|
558
|
+
);
|
|
559
|
+
const codeValues = compareSql.values.slice(valuesBeforeLen);
|
|
560
|
+
if (dbValues.length !== codeValues.length || dbValues.length && JSON.stringify(dbValues) !== JSON.stringify(codeValues)) {
|
|
561
|
+
compareSql.values.length = valuesBeforeLen;
|
|
562
|
+
return "change";
|
|
563
|
+
} else if (dbDefault !== codeDefault && dbDefault !== `(${codeDefault})`) {
|
|
564
|
+
compareSql.expressions.push({
|
|
565
|
+
inDb: dbDefault,
|
|
566
|
+
inCode: codeDefault,
|
|
567
|
+
change: () => {
|
|
568
|
+
changeColumn(
|
|
569
|
+
changeTableData.changeTableAst.shape,
|
|
570
|
+
key,
|
|
571
|
+
dbColumn,
|
|
572
|
+
codeColumn
|
|
573
|
+
);
|
|
574
|
+
if (!changeTableData.pushedAst) {
|
|
575
|
+
changeTableData.pushedAst = true;
|
|
576
|
+
ast.push(changeTableData.changeTableAst);
|
|
549
577
|
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
if (changed) {
|
|
554
|
-
changeColumn(shape, key, dbColumn, codeColumn);
|
|
555
|
-
} else {
|
|
556
|
-
const to = (_e = codeColumn.data.name) != null ? _e : codeKey;
|
|
557
|
-
if (dbName !== to) {
|
|
558
|
-
shape[config.snakeCase ? dbName === toSnakeCase(codeKey) ? codeKey : dbName : dbName] = {
|
|
559
|
-
type: "rename",
|
|
560
|
-
name: config.snakeCase ? to === toSnakeCase(codeKey) ? codeKey : to : to
|
|
561
|
-
};
|
|
562
|
-
}
|
|
578
|
+
}
|
|
579
|
+
});
|
|
563
580
|
}
|
|
564
581
|
}
|
|
582
|
+
return;
|
|
565
583
|
};
|
|
566
584
|
const changeColumn = (shape, name, dbColumn, codeColumn) => {
|
|
567
585
|
dbColumn.data.as = codeColumn.data.as = void 0;
|
|
@@ -577,6 +595,8 @@ const getColumnDbType = (column, currentSchema) => {
|
|
|
577
595
|
column.enumName
|
|
578
596
|
);
|
|
579
597
|
return column.enumName = `${schema}.${name}`;
|
|
598
|
+
} else if (column instanceof ArrayColumn) {
|
|
599
|
+
return column.data.item.dataType + "[]".repeat(column.data.arrayDims);
|
|
580
600
|
} else {
|
|
581
601
|
return column.dataType;
|
|
582
602
|
}
|
|
@@ -613,7 +633,7 @@ const processDomains = async (ast, adapter, structureToAstCtx, domainsMap, dbStr
|
|
|
613
633
|
name: domain.name,
|
|
614
634
|
typeSchema: domain.typeSchema,
|
|
615
635
|
type: domain.type,
|
|
616
|
-
|
|
636
|
+
arrayDims: domain.arrayDims,
|
|
617
637
|
default: domain.default,
|
|
618
638
|
isNullable: domain.isNullable,
|
|
619
639
|
collate: domain.collate,
|
|
@@ -694,12 +714,12 @@ const processDomains = async (ast, adapter, structureToAstCtx, domainsMap, dbStr
|
|
|
694
714
|
};
|
|
695
715
|
const makeComparableDomain = (currentSchema, schemaName, name, column) => {
|
|
696
716
|
var _a;
|
|
697
|
-
let
|
|
717
|
+
let arrayDims = 0;
|
|
698
718
|
const isNullable = (_a = column.data.isNullable) != null ? _a : false;
|
|
699
719
|
let inner = column;
|
|
700
|
-
|
|
701
|
-
inner =
|
|
702
|
-
|
|
720
|
+
while (inner instanceof ArrayColumn) {
|
|
721
|
+
inner = inner.data.item;
|
|
722
|
+
arrayDims++;
|
|
703
723
|
}
|
|
704
724
|
const fullType = getColumnDbType(inner, currentSchema);
|
|
705
725
|
const [typeSchema = "pg_catalog", type] = getSchemaAndTableFromName(fullType);
|
|
@@ -710,7 +730,7 @@ const makeComparableDomain = (currentSchema, schemaName, name, column) => {
|
|
|
710
730
|
compare: {
|
|
711
731
|
type,
|
|
712
732
|
typeSchema,
|
|
713
|
-
|
|
733
|
+
arrayDims,
|
|
714
734
|
isNullable,
|
|
715
735
|
maxChars: inner.data.maxChars,
|
|
716
736
|
numericPrecision: inner.data.numericPrecision,
|