rake-db 2.33.11 → 2.34.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/dist/index.mjs CHANGED
@@ -518,14 +518,34 @@ const resetChangeTableData = () => {
518
518
  changeTableData = newChangeTableData();
519
519
  };
520
520
  const addOrDropChanges = [];
521
+ const standaloneCheckChanges = [];
521
522
  function add(item, options) {
522
523
  consumeColumnName();
523
524
  setName(this, item);
524
- if (isNoForeignKeyChangeInput(item)) throw new Error("t.noForeignKey() is only supported in t.change(...)");
525
525
  if (item instanceof Column) {
526
526
  const result = addOrDrop("add", item, options);
527
- if (result.type === "change") return result;
527
+ if (result.type === "change") {
528
+ result.name ??= getName(this);
529
+ return result;
530
+ }
531
+ addOrDropChanges.push(result);
532
+ return addOrDropChanges.length - 1;
533
+ }
534
+ if (isStandaloneAddOrDropInput(item)) {
535
+ const result = standaloneAddOrDropToChange("add", item);
536
+ result.name ??= getName(this);
537
+ addOrDropChanges.push(result);
538
+ return addOrDropChanges.length - 1;
539
+ }
540
+ if (isStandaloneCheckAddOrDropInput(item)) {
541
+ const result = standaloneAddOrDropToChange("add", item);
542
+ result.name ??= getName(this);
528
543
  addOrDropChanges.push(result);
544
+ standaloneCheckChanges.push({
545
+ index: addOrDropChanges.length - 1,
546
+ type: "add",
547
+ item
548
+ });
529
549
  return addOrDropChanges.length - 1;
530
550
  }
531
551
  for (const key in item) {
@@ -545,11 +565,30 @@ function add(item, options) {
545
565
  const drop = function(item, options) {
546
566
  consumeColumnName();
547
567
  setName(this, item);
548
- if (isNoForeignKeyChangeInput(item)) throw new Error("t.noForeignKey() is only supported in t.change(...)");
549
568
  if (item instanceof Column) {
550
569
  const result = addOrDrop("drop", item, options);
551
- if (result.type === "change") return result;
570
+ if (result.type === "change") {
571
+ result.name ??= getName(this);
572
+ return result;
573
+ }
574
+ addOrDropChanges.push(result);
575
+ return addOrDropChanges.length - 1;
576
+ }
577
+ if (isStandaloneAddOrDropInput(item)) {
578
+ const result = standaloneAddOrDropToChange("drop", item);
579
+ result.name ??= getName(this);
580
+ addOrDropChanges.push(result);
581
+ return addOrDropChanges.length - 1;
582
+ }
583
+ if (isStandaloneCheckAddOrDropInput(item)) {
584
+ const result = standaloneAddOrDropToChange("drop", item);
585
+ result.name ??= getName(this);
552
586
  addOrDropChanges.push(result);
587
+ standaloneCheckChanges.push({
588
+ index: addOrDropChanges.length - 1,
589
+ type: "drop",
590
+ item
591
+ });
553
592
  return addOrDropChanges.length - 1;
554
593
  }
555
594
  for (const key in item) {
@@ -589,22 +628,48 @@ const addOrDrop = (type, item, options) => {
589
628
  dropMode: options?.dropMode
590
629
  };
591
630
  };
631
+ const standaloneAddOrDropToChange = (type, item) => {
632
+ const empty = columnTypeToColumnChange({
633
+ type: "change",
634
+ to: {}
635
+ });
636
+ const change = changeInputToColumnChange(item);
637
+ return {
638
+ type: "change",
639
+ from: type === "add" ? empty : change,
640
+ to: type === "add" ? change : empty
641
+ };
642
+ };
592
643
  const isColumnForeignKeyChangeInput = (item) => {
593
644
  return "columnForeignKey" in item;
594
645
  };
595
- const isNoForeignKeyChangeInput = (item) => {
596
- return "noForeignKey" in item;
646
+ const isColumnPrimaryKeyChangeInput = (item) => {
647
+ return "columnPrimaryKey" in item;
648
+ };
649
+ const isColumnIndexChangeInput = (item) => {
650
+ return "columnIndex" in item;
651
+ };
652
+ const isColumnExcludeChangeInput = (item) => {
653
+ return "columnExclude" in item;
654
+ };
655
+ const isStandaloneAddOrDropInput = (item) => {
656
+ return isColumnForeignKeyChangeInput(item) || isColumnPrimaryKeyChangeInput(item) || isColumnIndexChangeInput(item) || isColumnExcludeChangeInput(item);
657
+ };
658
+ const isStandaloneCheckAddOrDropInput = (item) => {
659
+ return isCheckConstraintItem(item);
597
660
  };
598
661
  const isCheckConstraintItem = (item) => {
599
662
  return !!item.constraint?.check;
600
663
  };
601
- const changeInputToColumnChange = (item, opposite) => {
664
+ const changeInputToColumnChange = (item) => {
602
665
  if (item instanceof Column || "type" in item) return columnTypeToColumnChange(item);
666
+ if (isColumnPrimaryKeyChangeInput(item)) return {
667
+ primaryKey: true,
668
+ primaryKeyName: item.columnPrimaryKey.name
669
+ };
670
+ if (isColumnIndexChangeInput(item)) return { indexes: [item.columnIndex] };
671
+ if (isColumnExcludeChangeInput(item)) return { excludes: [item.columnExclude] };
603
672
  if (isColumnForeignKeyChangeInput(item)) return { foreignKeys: [item.columnForeignKey] };
604
- if (isNoForeignKeyChangeInput(item)) {
605
- if (!isColumnForeignKeyChangeInput(opposite)) throw new Error("t.noForeignKey() in t.change(...) must be paired with t.foreignKey(...)");
606
- return { foreignKeys: [] };
607
- }
608
673
  if (isCheckConstraintItem(item)) return { checks: [{
609
674
  sql: item.constraint.check,
610
675
  name: item.constraint.name
@@ -635,6 +700,9 @@ const columnTypeToColumnChange = (item, name) => {
635
700
  return item.to;
636
701
  };
637
702
  const nameKey = Symbol("name");
703
+ const getName = (self) => {
704
+ return self[nameKey];
705
+ };
638
706
  const setName = (self, item) => {
639
707
  const name = self[nameKey];
640
708
  if (!name) return;
@@ -654,6 +722,47 @@ function foreignKey(...args) {
654
722
  options
655
723
  } };
656
724
  }
725
+ function primaryKey(...args) {
726
+ if (Array.isArray(args[0])) {
727
+ const [columns, name] = args;
728
+ return tableDataMethods.primaryKey(columns, name);
729
+ }
730
+ const [name] = args;
731
+ return { columnPrimaryKey: { name } };
732
+ }
733
+ function index(...args) {
734
+ if (Array.isArray(args[0])) {
735
+ const [columns, first, second] = args;
736
+ if (typeof first === "string") return tableDataMethods.index(columns, first, second);
737
+ return tableDataMethods.index(columns, first);
738
+ }
739
+ const [options] = args;
740
+ return { columnIndex: { options: { ...options } } };
741
+ }
742
+ function unique(...args) {
743
+ if (Array.isArray(args[0])) {
744
+ const [columns, first, second] = args;
745
+ if (typeof first === "string") return tableDataMethods.unique(columns, first, second);
746
+ return tableDataMethods.unique(columns, first);
747
+ }
748
+ const [options] = args;
749
+ return { columnIndex: { options: {
750
+ ...options,
751
+ unique: true
752
+ } } };
753
+ }
754
+ function exclude(...args) {
755
+ if (Array.isArray(args[0])) {
756
+ const [columns, first, second] = args;
757
+ if (typeof first === "string") return tableDataMethods.exclude(columns, first, second);
758
+ return tableDataMethods.exclude(columns, first);
759
+ }
760
+ const [with_, options] = args;
761
+ return { columnExclude: {
762
+ with: with_,
763
+ options: { ...options }
764
+ } };
765
+ }
657
766
  const tableChangeMethods = {
658
767
  ...tableMethods,
659
768
  ...tableDataMethods,
@@ -665,14 +774,15 @@ const tableChangeMethods = {
665
774
  },
666
775
  add,
667
776
  drop,
777
+ primaryKey,
778
+ index,
779
+ unique,
780
+ exclude,
668
781
  foreignKey,
669
- noForeignKey() {
670
- return { noForeignKey: true };
671
- },
672
782
  change(from, to, using) {
673
783
  consumeColumnName();
674
- const f = changeInputToColumnChange(from, to);
675
- const t = changeInputToColumnChange(to, from);
784
+ const f = changeInputToColumnChange(from);
785
+ const t = changeInputToColumnChange(to);
676
786
  setName(this, f);
677
787
  setName(this, t);
678
788
  return {
@@ -722,6 +832,7 @@ const changeTable = async (migration, up, tableName, options, fn) => {
722
832
  const tableChanger = Object.create(migration.columnTypes);
723
833
  Object.assign(tableChanger, tableChangeMethods);
724
834
  addOrDropChanges.length = 0;
835
+ standaloneCheckChanges.length = 0;
725
836
  const changeData = fn?.(tableChanger) || {};
726
837
  const schema = migration.adapter.getSchema();
727
838
  const queries = astToQueries(schema, makeAst$3(schema, up, tableName, changeData, changeTableData, options), snakeCase, language);
@@ -736,6 +847,7 @@ const makeAst$3 = (schema, up, name, changeData, changeTableData, options) => {
736
847
  const consumedChanges = {};
737
848
  for (const key in changeData) {
738
849
  let item = changeData[key];
850
+ if (item === void 0) continue;
739
851
  if (typeof item === "number") {
740
852
  consumedChanges[item] = true;
741
853
  item = addOrDropChanges[item];
@@ -761,9 +873,15 @@ const makeAst$3 = (schema, up, name, changeData, changeTableData, options) => {
761
873
  }
762
874
  } : item;
763
875
  }
876
+ for (const checkChange of standaloneCheckChanges) {
877
+ if (consumedChanges[checkChange.index]) continue;
878
+ parseTableDataInput(changeTableData[checkChange.type], checkChange.item);
879
+ consumedChanges[checkChange.index] = true;
880
+ }
764
881
  for (let i = 0; i < addOrDropChanges.length; i++) {
765
882
  if (consumedChanges[i]) continue;
766
883
  const change = addOrDropChanges[i];
884
+ if (change.type === "change") throw new Error("Standalone helper add/drop changes must be assigned to a column key");
767
885
  const name = change.item.data.name;
768
886
  if (!name) throw new Error(`Column in ...t.${change.type}() must have a name`);
769
887
  const arr = shape[name] ? toArray(shape[name]) : [];
@@ -859,6 +977,11 @@ const alterTableSql = (tableName, lines, values) => ({
859
977
  ${lines.join(",\n ")}`,
860
978
  values
861
979
  });
980
+ const setPrimaryKeyName = (key, primaryKey, name) => {
981
+ if (!name) return;
982
+ if (primaryKey.name && primaryKey.name !== name) throw new Error(`Cannot use different primary key names in standalone changes for column ${key}`);
983
+ primaryKey.name = name;
984
+ };
862
985
  const handlePrerequisitesForTableItem = (schema, key, item, queries, addPrimaryKeys, dropPrimaryKeys, snakeCase) => {
863
986
  if ("item" in item) {
864
987
  const { item: column } = item;
@@ -872,10 +995,12 @@ const handlePrerequisitesForTableItem = (schema, key, item, queries, addPrimaryK
872
995
  if (item.from.column instanceof EnumColumn) queries.push(makePopulateEnumQuery(schema, item.from.column));
873
996
  if (item.to.column instanceof EnumColumn) queries.push(makePopulateEnumQuery(schema, item.to.column));
874
997
  if (item.from.primaryKey) {
998
+ setPrimaryKeyName(key, dropPrimaryKeys, item.from.primaryKeyName);
875
999
  dropPrimaryKeys.columns.push(item.from.column ? getColumnName(item.from.column, key, snakeCase) : snakeCase ? toSnakeCase(key) : key);
876
1000
  dropPrimaryKeys.change = true;
877
1001
  }
878
1002
  if (item.to.primaryKey) {
1003
+ setPrimaryKeyName(key, addPrimaryKeys, item.to.primaryKeyName);
879
1004
  addPrimaryKeys.columns.push(item.to.column ? getColumnName(item.to.column, key, snakeCase) : snakeCase ? toSnakeCase(key) : key);
880
1005
  addPrimaryKeys.change = true;
881
1006
  }
@@ -2135,7 +2260,7 @@ const wrapWithEnhancingError = async (text, values, promise) => {
2135
2260
  try {
2136
2261
  return await promise;
2137
2262
  } catch (err) {
2138
- if (err && typeof err === "object" && "message" in err && typeof err.message === "string" && err.constructor.name === "PostgresError") {
2263
+ if (err && typeof err === "object" && "message" in err && typeof err.message === "string" && (err.constructor.name === "PostgresError" || err.constructor.name === "DatabaseError")) {
2139
2264
  err.message += `\nSQL: ${text}${values ? `\nVariables: ${JSON.stringify(values)}` : ""}`;
2140
2265
  throw new err.constructor(err);
2141
2266
  }
@@ -2609,13 +2734,11 @@ const getMaybeTransactionAdapter = (db) => "$getAdapter" in db ? db.$getAdapter(
2609
2734
  const runSqlInSavePoint = async (db, sql, code) => {
2610
2735
  const adapter = getMaybeTransactionAdapter(db);
2611
2736
  try {
2612
- await adapter.query(adapter.isInTransaction() ? `SAVEPOINT s; ${sql}; RELEASE SAVEPOINT s` : sql);
2737
+ const query = () => adapter.query(sql);
2738
+ await (adapter.isInTransaction() ? adapter.savepoint("s", query) : query());
2613
2739
  return "done";
2614
2740
  } catch (err) {
2615
- if (err.code === code) {
2616
- if (adapter.isInTransaction()) await adapter.query(`ROLLBACK TO SAVEPOINT s`);
2617
- return "already";
2618
- }
2741
+ if (err.code === code) return "already";
2619
2742
  throw err;
2620
2743
  }
2621
2744
  };
@@ -2745,17 +2868,14 @@ const deleteMigratedVersion = async (adapter, version, name, config) => {
2745
2868
  var NoMigrationsTableError = class extends Error {};
2746
2869
  const getMigratedVersionsMap = async (ctx, adapter, config, renameTo) => {
2747
2870
  const table = migrationsSchemaTableSql(adapter, config);
2748
- const inTransaction = "isInTransaction" in adapter && adapter.isInTransaction();
2871
+ const queryVersion = () => adapter.arrays(`SELECT * FROM ${table} ORDER BY version`);
2749
2872
  let result;
2750
2873
  try {
2751
- if (inTransaction) await adapter.query(`SAVEPOINT check_migrations_table`);
2752
- result = await adapter.arrays(`SELECT * FROM ${table} ORDER BY version`);
2753
- if (inTransaction) await adapter.query(`RELEASE SAVEPOINT check_migrations_table`);
2874
+ if (adapter.isInTransaction()) result = await adapter.savepoint("check_migrations_table", queryVersion);
2875
+ else result = await queryVersion();
2754
2876
  } catch (err) {
2755
- if (err.code === "42P01") {
2756
- if (inTransaction) await adapter.query(`ROLLBACK TO SAVEPOINT check_migrations_table`);
2757
- throw new NoMigrationsTableError();
2758
- } else throw err;
2877
+ if (err.code === "42P01") throw new NoMigrationsTableError();
2878
+ else throw err;
2759
2879
  }
2760
2880
  if (!result.fields[1]) {
2761
2881
  const { migrations } = await getMigrations(ctx, config, true);