rake-db 2.1.16 → 2.1.18

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.js CHANGED
@@ -228,7 +228,7 @@ var __spreadValues$3 = (a, b) => {
228
228
  return a;
229
229
  };
230
230
  var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
231
- const columnToSql = (key, item, { values }) => {
231
+ const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
232
232
  const line = [`"${key}" ${item.toSQL()}`];
233
233
  if (item.data.compression) {
234
234
  line.push(`COMPRESSION ${item.data.compression}`);
@@ -236,7 +236,7 @@ const columnToSql = (key, item, { values }) => {
236
236
  if (item.data.collate) {
237
237
  line.push(`COLLATE ${pqb.quote(item.data.collate)}`);
238
238
  }
239
- if (item.isPrimaryKey) {
239
+ if (item.isPrimaryKey && !hasMultiplePrimaryKeys) {
240
240
  line.push("PRIMARY KEY");
241
241
  } else if (!item.isNullable) {
242
242
  line.push("NOT NULL");
@@ -488,29 +488,9 @@ const types = Object.assign(Object.create(pqb.columnTypes), {
488
488
  raw: pqb.raw
489
489
  });
490
490
  const createTable = async (migration, up, tableName, options, fn) => {
491
- var _a, _b;
492
491
  const shape = pqb.getColumnTypes(types, fn);
493
492
  const tableData = pqb.getTableData();
494
- const { noPrimaryKey } = migration.options;
495
- if (!options.noPrimaryKey && (!noPrimaryKey || noPrimaryKey !== "ignore")) {
496
- let hasPrimaryKey = !!((_b = (_a = tableData.primaryKey) == null ? void 0 : _a.columns) == null ? void 0 : _b.length);
497
- if (!hasPrimaryKey) {
498
- for (const key in shape) {
499
- if (shape[key].isPrimaryKey) {
500
- hasPrimaryKey = true;
501
- break;
502
- }
503
- }
504
- }
505
- if (!hasPrimaryKey) {
506
- const message = `Table ${tableName} has no primary key`;
507
- if (!noPrimaryKey || noPrimaryKey === "error") {
508
- throw new Error(message);
509
- } else {
510
- console.warn(message);
511
- }
512
- }
513
- }
493
+ validatePrimaryKey(migration, options, tableData, shape, tableName);
514
494
  if (!up) {
515
495
  const { dropMode } = options;
516
496
  await migration.query(
@@ -519,19 +499,23 @@ const createTable = async (migration, up, tableName, options, fn) => {
519
499
  return;
520
500
  }
521
501
  const lines = [];
502
+ applyMultiplePrimaryKeys(shape, tableData);
522
503
  const state = {
523
504
  migration,
524
505
  tableName,
525
506
  values: [],
526
507
  indexes: [],
527
- comments: []
508
+ comments: [],
509
+ tableData
528
510
  };
529
511
  for (const key in shape) {
530
512
  const item = shape[key];
531
513
  addColumnIndex(state.indexes, key, item);
532
514
  addColumnComment(state.comments, key, item);
533
- lines.push(`
534
- ${columnToSql(key, item, state)}`);
515
+ lines.push(
516
+ `
517
+ ${columnToSql(key, item, state.values, tableData.primaryKey)}`
518
+ );
535
519
  }
536
520
  if (tableData.primaryKey) {
537
521
  lines.push(`
@@ -555,6 +539,44 @@ const createTable = async (migration, up, tableName, options, fn) => {
555
539
  );
556
540
  }
557
541
  };
542
+ const validatePrimaryKey = (migration, options, tableData, shape, tableName) => {
543
+ var _a, _b;
544
+ const { noPrimaryKey } = migration.options;
545
+ if (!options.noPrimaryKey && (!noPrimaryKey || noPrimaryKey !== "ignore")) {
546
+ let hasPrimaryKey = !!((_b = (_a = tableData.primaryKey) == null ? void 0 : _a.columns) == null ? void 0 : _b.length);
547
+ if (!hasPrimaryKey) {
548
+ for (const key in shape) {
549
+ if (shape[key].isPrimaryKey) {
550
+ hasPrimaryKey = true;
551
+ break;
552
+ }
553
+ }
554
+ }
555
+ if (!hasPrimaryKey) {
556
+ const message = `Table ${tableName} has no primary key`;
557
+ if (!noPrimaryKey || noPrimaryKey === "error") {
558
+ throw new Error(message);
559
+ } else {
560
+ console.warn(message);
561
+ }
562
+ }
563
+ }
564
+ };
565
+ const applyMultiplePrimaryKeys = (shape, tableData) => {
566
+ const columns = [];
567
+ for (const key in shape) {
568
+ if (shape[key].isPrimaryKey) {
569
+ columns.push(key);
570
+ }
571
+ }
572
+ if (columns.length <= 1)
573
+ return;
574
+ if (!tableData.primaryKey) {
575
+ tableData.primaryKey = { columns };
576
+ } else {
577
+ tableData.primaryKey.columns.unshift(...columns);
578
+ }
579
+ };
558
580
 
559
581
  var __defProp$1 = Object.defineProperty;
560
582
  var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
@@ -638,11 +660,33 @@ const tableChangeMethods = {
638
660
  }
639
661
  };
640
662
  const changeTable = async (migration, up, tableName, options, fn) => {
663
+ var _a;
641
664
  pqb.resetTableData();
642
665
  resetChangeTableData();
643
666
  const tableChanger = Object.create(pqb.columnTypes);
644
667
  Object.assign(tableChanger, tableChangeMethods);
645
668
  const changeData = (fn == null ? void 0 : fn(tableChanger)) || {};
669
+ const addPrimaryKeys = {
670
+ columns: []
671
+ };
672
+ const dropPrimaryKeys = {
673
+ columns: []
674
+ };
675
+ for (const key in changeData) {
676
+ const item = changeData[key];
677
+ if (Array.isArray(item)) {
678
+ const [action] = item;
679
+ if (action === "add") {
680
+ if (item[1].isPrimaryKey) {
681
+ addPrimaryKeys.columns.push(key);
682
+ }
683
+ } else if (action === "drop") {
684
+ if (item[1].isPrimaryKey) {
685
+ dropPrimaryKeys.columns.push(key);
686
+ }
687
+ }
688
+ }
689
+ }
646
690
  const state = {
647
691
  migration,
648
692
  up,
@@ -651,37 +695,70 @@ const changeTable = async (migration, up, tableName, options, fn) => {
651
695
  values: [],
652
696
  indexes: [],
653
697
  dropIndexes: [],
654
- comments: []
698
+ comments: [],
699
+ addPrimaryKeys,
700
+ dropPrimaryKeys
655
701
  };
656
702
  if (options.comment !== void 0) {
657
703
  await changeActions.tableComment(state, tableName, options.comment);
658
704
  }
659
705
  for (const key in changeData) {
660
- const result = changeData[key];
661
- if (Array.isArray(result)) {
662
- const [action] = result;
706
+ const item = changeData[key];
707
+ if (Array.isArray(item)) {
708
+ const [action] = item;
663
709
  if (action === "change") {
664
- const [, from, to, options2] = result;
710
+ const [, from, to, options2] = item;
665
711
  changeActions.change(state, up, key, from, to, options2);
666
712
  } else if (action === "rename") {
667
- const [, name] = result;
713
+ const [, name] = item;
668
714
  changeActions.rename(state, up, key, name);
669
715
  } else if (action) {
670
- const [action2, item, options2] = result;
671
- changeActions[action2](state, up, key, item, options2);
716
+ const [action2, columnType, options2] = item;
717
+ changeActions[action2](state, up, key, columnType, options2);
672
718
  }
673
719
  }
674
720
  }
721
+ const prependAlterTable = [];
722
+ let addedDownKey = false;
675
723
  changeTableData[up ? "drop" : "add"].forEach((tableData) => {
676
- handleTableData(state, false, tableName, tableData);
724
+ if (tableData.primaryKey) {
725
+ addedDownKey = true;
726
+ const keys = state[up ? "dropPrimaryKeys" : "addPrimaryKeys"];
727
+ keys.columns.push(...tableData.primaryKey.columns);
728
+ keys.options = tableData.primaryKey.options;
729
+ }
730
+ state.dropIndexes.push(...tableData.indexes);
731
+ prependAlterTable.push(...getForeignKeysLines(state, false, tableData));
677
732
  });
733
+ const dropKeys = state[up ? "dropPrimaryKeys" : "addPrimaryKeys"];
734
+ if (addedDownKey || dropKeys.change || dropKeys.columns.length > 1) {
735
+ const name = ((_a = dropKeys.options) == null ? void 0 : _a.name) || `${tableName}_pkey`;
736
+ prependAlterTable.push(`DROP CONSTRAINT "${name}"`);
737
+ }
738
+ let addedUpKey = false;
678
739
  changeTableData[up ? "add" : "drop"].forEach((tableData) => {
679
- handleTableData(state, true, tableName, tableData);
740
+ if (tableData.primaryKey) {
741
+ addedUpKey = true;
742
+ const keys = state[up ? "addPrimaryKeys" : "dropPrimaryKeys"];
743
+ keys.columns.push(...tableData.primaryKey.columns);
744
+ keys.options = tableData.primaryKey.options;
745
+ }
746
+ state.indexes.push(...tableData.indexes);
747
+ state.alterTable.push(...getForeignKeysLines(state, true, tableData));
680
748
  });
681
- if (state.alterTable.length) {
749
+ const addKeys = state[up ? "addPrimaryKeys" : "dropPrimaryKeys"];
750
+ if (addedUpKey || addKeys.change || addKeys.columns.length > 1) {
751
+ state.alterTable.push(`ADD ${primaryKeyToSql(addKeys)}`);
752
+ }
753
+ if (prependAlterTable.length || state.alterTable.length) {
682
754
  await migration.query(
683
755
  `ALTER TABLE ${quoteTable(tableName)}
684
- ${state.alterTable.join(",\n ")}`
756
+ ${[
757
+ ...prependAlterTable,
758
+ ...state.alterTable.map(
759
+ (item) => typeof item === "string" ? item : item(state)
760
+ )
761
+ ].join(",\n ")}`
685
762
  );
686
763
  }
687
764
  await migrateIndexes(state, state.dropIndexes, false);
@@ -706,7 +783,14 @@ const changeActions = {
706
783
  addColumnComment(state.comments, key, item);
707
784
  }
708
785
  if (up) {
709
- state.alterTable.push(`ADD COLUMN ${columnToSql(key, item, state)}`);
786
+ state.alterTable.push(
787
+ (state2) => `ADD COLUMN ${columnToSql(
788
+ key,
789
+ item,
790
+ state2.values,
791
+ (state2.up ? state2.addPrimaryKeys : state2.dropPrimaryKeys).columns.length > 1
792
+ )}`
793
+ );
710
794
  } else {
711
795
  state.alterTable.push(
712
796
  `DROP COLUMN "${key}"${(options == null ? void 0 : options.dropMode) ? ` ${options.dropMode}` : ""}`
@@ -741,6 +825,11 @@ const changeActions = {
741
825
  `ALTER COLUMN "${key}" SET COMPRESSION ${to.compression || "DEFAULT"}`
742
826
  );
743
827
  }
828
+ if (from.primaryKey || to.primaryKey) {
829
+ const primaryKey = state[up && to.primaryKey || !up && from.primaryKey ? "addPrimaryKeys" : "dropPrimaryKeys"];
830
+ primaryKey.columns.push(key);
831
+ primaryKey.change = true;
832
+ }
744
833
  const fromFkey = from.foreignKey;
745
834
  const toFkey = to.foreignKey;
746
835
  if (fromFkey || toFkey) {
@@ -822,6 +911,7 @@ const getChangeProperties = (item) => {
822
911
  nullable: item.isNullable,
823
912
  comment: item.data.comment,
824
913
  compression: item.data.compression,
914
+ primaryKey: item.isPrimaryKey,
825
915
  foreignKey: item.data.foreignKey,
826
916
  index: item.data.index
827
917
  };
@@ -833,33 +923,21 @@ const getChangeProperties = (item) => {
833
923
  nullable: item[0] === "nullable" ? item[1] : void 0,
834
924
  comment: item[0] === "comment" ? item[1] : void 0,
835
925
  compression: item[0] === "compression" ? item[1] : void 0,
926
+ primaryKey: item[0] === "primaryKey" ? item[1] : void 0,
836
927
  foreignKey: item[0] === "foreignKey" ? item[1] : void 0,
837
928
  index: item[0] === "index" ? item[1] : void 0
838
929
  };
839
930
  }
840
931
  };
841
- const handleTableData = (state, up, tableName, tableData) => {
842
- var _a;
843
- if (tableData.primaryKey) {
844
- if (up) {
845
- state.alterTable.push(`ADD ${primaryKeyToSql(tableData.primaryKey)}`);
846
- } else {
847
- const name = ((_a = tableData.primaryKey.options) == null ? void 0 : _a.name) || `${tableName}_pkey`;
848
- state.alterTable.push(`DROP CONSTRAINT "${name}"`);
849
- }
850
- }
851
- if (tableData.indexes.length) {
852
- state[up ? "indexes" : "dropIndexes"].push(...tableData.indexes);
853
- }
854
- if (tableData.foreignKeys.length) {
855
- tableData.foreignKeys.forEach((foreignKey) => {
856
- const action = up ? "ADD" : "DROP";
857
- state.alterTable.push(
858
- `
859
- ${action} ${constraintToSql(state.tableName, up, foreignKey)}`
860
- );
861
- });
862
- }
932
+ const getForeignKeysLines = (state, up, tableData) => {
933
+ return tableData.foreignKeys.map(
934
+ (foreignKey) => `
935
+ ${up ? "ADD" : "DROP"} ${constraintToSql(
936
+ state.tableName,
937
+ up,
938
+ foreignKey
939
+ )}`
940
+ );
863
941
  };
864
942
  const getRawOrValue = (item, values) => {
865
943
  return typeof item === "object" && item && pqb.isRaw(item) ? pqb.getRaw(item, values) : pqb.quote(item);