tempest-db-js 0.7.0 → 0.9.0
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/README.md +9 -0
- package/dist/bin.cjs +1921 -12
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +31 -2
- package/dist/bin.js.map +1 -1
- package/dist/chunk-HXK6WIBP.js +5897 -0
- package/dist/chunk-HXK6WIBP.js.map +1 -0
- package/dist/{chunk-SI4CLSF7.js → chunk-ZBIHRVUS.js} +255 -11
- package/dist/chunk-ZBIHRVUS.js.map +1 -0
- package/dist/index.cjs +3156 -280
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3058 -549
- package/dist/index.d.ts +3058 -549
- package/dist/index.js +1 -1
- package/dist/migrations/index.cjs +1654 -11
- package/dist/migrations/index.cjs.map +1 -1
- package/dist/migrations/index.d.cts +30 -1
- package/dist/migrations/index.d.ts +30 -1
- package/dist/migrations/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-4AWUP7BM.js +0 -3076
- package/dist/chunk-4AWUP7BM.js.map +0 -1
- package/dist/chunk-SI4CLSF7.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { renderPortableToken, columnNamesOf, columnsOf, toAsyncDriver } from './chunk-
|
|
1
|
+
import { renderPortableToken, columnNamesOf, columnsOf, toAsyncDriver, LiteralParams, getDialect } from './chunk-HXK6WIBP.js';
|
|
2
2
|
|
|
3
3
|
// src/migrations/operations.ts
|
|
4
4
|
var IrreversibleMigration = class extends Error {
|
|
@@ -33,6 +33,10 @@ function invert(op) {
|
|
|
33
33
|
return { kind: "recreate_table", from: op.to, to: op.from };
|
|
34
34
|
case "add_constraint":
|
|
35
35
|
return { kind: "drop_constraint", table: op.table, constraint: op.constraint };
|
|
36
|
+
case "create_index":
|
|
37
|
+
return { kind: "drop_index", table: op.table, index: op.index };
|
|
38
|
+
case "drop_index":
|
|
39
|
+
return { kind: "create_index", table: op.table, index: op.index };
|
|
36
40
|
case "drop_constraint":
|
|
37
41
|
return { kind: "add_constraint", table: op.table, constraint: op.constraint };
|
|
38
42
|
case "execute":
|
|
@@ -223,7 +227,8 @@ function renderDefault(def, dialect, type) {
|
|
|
223
227
|
"sql.expr`...` binds parameters and cannot be rendered as a DEFAULT \u2014 use sql.raw()."
|
|
224
228
|
);
|
|
225
229
|
}
|
|
226
|
-
|
|
230
|
+
const rendered = renderPortableToken(expr, dialect);
|
|
231
|
+
return dialect === "sqlite" && rendered.includes("(") ? `(${rendered})` : rendered;
|
|
227
232
|
}
|
|
228
233
|
const value = def.value;
|
|
229
234
|
if (value === null) return "NULL";
|
|
@@ -271,9 +276,31 @@ function renderForeignKeyConstraint(fk, dialect) {
|
|
|
271
276
|
function tableConstraintClauses(table, dialect) {
|
|
272
277
|
return [
|
|
273
278
|
...table.uniqueConstraints.map((uc) => renderUniqueConstraint(uc, dialect)),
|
|
274
|
-
...table.foreignKeys.map((fk) => renderForeignKeyConstraint(fk, dialect))
|
|
279
|
+
...table.foreignKeys.map((fk) => renderForeignKeyConstraint(fk, dialect)),
|
|
280
|
+
...table.checks.map((ck) => renderCheckConstraint(ck, dialect))
|
|
275
281
|
];
|
|
276
282
|
}
|
|
283
|
+
function renderPredicate(node, dialect) {
|
|
284
|
+
const literals = new LiteralParams();
|
|
285
|
+
return getDialect(dialect).renderConditionLiteral(node, literals);
|
|
286
|
+
}
|
|
287
|
+
function renderCheckConstraint(ck, dialect) {
|
|
288
|
+
return `CONSTRAINT ${quoteId(ck.name, dialect)} CHECK (${renderPredicate(ck.expression, dialect)})`;
|
|
289
|
+
}
|
|
290
|
+
function renderCreateIndex(table, ix, dialect) {
|
|
291
|
+
if (ix.where && dialect === "mysql") {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`MySQL has no partial index; ${ix.name} on ${table} declares a WHERE predicate.`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
const unique = ix.unique ? "UNIQUE " : "";
|
|
297
|
+
const cols = ix.columns.map((c) => quoteId(c, dialect)).join(", ");
|
|
298
|
+
const where = ix.where ? ` WHERE ${renderPredicate(ix.where, dialect)}` : "";
|
|
299
|
+
return `CREATE ${unique}INDEX ${quoteId(ix.name, dialect)} ON ${quoteId(table, dialect)} (${cols})${where}`;
|
|
300
|
+
}
|
|
301
|
+
function renderDropIndex(table, ix, dialect) {
|
|
302
|
+
return dialect === "mysql" ? `DROP INDEX ${quoteId(ix.name, dialect)} ON ${quoteId(table, dialect)}` : `DROP INDEX ${quoteId(ix.name, dialect)}`;
|
|
303
|
+
}
|
|
277
304
|
function renderColumnDef(col, dialect) {
|
|
278
305
|
let sql = `${quoteId(col.name, dialect)} ${renderColumnType(col.type, dialect)}`;
|
|
279
306
|
if (col.notNull) sql += " NOT NULL";
|
|
@@ -326,7 +353,10 @@ function renderCreateTable(table, dialect) {
|
|
|
326
353
|
...typeStmts,
|
|
327
354
|
`CREATE TABLE ${quoteId(table.name, dialect)} (
|
|
328
355
|
${cols.join(",\n ")}
|
|
329
|
-
)
|
|
356
|
+
)`,
|
|
357
|
+
// Indexes are separate statements, not table clauses — which is also why a
|
|
358
|
+
// SQLite table rebuild has to recreate them.
|
|
359
|
+
...table.indexes.map((ix) => renderCreateIndex(table.name, ix, dialect))
|
|
330
360
|
];
|
|
331
361
|
}
|
|
332
362
|
function renderOperation(op, dialect) {
|
|
@@ -359,6 +389,10 @@ function renderOperation(op, dialect) {
|
|
|
359
389
|
return renderAddConstraint(op.table, op.constraint, dialect);
|
|
360
390
|
case "drop_constraint":
|
|
361
391
|
return renderDropConstraint(op.table, op.constraint, dialect);
|
|
392
|
+
case "create_index":
|
|
393
|
+
return [renderCreateIndex(op.table, op.index, dialect)];
|
|
394
|
+
case "drop_index":
|
|
395
|
+
return [renderDropIndex(op.table, op.index, dialect)];
|
|
362
396
|
case "execute":
|
|
363
397
|
return [op.up];
|
|
364
398
|
}
|
|
@@ -369,7 +403,7 @@ function renderAddConstraint(table, constraint, dialect) {
|
|
|
369
403
|
`add_constraint on SQLite needs a table-rebuild (recreate_table); constraint ${constraint.constraint.name} on ${table}`
|
|
370
404
|
);
|
|
371
405
|
}
|
|
372
|
-
const clause = constraint.type === "unique" ? renderUniqueConstraint(constraint.constraint, dialect) : renderForeignKeyConstraint(constraint.constraint, dialect);
|
|
406
|
+
const clause = constraint.type === "unique" ? renderUniqueConstraint(constraint.constraint, dialect) : constraint.type === "check" ? renderCheckConstraint(constraint.constraint, dialect) : renderForeignKeyConstraint(constraint.constraint, dialect);
|
|
373
407
|
return [`ALTER TABLE ${quoteId(table, dialect)} ADD ${clause}`];
|
|
374
408
|
}
|
|
375
409
|
function renderDropConstraint(table, constraint, dialect) {
|
|
@@ -406,6 +440,10 @@ function renderSqliteRebuild(from, to) {
|
|
|
406
440
|
common.length > 0 ? `INSERT INTO ${quoteId(tmp, "sqlite")} (${commonSql}) SELECT ${commonSql} FROM ${quoteId(from.name, "sqlite")}` : `-- no common columns to copy from ${from.name}`,
|
|
407
441
|
`DROP TABLE ${quoteId(from.name, "sqlite")}`,
|
|
408
442
|
`ALTER TABLE ${quoteId(tmp, "sqlite")} RENAME TO ${quoteId(to.name, "sqlite")}`,
|
|
443
|
+
// The rebuild dropped the old table, and its indexes with it: SQLite ties an
|
|
444
|
+
// index to the table it was created on. Recreating them is part of the
|
|
445
|
+
// rebuild, not a follow-up somebody has to remember.
|
|
446
|
+
...to.indexes.map((ix) => renderCreateIndex(to.name, ix, "sqlite")),
|
|
409
447
|
"PRAGMA foreign_keys=on"
|
|
410
448
|
];
|
|
411
449
|
}
|
|
@@ -508,8 +546,49 @@ function diffConstraints(current, target) {
|
|
|
508
546
|
ops.push(addForeignKey(table, tgt));
|
|
509
547
|
}
|
|
510
548
|
}
|
|
549
|
+
const currentCk = new Map(current.checks.map((c) => [c.name, c]));
|
|
550
|
+
const targetCk = new Map(target.checks.map((c) => [c.name, c]));
|
|
551
|
+
for (const [name, cur] of currentCk) {
|
|
552
|
+
const tgt = targetCk.get(name);
|
|
553
|
+
if (!tgt || checkSignature(cur) !== checkSignature(tgt)) {
|
|
554
|
+
ops.push({ kind: "drop_constraint", table, constraint: checkNamed(cur) });
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
for (const [name, tgt] of targetCk) {
|
|
558
|
+
const cur = currentCk.get(name);
|
|
559
|
+
if (!cur || checkSignature(cur) !== checkSignature(tgt)) {
|
|
560
|
+
ops.push({ kind: "add_constraint", table, constraint: checkNamed(tgt) });
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
const currentIx = new Map(current.indexes.map((i) => [i.name, i]));
|
|
564
|
+
const targetIx = new Map(target.indexes.map((i) => [i.name, i]));
|
|
565
|
+
for (const [name, cur] of currentIx) {
|
|
566
|
+
const tgt = targetIx.get(name);
|
|
567
|
+
if (!tgt || indexSignature(cur) !== indexSignature(tgt)) {
|
|
568
|
+
ops.push({ kind: "drop_index", table, index: cur });
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
for (const [name, tgt] of targetIx) {
|
|
572
|
+
const cur = currentIx.get(name);
|
|
573
|
+
if (!cur || indexSignature(cur) !== indexSignature(tgt)) {
|
|
574
|
+
ops.push({ kind: "create_index", table, index: tgt });
|
|
575
|
+
}
|
|
576
|
+
}
|
|
511
577
|
return ops;
|
|
512
578
|
}
|
|
579
|
+
function checkSignature(ck) {
|
|
580
|
+
return JSON.stringify(ck.expression);
|
|
581
|
+
}
|
|
582
|
+
function indexSignature(ix) {
|
|
583
|
+
return JSON.stringify({
|
|
584
|
+
columns: ix.columns,
|
|
585
|
+
unique: ix.unique,
|
|
586
|
+
where: ix.where
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
function checkNamed(ck) {
|
|
590
|
+
return { type: "check", constraint: ck };
|
|
591
|
+
}
|
|
513
592
|
function uniqueNamed(uc) {
|
|
514
593
|
return { type: "unique", constraint: uc };
|
|
515
594
|
}
|
|
@@ -624,6 +703,41 @@ function heads(migrations) {
|
|
|
624
703
|
function constraintName(prefix, table, columns) {
|
|
625
704
|
return `${prefix}_${table}_${columns.join("_")}`;
|
|
626
705
|
}
|
|
706
|
+
function renameConditionColumns(node, toColumn) {
|
|
707
|
+
const expr = (current) => {
|
|
708
|
+
switch (current.kind) {
|
|
709
|
+
case "column":
|
|
710
|
+
return { kind: "column", name: toColumn(current.name) };
|
|
711
|
+
case "fn":
|
|
712
|
+
return { ...current, args: current.args.map(expr) };
|
|
713
|
+
case "cast":
|
|
714
|
+
return { ...current, operand: expr(current.operand) };
|
|
715
|
+
default:
|
|
716
|
+
return current;
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
switch (node.kind) {
|
|
720
|
+
case "fields": {
|
|
721
|
+
const fields = {};
|
|
722
|
+
for (const [key, value] of Object.entries(node.fields)) {
|
|
723
|
+
fields[toColumn(key)] = value;
|
|
724
|
+
}
|
|
725
|
+
return { kind: "fields", fields };
|
|
726
|
+
}
|
|
727
|
+
case "and":
|
|
728
|
+
case "or":
|
|
729
|
+
return {
|
|
730
|
+
...node,
|
|
731
|
+
parts: node.parts.map((part) => renameConditionColumns(part, toColumn))
|
|
732
|
+
};
|
|
733
|
+
case "not":
|
|
734
|
+
return { kind: "not", part: renameConditionColumns(node.part, toColumn) };
|
|
735
|
+
case "compare":
|
|
736
|
+
return { ...node, left: expr(node.left), right: expr(node.right) };
|
|
737
|
+
default:
|
|
738
|
+
return node;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
627
741
|
function reflectTable(model) {
|
|
628
742
|
const names = columnNamesOf(model);
|
|
629
743
|
const toColumn = (prop) => names?.[prop] ?? prop;
|
|
@@ -645,6 +759,8 @@ function reflectTable(model) {
|
|
|
645
759
|
}
|
|
646
760
|
const uniqueConstraints = [];
|
|
647
761
|
const foreignKeys = [];
|
|
762
|
+
const checks = [];
|
|
763
|
+
const indexes = [];
|
|
648
764
|
for (const c of model.tableArgs?.() ?? []) {
|
|
649
765
|
const cols = c.columns.map(toColumn);
|
|
650
766
|
if (c.kind === "unique") {
|
|
@@ -652,6 +768,18 @@ function reflectTable(model) {
|
|
|
652
768
|
name: c.name ?? constraintName("uq", model.tablename, cols),
|
|
653
769
|
columns: cols
|
|
654
770
|
});
|
|
771
|
+
} else if (c.kind === "check") {
|
|
772
|
+
checks.push({
|
|
773
|
+
name: c.name ?? constraintName("ck", model.tablename, cols),
|
|
774
|
+
expression: renameConditionColumns(c.expression, toColumn)
|
|
775
|
+
});
|
|
776
|
+
} else if (c.kind === "index") {
|
|
777
|
+
indexes.push({
|
|
778
|
+
name: c.name ?? constraintName("ix", model.tablename, cols),
|
|
779
|
+
columns: cols,
|
|
780
|
+
unique: c.unique === true,
|
|
781
|
+
where: c.where ? renameConditionColumns(c.where, toColumn) : null
|
|
782
|
+
});
|
|
655
783
|
} else {
|
|
656
784
|
foreignKeys.push({
|
|
657
785
|
name: c.name ?? constraintName("fk", model.tablename, cols),
|
|
@@ -663,7 +791,15 @@ function reflectTable(model) {
|
|
|
663
791
|
});
|
|
664
792
|
}
|
|
665
793
|
}
|
|
666
|
-
return {
|
|
794
|
+
return {
|
|
795
|
+
name: model.tablename,
|
|
796
|
+
columns,
|
|
797
|
+
primaryKey,
|
|
798
|
+
uniqueConstraints,
|
|
799
|
+
foreignKeys,
|
|
800
|
+
checks,
|
|
801
|
+
indexes
|
|
802
|
+
};
|
|
667
803
|
}
|
|
668
804
|
function reflectSchema(models) {
|
|
669
805
|
const tables = {};
|
|
@@ -727,6 +863,8 @@ function introspectSqlite(driver) {
|
|
|
727
863
|
columns,
|
|
728
864
|
primaryKey,
|
|
729
865
|
uniqueConstraints: sqliteUniques(driver, tableName),
|
|
866
|
+
checks: [],
|
|
867
|
+
indexes: sqliteIndexes(driver, tableName),
|
|
730
868
|
foreignKeys: sqliteForeignKeys(driver, tableName)
|
|
731
869
|
};
|
|
732
870
|
}
|
|
@@ -815,6 +953,7 @@ function compareSqliteSchemas(actual, expected) {
|
|
|
815
953
|
);
|
|
816
954
|
}
|
|
817
955
|
}
|
|
956
|
+
issues.push(...indexDrift(tableName, actualTable, expectedTable));
|
|
818
957
|
}
|
|
819
958
|
for (const tableName of Object.keys(actual.tables)) {
|
|
820
959
|
if (!expected.tables[tableName]) {
|
|
@@ -865,9 +1004,58 @@ function sqliteUniqueFromPragma(table, rows) {
|
|
|
865
1004
|
if (cols.length === 0) return null;
|
|
866
1005
|
return { name: `uq_${table}_${cols.join("_")}`, columns: cols };
|
|
867
1006
|
}
|
|
1007
|
+
function indexesFromPragma(rows, columnsOfIndex) {
|
|
1008
|
+
const indexes = [];
|
|
1009
|
+
for (const idx of rows) {
|
|
1010
|
+
if (idx.origin !== "c") continue;
|
|
1011
|
+
if (idx.partial === 1) continue;
|
|
1012
|
+
const cols = [...columnsOfIndex(idx.name)].sort((a, b) => a.seqno - b.seqno).map((c) => c.name);
|
|
1013
|
+
if (cols.length === 0) continue;
|
|
1014
|
+
indexes.push({
|
|
1015
|
+
name: idx.name,
|
|
1016
|
+
columns: cols,
|
|
1017
|
+
unique: Number(idx.unique) === 1,
|
|
1018
|
+
where: null
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
return indexes;
|
|
1022
|
+
}
|
|
1023
|
+
function sqliteIndexes(driver, table) {
|
|
1024
|
+
const rows = driver.execute(`PRAGMA index_list(${JSON.stringify(table)})`, []).rows;
|
|
1025
|
+
return indexesFromPragma(
|
|
1026
|
+
rows,
|
|
1027
|
+
(name) => driver.execute(`PRAGMA index_info(${JSON.stringify(name)})`, []).rows
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
868
1030
|
function isUniqueIndex(idx) {
|
|
869
1031
|
return Number(idx.unique) === 1 && idx.origin !== "pk";
|
|
870
1032
|
}
|
|
1033
|
+
function indexDrift(tableName, actual, expected) {
|
|
1034
|
+
const issues = [];
|
|
1035
|
+
const signature = (ix) => `${ix.columns.join(",")}${ix.unique ? " unique" : ""}`;
|
|
1036
|
+
const actualByName = new Map(actual.indexes.map((ix) => [ix.name, ix]));
|
|
1037
|
+
const expectedByName = new Map(expected.indexes.map((ix) => [ix.name, ix]));
|
|
1038
|
+
for (const [name, exp] of expectedByName) {
|
|
1039
|
+
const act = actualByName.get(name);
|
|
1040
|
+
if (!act) {
|
|
1041
|
+
issues.push(`index "${tableName}.${name}" is missing from the database`);
|
|
1042
|
+
continue;
|
|
1043
|
+
}
|
|
1044
|
+
if (signature(act) !== signature(exp)) {
|
|
1045
|
+
issues.push(
|
|
1046
|
+
`index "${tableName}.${name}" differs: model (${signature(exp)}), db (${signature(act)})`
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
for (const name of actualByName.keys()) {
|
|
1051
|
+
if (!expectedByName.has(name)) {
|
|
1052
|
+
issues.push(
|
|
1053
|
+
`index "${tableName}.${name}" exists in the database but not in the model`
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return issues;
|
|
1058
|
+
}
|
|
871
1059
|
var SQLITE_TABLES_SQL = "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name != 'tempest_db_js_migrations'";
|
|
872
1060
|
async function introspectSqliteAsync(driver) {
|
|
873
1061
|
const tablesRows = (await driver.execute(SQLITE_TABLES_SQL, [])).rows;
|
|
@@ -885,12 +1073,27 @@ async function introspectSqliteAsync(driver) {
|
|
|
885
1073
|
const unique = sqliteUniqueFromPragma(tableName, cols);
|
|
886
1074
|
if (unique) uniqueConstraints.push(unique);
|
|
887
1075
|
}
|
|
1076
|
+
const explicitIndexes = [];
|
|
1077
|
+
for (const idx of indexes) {
|
|
1078
|
+
if (idx.origin !== "c" || idx.partial === 1) continue;
|
|
1079
|
+
const cols = (await driver.execute(`PRAGMA index_info(${JSON.stringify(idx.name)})`, [])).rows;
|
|
1080
|
+
const sorted = [...cols].sort((a, b) => a.seqno - b.seqno).map((c) => c.name);
|
|
1081
|
+
if (sorted.length === 0) continue;
|
|
1082
|
+
explicitIndexes.push({
|
|
1083
|
+
name: idx.name,
|
|
1084
|
+
columns: sorted,
|
|
1085
|
+
unique: Number(idx.unique) === 1,
|
|
1086
|
+
where: null
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
888
1089
|
tables[tableName] = {
|
|
889
1090
|
name: tableName,
|
|
890
1091
|
columns,
|
|
891
1092
|
primaryKey,
|
|
892
1093
|
uniqueConstraints,
|
|
893
|
-
foreignKeys: sqliteForeignKeysFromPragma(tableName, fkRows)
|
|
1094
|
+
foreignKeys: sqliteForeignKeysFromPragma(tableName, fkRows),
|
|
1095
|
+
checks: [],
|
|
1096
|
+
indexes: explicitIndexes
|
|
894
1097
|
};
|
|
895
1098
|
}
|
|
896
1099
|
return { tables };
|
|
@@ -1016,6 +1219,8 @@ async function introspectPostgres(driver) {
|
|
|
1016
1219
|
columns,
|
|
1017
1220
|
primaryKey,
|
|
1018
1221
|
uniqueConstraints: await postgresUniques(driver, tableName),
|
|
1222
|
+
checks: [],
|
|
1223
|
+
indexes: await postgresIndexes(driver, tableName),
|
|
1019
1224
|
foreignKeys: await postgresForeignKeys(driver, tableName)
|
|
1020
1225
|
};
|
|
1021
1226
|
}
|
|
@@ -1058,6 +1263,29 @@ async function postgresUniques(driver, table) {
|
|
|
1058
1263
|
columns: r.cols ?? []
|
|
1059
1264
|
}));
|
|
1060
1265
|
}
|
|
1266
|
+
async function postgresIndexes(driver, table) {
|
|
1267
|
+
const { rows } = await driver.execute(
|
|
1268
|
+
`SELECT i.relname AS name,
|
|
1269
|
+
ix.indisunique AS is_unique,
|
|
1270
|
+
ix.indpred IS NOT NULL AS is_partial,
|
|
1271
|
+
array_to_string(array_agg(a.attname ORDER BY k.ord), ',') AS columns
|
|
1272
|
+
FROM pg_index ix
|
|
1273
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
1274
|
+
JOIN pg_class t ON t.oid = ix.indrelid
|
|
1275
|
+
JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS k(attnum, ord) ON true
|
|
1276
|
+
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum
|
|
1277
|
+
WHERE t.relname = $1
|
|
1278
|
+
AND NOT EXISTS (SELECT 1 FROM pg_constraint c WHERE c.conindid = ix.indexrelid)
|
|
1279
|
+
GROUP BY i.relname, ix.indisunique, ix.indpred`,
|
|
1280
|
+
[table]
|
|
1281
|
+
);
|
|
1282
|
+
return rows.filter((row) => !row.is_partial).map((row) => ({
|
|
1283
|
+
name: row.name,
|
|
1284
|
+
columns: row.columns.split(","),
|
|
1285
|
+
unique: row.is_unique === true,
|
|
1286
|
+
where: null
|
|
1287
|
+
}));
|
|
1288
|
+
}
|
|
1061
1289
|
function describeKind(type) {
|
|
1062
1290
|
if (type.kind !== "array") return type.kind;
|
|
1063
1291
|
return `${type.meta.element ? describeKind(type.meta.element) : "unknown"}[]`;
|
|
@@ -1108,6 +1336,7 @@ async function checkDriftPostgres(driver, models) {
|
|
|
1108
1336
|
);
|
|
1109
1337
|
}
|
|
1110
1338
|
}
|
|
1339
|
+
issues.push(...indexDrift(tableName, actualTable, expectedTable));
|
|
1111
1340
|
}
|
|
1112
1341
|
for (const tableName of Object.keys(actual.tables)) {
|
|
1113
1342
|
if (!expected.tables[tableName]) {
|
|
@@ -1526,7 +1755,22 @@ function applyOperation(schema, op) {
|
|
|
1526
1755
|
tables[op.table] = op.constraint.type === "unique" ? {
|
|
1527
1756
|
...t,
|
|
1528
1757
|
uniqueConstraints: [...t.uniqueConstraints, op.constraint.constraint]
|
|
1529
|
-
} : { ...t, foreignKeys: [...t.foreignKeys, op.constraint.constraint] };
|
|
1758
|
+
} : op.constraint.type === "check" ? { ...t, checks: [...t.checks, op.constraint.constraint] } : { ...t, foreignKeys: [...t.foreignKeys, op.constraint.constraint] };
|
|
1759
|
+
}
|
|
1760
|
+
break;
|
|
1761
|
+
}
|
|
1762
|
+
case "create_index": {
|
|
1763
|
+
const t = tables[op.table];
|
|
1764
|
+
if (t) tables[op.table] = { ...t, indexes: [...t.indexes, op.index] };
|
|
1765
|
+
break;
|
|
1766
|
+
}
|
|
1767
|
+
case "drop_index": {
|
|
1768
|
+
const t = tables[op.table];
|
|
1769
|
+
if (t) {
|
|
1770
|
+
tables[op.table] = {
|
|
1771
|
+
...t,
|
|
1772
|
+
indexes: t.indexes.filter((i) => i.name !== op.index.name)
|
|
1773
|
+
};
|
|
1530
1774
|
}
|
|
1531
1775
|
break;
|
|
1532
1776
|
}
|
|
@@ -1537,7 +1781,7 @@ function applyOperation(schema, op) {
|
|
|
1537
1781
|
tables[op.table] = op.constraint.type === "unique" ? {
|
|
1538
1782
|
...t,
|
|
1539
1783
|
uniqueConstraints: t.uniqueConstraints.filter((u) => u.name !== dropName)
|
|
1540
|
-
} : {
|
|
1784
|
+
} : op.constraint.type === "check" ? { ...t, checks: t.checks.filter((c) => c.name !== dropName) } : {
|
|
1541
1785
|
...t,
|
|
1542
1786
|
foreignKeys: t.foreignKeys.filter((f) => f.name !== dropName)
|
|
1543
1787
|
};
|
|
@@ -1682,5 +1926,5 @@ async function runMigrationCli(argv, config) {
|
|
|
1682
1926
|
}
|
|
1683
1927
|
|
|
1684
1928
|
export { AsyncMigrationRunner, CyclicMigrationGraph, IrreversibleMigration, MigrationRunner, Op, UnknownRevision, applyOperation, applyRenames, checkDrift, checkDriftAsync, checkDriftPostgres, compareSqliteSchemas, defineMigrationConfig, detectRenames, diffSchema, emptySchema, generateMigration, heads, introspectPostgres, introspectSqlite, introspectSqliteAsync, invert, invertAll, makeRevisionId, reflectSchema, reflectTable, renderColumnDef, renderColumnType, renderDefault, renderOperation, replaySchema, runMigrationCli, sqliteAffinity, topoOrder };
|
|
1685
|
-
//# sourceMappingURL=chunk-
|
|
1686
|
-
//# sourceMappingURL=chunk-
|
|
1929
|
+
//# sourceMappingURL=chunk-ZBIHRVUS.js.map
|
|
1930
|
+
//# sourceMappingURL=chunk-ZBIHRVUS.js.map
|