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.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -266,17 +266,20 @@ const getExcludeName = (table, columns) => getIndexOrExcludeName(table, columns,
|
|
|
266
266
|
const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, language) => {
|
|
267
267
|
return indexes.map((index) => {
|
|
268
268
|
const { options } = index;
|
|
269
|
+
const isDeferrableUnique = isActiveUniqueDeferrable(options.deferrable);
|
|
270
|
+
if (isDeferrableUnique && !options.unique) throw new Error("Only unique indexes can be deferrable");
|
|
269
271
|
const { columns, include, name } = getIndexOrExcludeMainOptions(tableName, index, getIndexName, snakeCase);
|
|
270
|
-
if (!up) return { text: `DROP INDEX "${name}"${options.dropMode ? ` ${options.dropMode}` : ""}` };
|
|
272
|
+
if (!up) return { text: `${isDeferrableUnique ? `ALTER TABLE ${quoteTable(schema, tableName)} DROP CONSTRAINT "${name}"` : `DROP INDEX "${name}"`}${options.dropMode ? ` ${options.dropMode}` : ""}` };
|
|
273
|
+
if (isDeferrableUnique) validateDeferrableUnique(index);
|
|
271
274
|
const values = [];
|
|
272
|
-
const sql = ["CREATE"];
|
|
273
|
-
if (options.unique) sql.push("UNIQUE");
|
|
274
|
-
sql.push(`INDEX "${name}" ON ${quoteTable(schema, tableName)}`);
|
|
275
|
+
const sql = isDeferrableUnique ? [`ALTER TABLE ${quoteTable(schema, tableName)} ADD CONSTRAINT "${name}"`, `UNIQUE${options.nullsNotDistinct ? " NULLS NOT DISTINCT" : ""}`] : ["CREATE"];
|
|
276
|
+
if (!isDeferrableUnique && options.unique) sql.push("UNIQUE");
|
|
277
|
+
if (!isDeferrableUnique) sql.push(`INDEX "${name}" ON ${quoteTable(schema, tableName)}`);
|
|
275
278
|
const u = options.using || options.tsVector && "GIN";
|
|
276
|
-
if (u) sql.push(`USING ${u}`);
|
|
279
|
+
if (!isDeferrableUnique && u) sql.push(`USING ${u}`);
|
|
277
280
|
const lang = options.tsVector && options.languageColumn ? `"${options.languageColumn}"` : options.language ? `'${options.language}'` : `'${language || "english"}'`;
|
|
278
|
-
let hasWeight = options.tsVector && columns.some((column) => !!column.weight);
|
|
279
|
-
const columnsSql = columns.map((column) => {
|
|
281
|
+
let hasWeight = !isDeferrableUnique && options.tsVector && columns.some((column) => !!column.weight);
|
|
282
|
+
const columnsSql = isDeferrableUnique ? columns.map(uniqueConstraintColumnToSql) : columns.map((column) => {
|
|
280
283
|
let sql = [
|
|
281
284
|
"expression" in column ? `(${column.expression})` : `"${column.column}"`,
|
|
282
285
|
column.collate && `COLLATE ${quoteNameFromString(schema, column.collate)}`,
|
|
@@ -298,16 +301,45 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
|
|
|
298
301
|
else columnList = columnsSql.join(", ");
|
|
299
302
|
sql.push(`(${columnList})`);
|
|
300
303
|
if (include && include.length) sql.push(`INCLUDE (${include.map((column) => `"${column}"`).join(", ")})`);
|
|
301
|
-
if (options.nullsNotDistinct) sql.push(`NULLS NOT DISTINCT`);
|
|
304
|
+
if (!isDeferrableUnique && options.nullsNotDistinct) sql.push(`NULLS NOT DISTINCT`);
|
|
302
305
|
if (options.with) sql.push(`WITH (${options.with})`);
|
|
303
|
-
if (options.tablespace) sql.push(`TABLESPACE ${options.tablespace}`);
|
|
304
|
-
if (options.where) sql.push(`WHERE ${(0, pqb_internal.isRawSQL)(options.where) ? options.where.toSQL({ values }) : options.where}`);
|
|
306
|
+
if (options.tablespace) sql.push(isDeferrableUnique ? `USING INDEX TABLESPACE ${options.tablespace}` : `TABLESPACE ${options.tablespace}`);
|
|
307
|
+
if (!isDeferrableUnique && options.where) sql.push(`WHERE ${(0, pqb_internal.isRawSQL)(options.where) ? options.where.toSQL({ values }) : options.where}`);
|
|
308
|
+
if (isDeferrableUnique) sql.push(`DEFERRABLE INITIALLY ${options.deferrable === "deferred" ? "DEFERRED" : "IMMEDIATE"}`);
|
|
305
309
|
return {
|
|
306
310
|
text: sql.join(" "),
|
|
307
311
|
values
|
|
308
312
|
};
|
|
309
313
|
});
|
|
310
314
|
};
|
|
315
|
+
const isActiveUniqueDeferrable = (deferrable) => deferrable === "immediate" || deferrable === "deferred";
|
|
316
|
+
const uniqueConstraintColumnToSql = (column) => {
|
|
317
|
+
if ("expression" in column) throw new Error("Deferrable unique constraints do not support expression indexes");
|
|
318
|
+
return `"${column.column}"`;
|
|
319
|
+
};
|
|
320
|
+
const validateDeferrableUnique = (index) => {
|
|
321
|
+
const { options } = index;
|
|
322
|
+
if (options.where) throw new Error("Deferrable unique constraints do not support partial indexes");
|
|
323
|
+
const unsupportedOption = getUnsupportedDeferrableUniqueIndexOption(options);
|
|
324
|
+
if (unsupportedOption) throw new Error(`Deferrable unique constraints do not support index option: ${unsupportedOption}`);
|
|
325
|
+
for (const column of index.columns) {
|
|
326
|
+
if ("expression" in column) throw new Error("Deferrable unique constraints do not support expression indexes");
|
|
327
|
+
const unsupportedColumnOption = getUnsupportedDeferrableUniqueColumnOption(column);
|
|
328
|
+
if (unsupportedColumnOption) throw new Error(`Deferrable unique constraints do not support index column option: ${unsupportedColumnOption}`);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
const getUnsupportedDeferrableUniqueIndexOption = (options) => {
|
|
332
|
+
if (options.using) return "using";
|
|
333
|
+
if (options.tsVector) return "tsVector";
|
|
334
|
+
if (options.language) return "language";
|
|
335
|
+
if (options.languageColumn) return "languageColumn";
|
|
336
|
+
};
|
|
337
|
+
const getUnsupportedDeferrableUniqueColumnOption = (column) => {
|
|
338
|
+
if (column.collate) return "collate";
|
|
339
|
+
if (column.opclass) return "opclass";
|
|
340
|
+
if (column.order) return "order";
|
|
341
|
+
if (column.weight) return "weight";
|
|
342
|
+
};
|
|
311
343
|
const excludesToQuery = (up, { schema, name: tableName }, excludes, snakeCase) => {
|
|
312
344
|
return excludes.map((exclude) => {
|
|
313
345
|
const { options } = exclude;
|
|
@@ -4769,6 +4801,10 @@ const indexesSql = `SELECT
|
|
|
4769
4801
|
ic.relname "name",
|
|
4770
4802
|
am.amname AS "using",
|
|
4771
4803
|
i.indisunique "unique",
|
|
4804
|
+
CASE
|
|
4805
|
+
WHEN c.condeferrable AND c.condeferred THEN 'deferred'
|
|
4806
|
+
WHEN c.condeferrable THEN 'immediate'
|
|
4807
|
+
END AS "deferrable",
|
|
4772
4808
|
(
|
|
4773
4809
|
SELECT json_agg(
|
|
4774
4810
|
(
|
|
@@ -4865,6 +4901,9 @@ JOIN pg_class t ON t.oid = i.indrelid
|
|
|
4865
4901
|
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
4866
4902
|
JOIN pg_class ic ON ic.oid = i.indexrelid
|
|
4867
4903
|
JOIN pg_am am ON am.oid = ic.relam
|
|
4904
|
+
LEFT JOIN pg_constraint c
|
|
4905
|
+
ON c.conindid = ic.oid
|
|
4906
|
+
AND c.contype = 'u'
|
|
4868
4907
|
LEFT JOIN pg_catalog.pg_class tc ON (ic.reltoastrelid = tc.oid)
|
|
4869
4908
|
WHERE ${filterSchema("n.nspname")}
|
|
4870
4909
|
AND NOT i.indisprimary
|
|
@@ -5218,6 +5257,7 @@ async function introspectDbSchema(db, params) {
|
|
|
5218
5257
|
const excludes = [];
|
|
5219
5258
|
for (const index of raw.indexes) {
|
|
5220
5259
|
nullsToUndefined(index);
|
|
5260
|
+
if (!index.deferrable) index.deferrable = void 0;
|
|
5221
5261
|
for (const column of index.columns) {
|
|
5222
5262
|
if (!("expression" in column)) continue;
|
|
5223
5263
|
const s = column.expression;
|
|
@@ -5523,6 +5563,8 @@ const instantiateDbColumn = (ctx, data, domains, dbColumn) => {
|
|
|
5523
5563
|
const arr = new pqb_internal.ArrayColumn(ctx.columnSchemaConfig, column, ctx.columnSchemaConfig.__schemaType);
|
|
5524
5564
|
arr.data.isNullable = dbColumn.isNullable;
|
|
5525
5565
|
arr.data.arrayDims = dbColumn.arrayDims;
|
|
5566
|
+
arr.data.default = column.data.default;
|
|
5567
|
+
column.data.default = void 0;
|
|
5526
5568
|
column = arr;
|
|
5527
5569
|
}
|
|
5528
5570
|
return column;
|
|
@@ -5767,6 +5809,7 @@ const makeIndexOrExcludeOptions = (tableName, index, key) => {
|
|
|
5767
5809
|
name: index.name !== (key === "indexes" ? getIndexName : getExcludeName)(tableName, index.columns) ? index.name : void 0,
|
|
5768
5810
|
using: index.using === "btree" ? void 0 : index.using,
|
|
5769
5811
|
unique: index.unique || void 0,
|
|
5812
|
+
deferrable: index.deferrable || void 0,
|
|
5770
5813
|
include: index.include,
|
|
5771
5814
|
nullsNotDistinct: index.nullsNotDistinct || void 0,
|
|
5772
5815
|
with: index.with,
|