rake-db 2.1.0 → 2.1.2
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 -2
- package/dist/index.esm.js +142 -54
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +141 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/migration/changeTable.test.ts +169 -2
- package/src/migration/changeTable.ts +141 -13
- package/src/migration/migration.test.ts +1 -1
- package/src/migration/migrationUtils.ts +3 -2
|
@@ -356,6 +356,7 @@ describe('changeTable', () => {
|
|
|
356
356
|
changeDefault: t.change(t.default('from'), t.default(t.raw("'to'"))),
|
|
357
357
|
changeNull: t.change(t.nonNullable(), t.nullable()),
|
|
358
358
|
changeComment: t.change(t.comment('comment 1'), t.comment('comment 2')),
|
|
359
|
+
changeCompression: t.change(t.text(), t.text().compression('value')),
|
|
359
360
|
}));
|
|
360
361
|
};
|
|
361
362
|
|
|
@@ -367,7 +368,8 @@ describe('changeTable', () => {
|
|
|
367
368
|
ALTER COLUMN "changeTypeUsing" TYPE text USING b::text,
|
|
368
369
|
ALTER COLUMN "changeCollate" TYPE text COLLATE 'fr_FR',
|
|
369
370
|
ALTER COLUMN "changeDefault" SET DEFAULT 'to',
|
|
370
|
-
ALTER COLUMN "changeNull" DROP NOT NULL
|
|
371
|
+
ALTER COLUMN "changeNull" DROP NOT NULL,
|
|
372
|
+
ALTER COLUMN "changeCompression" SET COMPRESSION value
|
|
371
373
|
`,
|
|
372
374
|
`COMMENT ON COLUMN "table"."changeComment" IS 'comment 2'`,
|
|
373
375
|
]);
|
|
@@ -382,12 +384,177 @@ describe('changeTable', () => {
|
|
|
382
384
|
ALTER COLUMN "changeTypeUsing" TYPE integer USING b::int,
|
|
383
385
|
ALTER COLUMN "changeCollate" TYPE text COLLATE 'de_DE',
|
|
384
386
|
ALTER COLUMN "changeDefault" SET DEFAULT 'from',
|
|
385
|
-
ALTER COLUMN "changeNull" SET NOT NULL
|
|
387
|
+
ALTER COLUMN "changeNull" SET NOT NULL,
|
|
388
|
+
ALTER COLUMN "changeCompression" SET COMPRESSION DEFAULT
|
|
386
389
|
`,
|
|
387
390
|
`COMMENT ON COLUMN "table"."changeComment" IS 'comment 1'`,
|
|
388
391
|
]);
|
|
389
392
|
});
|
|
390
393
|
|
|
394
|
+
it('should change column foreign key', async () => {
|
|
395
|
+
const fn = () => {
|
|
396
|
+
return db.changeTable('table', (t) => ({
|
|
397
|
+
addFkey: t.change(
|
|
398
|
+
t.integer(),
|
|
399
|
+
t.integer().foreignKey('otherTable', 'foreignId'),
|
|
400
|
+
),
|
|
401
|
+
addFkeyWithOptions: t.change(
|
|
402
|
+
t.integer(),
|
|
403
|
+
t.integer().foreignKey('otherTable', 'foreignId', {
|
|
404
|
+
name: 'foreignKeyName',
|
|
405
|
+
match: 'FULL',
|
|
406
|
+
onUpdate: 'SET NULL',
|
|
407
|
+
onDelete: 'CASCADE',
|
|
408
|
+
}),
|
|
409
|
+
),
|
|
410
|
+
removeFkey: t.change(
|
|
411
|
+
t.integer().foreignKey('otherTable', 'foreignId'),
|
|
412
|
+
t.integer(),
|
|
413
|
+
),
|
|
414
|
+
removeFkeyWithOptions: t.change(
|
|
415
|
+
t.integer().foreignKey('otherTable', 'foreignId', {
|
|
416
|
+
name: 'foreignKeyName',
|
|
417
|
+
match: 'FULL',
|
|
418
|
+
onUpdate: 'SET NULL',
|
|
419
|
+
onDelete: 'CASCADE',
|
|
420
|
+
}),
|
|
421
|
+
t.integer(),
|
|
422
|
+
),
|
|
423
|
+
changeForeignKey: t.change(
|
|
424
|
+
t.integer().foreignKey('a', 'aId', {
|
|
425
|
+
name: 'fromFkeyName',
|
|
426
|
+
match: 'PARTIAL',
|
|
427
|
+
onUpdate: 'RESTRICT',
|
|
428
|
+
onDelete: 'SET DEFAULT',
|
|
429
|
+
}),
|
|
430
|
+
t.integer().foreignKey('b', 'bId', {
|
|
431
|
+
name: 'toFkeyName',
|
|
432
|
+
match: 'FULL',
|
|
433
|
+
onUpdate: 'NO ACTION',
|
|
434
|
+
onDelete: 'CASCADE',
|
|
435
|
+
}),
|
|
436
|
+
),
|
|
437
|
+
}));
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
await fn();
|
|
441
|
+
expectSql(`
|
|
442
|
+
ALTER TABLE "table"
|
|
443
|
+
DROP CONSTRAINT "table_removeFkey_fkey",
|
|
444
|
+
DROP CONSTRAINT "foreignKeyName",
|
|
445
|
+
DROP CONSTRAINT "fromFkeyName",
|
|
446
|
+
ADD CONSTRAINT "table_addFkey_fkey" FOREIGN KEY ("addFkey") REFERENCES "otherTable"("foreignId"),
|
|
447
|
+
ADD CONSTRAINT "foreignKeyName" FOREIGN KEY ("addFkeyWithOptions") REFERENCES "otherTable"("foreignId") MATCH FULL ON DELETE CASCADE ON UPDATE SET NULL,
|
|
448
|
+
ADD CONSTRAINT "toFkeyName" FOREIGN KEY ("changeForeignKey") REFERENCES "b"("bId") MATCH FULL ON DELETE CASCADE ON UPDATE NO ACTION
|
|
449
|
+
`);
|
|
450
|
+
|
|
451
|
+
queryMock.mockClear();
|
|
452
|
+
db.up = false;
|
|
453
|
+
await fn();
|
|
454
|
+
expectSql(`
|
|
455
|
+
ALTER TABLE "table"
|
|
456
|
+
DROP CONSTRAINT "table_addFkey_fkey",
|
|
457
|
+
DROP CONSTRAINT "foreignKeyName",
|
|
458
|
+
DROP CONSTRAINT "toFkeyName",
|
|
459
|
+
ADD CONSTRAINT "table_removeFkey_fkey" FOREIGN KEY ("removeFkey") REFERENCES "otherTable"("foreignId"),
|
|
460
|
+
ADD CONSTRAINT "foreignKeyName" FOREIGN KEY ("removeFkeyWithOptions") REFERENCES "otherTable"("foreignId") MATCH FULL ON DELETE CASCADE ON UPDATE SET NULL,
|
|
461
|
+
ADD CONSTRAINT "fromFkeyName" FOREIGN KEY ("changeForeignKey") REFERENCES "a"("aId") MATCH PARTIAL ON DELETE SET DEFAULT ON UPDATE RESTRICT
|
|
462
|
+
`);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
it('should change index', async () => {
|
|
466
|
+
const fn = () => {
|
|
467
|
+
return db.changeTable('table', (t) => ({
|
|
468
|
+
addIndex: t.change(t.integer(), t.integer().index()),
|
|
469
|
+
addIndexWithOptions: t.change(
|
|
470
|
+
t.integer(),
|
|
471
|
+
t.integer().index({
|
|
472
|
+
expression: 'expression',
|
|
473
|
+
collate: 'collate',
|
|
474
|
+
operator: 'operator',
|
|
475
|
+
order: 'order',
|
|
476
|
+
unique: true,
|
|
477
|
+
using: 'using',
|
|
478
|
+
include: ['a', 'b'],
|
|
479
|
+
with: 'with',
|
|
480
|
+
tablespace: 'tablespace',
|
|
481
|
+
where: 'where',
|
|
482
|
+
dropMode: 'CASCADE',
|
|
483
|
+
}),
|
|
484
|
+
),
|
|
485
|
+
removeIndex: t.change(t.integer().index(), t.integer()),
|
|
486
|
+
removeIndexWithOptions: t.change(
|
|
487
|
+
t.integer().index({
|
|
488
|
+
expression: 'expression',
|
|
489
|
+
collate: 'collate',
|
|
490
|
+
operator: 'operator',
|
|
491
|
+
order: 'order',
|
|
492
|
+
unique: true,
|
|
493
|
+
using: 'using',
|
|
494
|
+
include: ['a', 'b'],
|
|
495
|
+
with: 'with',
|
|
496
|
+
tablespace: 'tablespace',
|
|
497
|
+
where: 'where',
|
|
498
|
+
dropMode: 'CASCADE',
|
|
499
|
+
}),
|
|
500
|
+
t.integer(),
|
|
501
|
+
),
|
|
502
|
+
changeIndex: t.change(
|
|
503
|
+
t.integer().index({
|
|
504
|
+
name: 'from',
|
|
505
|
+
expression: 'from',
|
|
506
|
+
collate: 'from',
|
|
507
|
+
operator: 'from',
|
|
508
|
+
order: 'from',
|
|
509
|
+
unique: false,
|
|
510
|
+
using: 'from',
|
|
511
|
+
include: ['a', 'b'],
|
|
512
|
+
with: 'from',
|
|
513
|
+
tablespace: 'from',
|
|
514
|
+
where: 'from',
|
|
515
|
+
dropMode: 'CASCADE',
|
|
516
|
+
}),
|
|
517
|
+
t.integer().index({
|
|
518
|
+
name: 'to',
|
|
519
|
+
expression: 'to',
|
|
520
|
+
collate: 'to',
|
|
521
|
+
operator: 'to',
|
|
522
|
+
order: 'to',
|
|
523
|
+
unique: true,
|
|
524
|
+
using: 'to',
|
|
525
|
+
include: ['c', 'd'],
|
|
526
|
+
with: 'to',
|
|
527
|
+
tablespace: 'to',
|
|
528
|
+
where: 'to',
|
|
529
|
+
dropMode: 'RESTRICT',
|
|
530
|
+
}),
|
|
531
|
+
),
|
|
532
|
+
}));
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
await fn();
|
|
536
|
+
expectSql([
|
|
537
|
+
`DROP INDEX "tableRemoveIndexIndex"`,
|
|
538
|
+
`DROP INDEX "tableRemoveIndexWithOptionsIndex" CASCADE`,
|
|
539
|
+
`DROP INDEX "from" CASCADE`,
|
|
540
|
+
`CREATE INDEX "tableAddIndexIndex" ON "table" ("addIndex")`,
|
|
541
|
+
`CREATE UNIQUE INDEX "tableAddIndexWithOptionsIndex" ON "table" USING using ("addIndexWithOptions"(expression) COLLATE 'collate' operator order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
|
|
542
|
+
`CREATE UNIQUE INDEX "to" ON "table" USING to ("changeIndex"(to) COLLATE 'to' to to) INCLUDE ("c", "d") WITH (to) TABLESPACE to WHERE to`,
|
|
543
|
+
]);
|
|
544
|
+
|
|
545
|
+
queryMock.mockClear();
|
|
546
|
+
db.up = false;
|
|
547
|
+
await fn();
|
|
548
|
+
expectSql([
|
|
549
|
+
`DROP INDEX "tableAddIndexIndex"`,
|
|
550
|
+
`DROP INDEX "tableAddIndexWithOptionsIndex" CASCADE`,
|
|
551
|
+
`DROP INDEX "to" RESTRICT`,
|
|
552
|
+
`CREATE INDEX "tableRemoveIndexIndex" ON "table" ("removeIndex")`,
|
|
553
|
+
`CREATE UNIQUE INDEX "tableRemoveIndexWithOptionsIndex" ON "table" USING using ("removeIndexWithOptions"(expression) COLLATE 'collate' operator order) INCLUDE ("a", "b") WITH (with) TABLESPACE tablespace WHERE where`,
|
|
554
|
+
`CREATE INDEX "from" ON "table" USING from ("changeIndex"(from) COLLATE 'from' from from) INCLUDE ("a", "b") WITH (from) TABLESPACE from WHERE from`,
|
|
555
|
+
]);
|
|
556
|
+
});
|
|
557
|
+
|
|
391
558
|
it('should rename a column', async () => {
|
|
392
559
|
const fn = () => {
|
|
393
560
|
return db.changeTable('table', (t) => ({
|
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
getRaw,
|
|
13
13
|
isRaw,
|
|
14
14
|
raw,
|
|
15
|
+
ForeignKey,
|
|
16
|
+
newTableData,
|
|
17
|
+
SingleColumnIndexOptions,
|
|
15
18
|
} from 'pqb';
|
|
16
19
|
import {
|
|
17
20
|
ChangeTableCallback,
|
|
@@ -98,7 +101,10 @@ type ChangeArg =
|
|
|
98
101
|
| ColumnType
|
|
99
102
|
| ['default', unknown | RawExpression]
|
|
100
103
|
| ['nullable', boolean]
|
|
101
|
-
| ['comment', string | null]
|
|
104
|
+
| ['comment', string | null]
|
|
105
|
+
| ['compression', string]
|
|
106
|
+
| ['foreignKey', ForeignKey<string, string[]>]
|
|
107
|
+
| ['index', Omit<SingleColumnIndexOptions, 'column'>];
|
|
102
108
|
|
|
103
109
|
type TableChangeMethods = typeof tableChangeMethods;
|
|
104
110
|
const tableChangeMethods = {
|
|
@@ -201,12 +207,12 @@ export const changeTable = async (
|
|
|
201
207
|
}
|
|
202
208
|
}
|
|
203
209
|
|
|
204
|
-
changeTableData
|
|
205
|
-
handleTableData(state,
|
|
210
|
+
changeTableData[up ? 'drop' : 'add'].forEach((tableData) => {
|
|
211
|
+
handleTableData(state, false, tableName, tableData);
|
|
206
212
|
});
|
|
207
213
|
|
|
208
|
-
changeTableData
|
|
209
|
-
handleTableData(state,
|
|
214
|
+
changeTableData[up ? 'add' : 'drop'].forEach((tableData) => {
|
|
215
|
+
handleTableData(state, true, tableName, tableData);
|
|
210
216
|
});
|
|
211
217
|
|
|
212
218
|
if (state.alterTable.length) {
|
|
@@ -216,10 +222,8 @@ export const changeTable = async (
|
|
|
216
222
|
);
|
|
217
223
|
}
|
|
218
224
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
await migrateIndexes(state, createIndexes, up);
|
|
222
|
-
await migrateIndexes(state, dropIndexes, !up);
|
|
225
|
+
await migrateIndexes(state, state.dropIndexes, false);
|
|
226
|
+
await migrateIndexes(state, state.indexes, true);
|
|
223
227
|
await migrateComments(state, state.comments);
|
|
224
228
|
};
|
|
225
229
|
|
|
@@ -309,6 +313,79 @@ const changeActions = {
|
|
|
309
313
|
);
|
|
310
314
|
}
|
|
311
315
|
|
|
316
|
+
if (from.compression !== to.compression) {
|
|
317
|
+
state.alterTable.push(
|
|
318
|
+
`ALTER COLUMN "${key}" SET COMPRESSION ${to.compression || 'DEFAULT'}`,
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const fromFkey = from.foreignKey;
|
|
323
|
+
const toFkey = to.foreignKey;
|
|
324
|
+
if (fromFkey || toFkey) {
|
|
325
|
+
if ((fromFkey && 'fn' in fromFkey) || (toFkey && 'fn' in toFkey)) {
|
|
326
|
+
throw new Error('Callback in foreignKey is not allowed in migration');
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (checkIfForeignKeysAreDifferent(fromFkey, toFkey)) {
|
|
330
|
+
if (fromFkey) {
|
|
331
|
+
const data = newTableData();
|
|
332
|
+
data.foreignKeys.push({
|
|
333
|
+
columns: [key],
|
|
334
|
+
fnOrTable: fromFkey.table,
|
|
335
|
+
foreignColumns: fromFkey.columns,
|
|
336
|
+
options: fromFkey,
|
|
337
|
+
});
|
|
338
|
+
changeTableData[up ? 'drop' : 'add'].push(data);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (toFkey) {
|
|
342
|
+
const data = newTableData();
|
|
343
|
+
data.foreignKeys.push({
|
|
344
|
+
columns: [key],
|
|
345
|
+
fnOrTable: toFkey.table,
|
|
346
|
+
foreignColumns: toFkey.columns,
|
|
347
|
+
options: toFkey,
|
|
348
|
+
});
|
|
349
|
+
changeTableData[up ? 'add' : 'drop'].push(data);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const fromIndex = from.index;
|
|
355
|
+
const toIndex = to.index;
|
|
356
|
+
if (
|
|
357
|
+
(fromIndex || toIndex) &&
|
|
358
|
+
checkIfIndexesAreDifferent(fromIndex, toIndex)
|
|
359
|
+
) {
|
|
360
|
+
if (fromIndex) {
|
|
361
|
+
const data = newTableData();
|
|
362
|
+
data.indexes.push({
|
|
363
|
+
columns: [
|
|
364
|
+
{
|
|
365
|
+
column: key,
|
|
366
|
+
...fromIndex,
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
options: fromIndex,
|
|
370
|
+
});
|
|
371
|
+
changeTableData[up ? 'drop' : 'add'].push(data);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (toIndex) {
|
|
375
|
+
const data = newTableData();
|
|
376
|
+
data.indexes.push({
|
|
377
|
+
columns: [
|
|
378
|
+
{
|
|
379
|
+
column: key,
|
|
380
|
+
...toIndex,
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
options: toIndex,
|
|
384
|
+
});
|
|
385
|
+
changeTableData[up ? 'add' : 'drop'].push(data);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
312
389
|
if (from.comment !== to.comment) {
|
|
313
390
|
state.comments.push({ column: key, comment: to.comment || null });
|
|
314
391
|
}
|
|
@@ -320,15 +397,60 @@ const changeActions = {
|
|
|
320
397
|
},
|
|
321
398
|
};
|
|
322
399
|
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
400
|
+
const checkIfForeignKeysAreDifferent = (
|
|
401
|
+
from?: ForeignKey<string, string[]> & { table: string },
|
|
402
|
+
to?: ForeignKey<string, string[]> & { table: string },
|
|
403
|
+
) => {
|
|
404
|
+
return (
|
|
405
|
+
!from ||
|
|
406
|
+
!to ||
|
|
407
|
+
from.name !== to.name ||
|
|
408
|
+
from.match !== to.match ||
|
|
409
|
+
from.onUpdate !== to.onUpdate ||
|
|
410
|
+
from.onDelete !== to.onDelete ||
|
|
411
|
+
from.dropMode !== to.dropMode ||
|
|
412
|
+
from.table !== to.table ||
|
|
413
|
+
from.columns.join(',') !== to.columns.join(',')
|
|
414
|
+
);
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
const checkIfIndexesAreDifferent = (
|
|
418
|
+
from?: Omit<SingleColumnIndexOptions, 'column'>,
|
|
419
|
+
to?: Omit<SingleColumnIndexOptions, 'column'>,
|
|
420
|
+
) => {
|
|
421
|
+
return (
|
|
422
|
+
!from ||
|
|
423
|
+
!to ||
|
|
424
|
+
from.expression !== to.expression ||
|
|
425
|
+
from.collate !== to.collate ||
|
|
426
|
+
from.operator !== to.operator ||
|
|
427
|
+
from.order !== to.order ||
|
|
428
|
+
from.name !== to.name ||
|
|
429
|
+
from.unique !== to.unique ||
|
|
430
|
+
from.using !== to.using ||
|
|
431
|
+
from.include !== to.include ||
|
|
432
|
+
(Array.isArray(from.include) &&
|
|
433
|
+
Array.isArray(to.include) &&
|
|
434
|
+
from.include.join(',') !== to.include.join(',')) ||
|
|
435
|
+
from.with !== to.with ||
|
|
436
|
+
from.tablespace !== to.tablespace ||
|
|
437
|
+
from.where !== to.where ||
|
|
438
|
+
from.dropMode !== to.dropMode
|
|
439
|
+
);
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
type ChangeProperties = {
|
|
326
443
|
type?: string;
|
|
327
444
|
collate?: string;
|
|
328
445
|
default?: unknown | RawExpression;
|
|
329
446
|
nullable?: boolean;
|
|
330
447
|
comment?: string | null;
|
|
331
|
-
|
|
448
|
+
compression?: string;
|
|
449
|
+
foreignKey?: ForeignKey<string, string[]>;
|
|
450
|
+
index?: Omit<SingleColumnIndexOptions, 'column'>;
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const getChangeProperties = (item: ChangeArg): ChangeProperties => {
|
|
332
454
|
if (item instanceof ColumnType) {
|
|
333
455
|
return {
|
|
334
456
|
type: item.toSQL(),
|
|
@@ -336,6 +458,9 @@ const getChangeProperties = (
|
|
|
336
458
|
default: item.data.default,
|
|
337
459
|
nullable: item.isNullable,
|
|
338
460
|
comment: item.data.comment,
|
|
461
|
+
compression: item.data.compression,
|
|
462
|
+
foreignKey: item.data.foreignKey,
|
|
463
|
+
index: item.data.index,
|
|
339
464
|
};
|
|
340
465
|
} else {
|
|
341
466
|
return {
|
|
@@ -344,6 +469,9 @@ const getChangeProperties = (
|
|
|
344
469
|
default: item[0] === 'default' ? item[1] : undefined,
|
|
345
470
|
nullable: item[0] === 'nullable' ? item[1] : undefined,
|
|
346
471
|
comment: item[0] === 'comment' ? item[1] : undefined,
|
|
472
|
+
compression: item[0] === 'compression' ? item[1] : undefined,
|
|
473
|
+
foreignKey: item[0] === 'foreignKey' ? item[1] : undefined,
|
|
474
|
+
index: item[0] === 'index' ? item[1] : undefined,
|
|
347
475
|
};
|
|
348
476
|
}
|
|
349
477
|
};
|
|
@@ -283,7 +283,7 @@ describe('migration', () => {
|
|
|
283
283
|
"createdAt" timestamp NOT NULL DEFAULT now(),
|
|
284
284
|
"updatedAt" timestamp NOT NULL DEFAULT now(),
|
|
285
285
|
PRIMARY KEY ("postUuid", "commentId", "commentAuthorName"),
|
|
286
|
-
CONSTRAINT "
|
|
286
|
+
CONSTRAINT "postsComments_commentId_commentAuthorName_fkey" FOREIGN KEY ("commentId", "commentAuthorName") REFERENCES "comments"("id", "authorName")
|
|
287
287
|
)
|
|
288
288
|
`);
|
|
289
289
|
};
|
|
@@ -101,15 +101,16 @@ export const constraintToSql = (
|
|
|
101
101
|
up: boolean,
|
|
102
102
|
foreignKey: TableData['foreignKeys'][number],
|
|
103
103
|
) => {
|
|
104
|
-
const table = getForeignKeyTable(foreignKey.fnOrTable);
|
|
105
104
|
const constraintName =
|
|
106
|
-
foreignKey.options.name ||
|
|
105
|
+
foreignKey.options.name ||
|
|
106
|
+
`${tableName}_${foreignKey.columns.join('_')}_fkey`;
|
|
107
107
|
|
|
108
108
|
if (!up) {
|
|
109
109
|
const { dropMode } = foreignKey.options;
|
|
110
110
|
return `CONSTRAINT "${constraintName}"${dropMode ? ` ${dropMode}` : ''}`;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
const table = getForeignKeyTable(foreignKey.fnOrTable);
|
|
113
114
|
return `CONSTRAINT "${constraintName}" FOREIGN KEY (${joinColumns(
|
|
114
115
|
foreignKey.columns,
|
|
115
116
|
)}) ${referencesToSql(table, foreignKey.foreignColumns, foreignKey.options)}`;
|