rake-db 2.36.15 → 2.36.17
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/index.d.ts +2 -0
- package/dist/index.js +53 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -243,17 +243,20 @@ const getExcludeName = (table, columns) => getIndexOrExcludeName(table, columns,
|
|
|
243
243
|
const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, language) => {
|
|
244
244
|
return indexes.map((index) => {
|
|
245
245
|
const { options } = index;
|
|
246
|
+
const isDeferrableUnique = isActiveUniqueDeferrable(options.deferrable);
|
|
247
|
+
if (isDeferrableUnique && !options.unique) throw new Error("Only unique indexes can be deferrable");
|
|
246
248
|
const { columns, include, name } = getIndexOrExcludeMainOptions(tableName, index, getIndexName, snakeCase);
|
|
247
|
-
if (!up) return { text: `DROP INDEX "${name}"${options.dropMode ? ` ${options.dropMode}` : ""}` };
|
|
249
|
+
if (!up) return { text: `${isDeferrableUnique ? `ALTER TABLE ${quoteTable(schema, tableName)} DROP CONSTRAINT "${name}"` : `DROP INDEX "${name}"`}${options.dropMode ? ` ${options.dropMode}` : ""}` };
|
|
250
|
+
if (isDeferrableUnique) validateDeferrableUnique(index);
|
|
248
251
|
const values = [];
|
|
249
|
-
const sql = ["CREATE"];
|
|
250
|
-
if (options.unique) sql.push("UNIQUE");
|
|
251
|
-
sql.push(`INDEX "${name}" ON ${quoteTable(schema, tableName)}`);
|
|
252
|
+
const sql = isDeferrableUnique ? [`ALTER TABLE ${quoteTable(schema, tableName)} ADD CONSTRAINT "${name}"`, `UNIQUE${options.nullsNotDistinct ? " NULLS NOT DISTINCT" : ""}`] : ["CREATE"];
|
|
253
|
+
if (!isDeferrableUnique && options.unique) sql.push("UNIQUE");
|
|
254
|
+
if (!isDeferrableUnique) sql.push(`INDEX "${name}" ON ${quoteTable(schema, tableName)}`);
|
|
252
255
|
const u = options.using || options.tsVector && "GIN";
|
|
253
|
-
if (u) sql.push(`USING ${u}`);
|
|
256
|
+
if (!isDeferrableUnique && u) sql.push(`USING ${u}`);
|
|
254
257
|
const lang = options.tsVector && options.languageColumn ? `"${options.languageColumn}"` : options.language ? `'${options.language}'` : `'${language || "english"}'`;
|
|
255
|
-
let hasWeight = options.tsVector && columns.some((column) => !!column.weight);
|
|
256
|
-
const columnsSql = columns.map((column) => {
|
|
258
|
+
let hasWeight = !isDeferrableUnique && options.tsVector && columns.some((column) => !!column.weight);
|
|
259
|
+
const columnsSql = isDeferrableUnique ? columns.map(uniqueConstraintColumnToSql) : columns.map((column) => {
|
|
257
260
|
let sql = [
|
|
258
261
|
"expression" in column ? `(${column.expression})` : `"${column.column}"`,
|
|
259
262
|
column.collate && `COLLATE ${quoteNameFromString(schema, column.collate)}`,
|
|
@@ -275,16 +278,45 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
|
|
|
275
278
|
else columnList = columnsSql.join(", ");
|
|
276
279
|
sql.push(`(${columnList})`);
|
|
277
280
|
if (include && include.length) sql.push(`INCLUDE (${include.map((column) => `"${column}"`).join(", ")})`);
|
|
278
|
-
if (options.nullsNotDistinct) sql.push(`NULLS NOT DISTINCT`);
|
|
281
|
+
if (!isDeferrableUnique && options.nullsNotDistinct) sql.push(`NULLS NOT DISTINCT`);
|
|
279
282
|
if (options.with) sql.push(`WITH (${options.with})`);
|
|
280
|
-
if (options.tablespace) sql.push(`TABLESPACE ${options.tablespace}`);
|
|
281
|
-
if (options.where) sql.push(`WHERE ${isRawSQL(options.where) ? options.where.toSQL({ values }) : options.where}`);
|
|
283
|
+
if (options.tablespace) sql.push(isDeferrableUnique ? `USING INDEX TABLESPACE ${options.tablespace}` : `TABLESPACE ${options.tablespace}`);
|
|
284
|
+
if (!isDeferrableUnique && options.where) sql.push(`WHERE ${isRawSQL(options.where) ? options.where.toSQL({ values }) : options.where}`);
|
|
285
|
+
if (isDeferrableUnique) sql.push(`DEFERRABLE INITIALLY ${options.deferrable === "deferred" ? "DEFERRED" : "IMMEDIATE"}`);
|
|
282
286
|
return {
|
|
283
287
|
text: sql.join(" "),
|
|
284
288
|
values
|
|
285
289
|
};
|
|
286
290
|
});
|
|
287
291
|
};
|
|
292
|
+
const isActiveUniqueDeferrable = (deferrable) => deferrable === "immediate" || deferrable === "deferred";
|
|
293
|
+
const uniqueConstraintColumnToSql = (column) => {
|
|
294
|
+
if ("expression" in column) throw new Error("Deferrable unique constraints do not support expression indexes");
|
|
295
|
+
return `"${column.column}"`;
|
|
296
|
+
};
|
|
297
|
+
const validateDeferrableUnique = (index) => {
|
|
298
|
+
const { options } = index;
|
|
299
|
+
if (options.where) throw new Error("Deferrable unique constraints do not support partial indexes");
|
|
300
|
+
const unsupportedOption = getUnsupportedDeferrableUniqueIndexOption(options);
|
|
301
|
+
if (unsupportedOption) throw new Error(`Deferrable unique constraints do not support index option: ${unsupportedOption}`);
|
|
302
|
+
for (const column of index.columns) {
|
|
303
|
+
if ("expression" in column) throw new Error("Deferrable unique constraints do not support expression indexes");
|
|
304
|
+
const unsupportedColumnOption = getUnsupportedDeferrableUniqueColumnOption(column);
|
|
305
|
+
if (unsupportedColumnOption) throw new Error(`Deferrable unique constraints do not support index column option: ${unsupportedColumnOption}`);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
const getUnsupportedDeferrableUniqueIndexOption = (options) => {
|
|
309
|
+
if (options.using) return "using";
|
|
310
|
+
if (options.tsVector) return "tsVector";
|
|
311
|
+
if (options.language) return "language";
|
|
312
|
+
if (options.languageColumn) return "languageColumn";
|
|
313
|
+
};
|
|
314
|
+
const getUnsupportedDeferrableUniqueColumnOption = (column) => {
|
|
315
|
+
if (column.collate) return "collate";
|
|
316
|
+
if (column.opclass) return "opclass";
|
|
317
|
+
if (column.order) return "order";
|
|
318
|
+
if (column.weight) return "weight";
|
|
319
|
+
};
|
|
288
320
|
const excludesToQuery = (up, { schema, name: tableName }, excludes, snakeCase) => {
|
|
289
321
|
return excludes.map((exclude) => {
|
|
290
322
|
const { options } = exclude;
|
|
@@ -4746,6 +4778,10 @@ const indexesSql = `SELECT
|
|
|
4746
4778
|
ic.relname "name",
|
|
4747
4779
|
am.amname AS "using",
|
|
4748
4780
|
i.indisunique "unique",
|
|
4781
|
+
CASE
|
|
4782
|
+
WHEN c.condeferrable AND c.condeferred THEN 'deferred'
|
|
4783
|
+
WHEN c.condeferrable THEN 'immediate'
|
|
4784
|
+
END AS "deferrable",
|
|
4749
4785
|
(
|
|
4750
4786
|
SELECT json_agg(
|
|
4751
4787
|
(
|
|
@@ -4842,6 +4878,9 @@ JOIN pg_class t ON t.oid = i.indrelid
|
|
|
4842
4878
|
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
4843
4879
|
JOIN pg_class ic ON ic.oid = i.indexrelid
|
|
4844
4880
|
JOIN pg_am am ON am.oid = ic.relam
|
|
4881
|
+
LEFT JOIN pg_constraint c
|
|
4882
|
+
ON c.conindid = ic.oid
|
|
4883
|
+
AND c.contype = 'u'
|
|
4845
4884
|
LEFT JOIN pg_catalog.pg_class tc ON (ic.reltoastrelid = tc.oid)
|
|
4846
4885
|
WHERE ${filterSchema("n.nspname")}
|
|
4847
4886
|
AND NOT i.indisprimary
|
|
@@ -5195,6 +5234,7 @@ async function introspectDbSchema(db, params) {
|
|
|
5195
5234
|
const excludes = [];
|
|
5196
5235
|
for (const index of raw.indexes) {
|
|
5197
5236
|
nullsToUndefined(index);
|
|
5237
|
+
if (!index.deferrable) index.deferrable = void 0;
|
|
5198
5238
|
for (const column of index.columns) {
|
|
5199
5239
|
if (!("expression" in column)) continue;
|
|
5200
5240
|
const s = column.expression;
|
|
@@ -5500,6 +5540,8 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5500
5540
|
const arr = new ArrayColumn(ctx.columnSchemaConfig, column, ctx.columnSchemaConfig.__schemaType);
|
|
5501
5541
|
arr.data.isNullable = dbColumn.isNullable;
|
|
5502
5542
|
arr.data.arrayDims = dbColumn.arrayDims;
|
|
5543
|
+
arr.data.default = column.data.default;
|
|
5544
|
+
column.data.default = void 0;
|
|
5503
5545
|
column = arr;
|
|
5504
5546
|
}
|
|
5505
5547
|
return column;
|
|
@@ -5744,6 +5786,7 @@ const makeIndexOrExcludeOptions = (tableName, index, key) => {
|
|
|
5744
5786
|
name: index.name !== (key === "indexes" ? getIndexName : getExcludeName)(tableName, index.columns) ? index.name : void 0,
|
|
5745
5787
|
using: index.using === "btree" ? void 0 : index.using,
|
|
5746
5788
|
unique: index.unique || void 0,
|
|
5789
|
+
deferrable: index.deferrable || void 0,
|
|
5747
5790
|
include: index.include,
|
|
5748
5791
|
nullsNotDistinct: index.nullsNotDistinct || void 0,
|
|
5749
5792
|
with: index.with,
|