rake-db 2.4.7 → 2.4.8

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 CHANGED
@@ -1,4 +1,5 @@
1
- import { ColumnType, EnumColumn, ColumnTypes, ColumnsShape, DbResult, DefaultColumnTypes, TransactionAdapter, QueryLogObject, IndexColumnOptions, IndexOptions, ForeignKeyOptions, TextColumn, NoPrimaryKeyOption, TableData, SingleColumnIndexOptions, AdapterOptions, QueryLogOptions, Adapter } from 'pqb';
1
+ import { ColumnType, EnumColumn, UnknownColumn, ColumnTypes, ColumnsShape, DbResult, DefaultColumnTypes, TransactionAdapter, QueryLogObject, IndexColumnOptions, IndexOptions, ForeignKeyOptions, TextColumn, NoPrimaryKeyOption, TableData, SingleColumnIndexOptions, AdapterOptions, QueryLogOptions, Adapter } from 'pqb';
2
+ import * as orchid_core from 'orchid-core';
2
3
  import { EmptyObject, RawExpression, ColumnTypesBase, raw, MaybeArray } from 'orchid-core';
3
4
 
4
5
  declare function add(this: ColumnTypesBase, item: ColumnType, options?: {
@@ -24,6 +25,7 @@ declare const tableChangeMethods: {
24
25
  comment(comment: string | null): Change;
25
26
  rename(name: string): RakeDbAst.ChangeTableItem.Rename;
26
27
  enum(this: ColumnTypesBase, name: string): EnumColumn<string, [string, ...string[]]>;
28
+ check(this: ColumnTypesBase, value: RawExpression<orchid_core.ColumnTypeBase<unknown, orchid_core.BaseOperators, unknown, orchid_core.ColumnDataBase>>): UnknownColumn;
27
29
  };
28
30
  declare type TableChanger = MigrationColumnTypes & TableChangeMethods;
29
31
  declare type TableChangeData = Record<string, RakeDbAst.ChangeTableItem.Column | RakeDbAst.ChangeTableItem.Rename | Change | EmptyObject>;
@@ -139,6 +141,7 @@ declare namespace RakeDbAst {
139
141
  comment?: string | null;
140
142
  compression?: string;
141
143
  primaryKey?: boolean;
144
+ check?: RawExpression;
142
145
  foreignKeys?: ({
143
146
  table: string;
144
147
  columns: string[];
package/dist/index.js CHANGED
@@ -315,6 +315,9 @@ const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
315
315
  } else if (!item.data.isNullable) {
316
316
  line.push("NOT NULL");
317
317
  }
318
+ if (item.data.check) {
319
+ line.push(`CHECK (${pqb.getRaw(item.data.check, values)})`);
320
+ }
318
321
  if (item.data.default !== void 0) {
319
322
  if (typeof item.data.default === "object" && item.data.default && orchidCore.isRaw(item.data.default)) {
320
323
  line.push(`DEFAULT ${pqb.getRaw(item.data.default, values)}`);
@@ -475,6 +478,9 @@ const primaryKeyToSql = (primaryKey) => {
475
478
  const tableMethods = {
476
479
  enum(name) {
477
480
  return new pqb.EnumColumn(this, name, []);
481
+ },
482
+ check(value) {
483
+ return new pqb.UnknownColumn(this).check(value);
478
484
  }
479
485
  };
480
486
 
@@ -676,14 +682,7 @@ const mergeTableData = (a, b) => {
676
682
  };
677
683
  function add(item, options) {
678
684
  if (item instanceof pqb.ColumnType) {
679
- if (this[orchidCore.nameKey]) {
680
- item.data.name = this[orchidCore.nameKey];
681
- }
682
- return {
683
- type: "add",
684
- item,
685
- dropMode: options == null ? void 0 : options.dropMode
686
- };
685
+ return addOrDrop(this, "add", item, options);
687
686
  } else if (item === orchidCore.emptyObject) {
688
687
  mergeTableData(changeTableData.add, pqb.getTableData());
689
688
  pqb.resetTableData();
@@ -702,14 +701,7 @@ function add(item, options) {
702
701
  }
703
702
  const drop = function(item, options) {
704
703
  if (item instanceof pqb.ColumnType) {
705
- if (this[orchidCore.nameKey]) {
706
- item.data.name = this[orchidCore.nameKey];
707
- }
708
- return {
709
- type: "drop",
710
- item,
711
- dropMode: options == null ? void 0 : options.dropMode
712
- };
704
+ return addOrDrop(this, "drop", item, options);
713
705
  } else if (item === orchidCore.emptyObject) {
714
706
  mergeTableData(changeTableData.drop, pqb.getTableData());
715
707
  pqb.resetTableData();
@@ -726,6 +718,35 @@ const drop = function(item, options) {
726
718
  return result;
727
719
  }
728
720
  };
721
+ const addOrDrop = (types, type, item, options) => {
722
+ if (types[orchidCore.nameKey]) {
723
+ item.data.name = types[orchidCore.nameKey];
724
+ }
725
+ if (item instanceof pqb.UnknownColumn) {
726
+ const empty = columnTypeToColumnChange({
727
+ type: "change",
728
+ from: {},
729
+ to: {}
730
+ });
731
+ const add2 = columnTypeToColumnChange({
732
+ type: "change",
733
+ from: {},
734
+ to: {
735
+ check: item.data.check
736
+ }
737
+ });
738
+ return __spreadValues$3({
739
+ type: "change",
740
+ from: type === "add" ? empty : add2,
741
+ to: type === "add" ? add2 : empty
742
+ }, options);
743
+ }
744
+ return {
745
+ type,
746
+ item,
747
+ dropMode: options == null ? void 0 : options.dropMode
748
+ };
749
+ };
729
750
  const columnTypeToColumnChange = (item) => {
730
751
  if (item instanceof pqb.ColumnType) {
731
752
  const foreignKeys = item.data.foreignKeys;
@@ -877,12 +898,13 @@ const astToQueries = (ast) => {
877
898
  for (const key in ast.shape) {
878
899
  const item = ast.shape[key];
879
900
  if (item.type === "add") {
880
- addColumnIndex(addIndexes, key, item.item);
881
- addColumnComment(comments, key, item.item);
901
+ const column = item.item;
902
+ addColumnIndex(addIndexes, key, column);
903
+ addColumnComment(comments, key, column);
882
904
  alterTable.push(
883
905
  `ADD COLUMN ${columnToSql(
884
906
  key,
885
- item.item,
907
+ column,
886
908
  values,
887
909
  addPrimaryKeys.columns.length > 1
888
910
  )}`
@@ -894,7 +916,7 @@ const astToQueries = (ast) => {
894
916
  );
895
917
  } else if (item.type === "change") {
896
918
  const { from, to } = item;
897
- if (from.type !== to.type || from.collate !== to.collate) {
919
+ if (to.type && (from.type !== to.type || from.collate !== to.collate)) {
898
920
  alterTable.push(
899
921
  `ALTER COLUMN "${item.name || key}" TYPE ${to.type}${to.collate ? ` COLLATE ${pqb.quote(to.collate)}` : ""}${item.using ? ` USING ${pqb.getRaw(item.using, values)}` : ""}`
900
922
  );
@@ -914,6 +936,18 @@ const astToQueries = (ast) => {
914
936
  `ALTER COLUMN "${item.name || key}" SET COMPRESSION ${to.compression || "DEFAULT"}`
915
937
  );
916
938
  }
939
+ if (from.check !== to.check) {
940
+ const name = `${ast.name}_${item.name || key}_check`;
941
+ if (from.check) {
942
+ alterTable.push(`DROP CONSTRAINT "${name}"`);
943
+ }
944
+ if (to.check) {
945
+ alterTable.push(
946
+ `ADD CONSTRAINT "${name}"
947
+ CHECK (${pqb.getRaw(to.check, values)})`
948
+ );
949
+ }
950
+ }
917
951
  const foreignKeysLen = Math.max(
918
952
  ((_a = from.foreignKeys) == null ? void 0 : _a.length) || 0,
919
953
  ((_b = to.foreignKeys) == null ? void 0 : _b.length) || 0
@@ -1864,6 +1898,31 @@ GROUP BY n.nspname, t.typname`
1864
1898
  );
1865
1899
  return rows;
1866
1900
  }
1901
+ async getChecks() {
1902
+ const { rows } = await this.db.query(`SELECT
1903
+ s.nspname AS "schemaName",
1904
+ t.relname AS "tableName",
1905
+ c.conname AS "name",
1906
+ (
1907
+ SELECT json_agg(ccu.column_name)
1908
+ FROM information_schema.constraint_column_usage ccu
1909
+ WHERE ccu.constraint_name = c.conname
1910
+ AND ccu.table_schema = cs.nspname
1911
+ ) AS "columnNames",
1912
+ pg_get_expr(conbin, conrelid) AS "expression"
1913
+ FROM pg_catalog.pg_constraint c
1914
+ JOIN pg_class t ON t.oid = conrelid
1915
+ JOIN pg_catalog.pg_namespace s ON s.oid = t.relnamespace
1916
+ JOIN pg_catalog.pg_namespace cs ON cs.oid = c.connamespace
1917
+ WHERE contype = 'c'
1918
+ ORDER BY c.conname`);
1919
+ for (const row of rows) {
1920
+ if (row.expression[0] === "(" && row.expression[row.expression.length - 1] === ")") {
1921
+ row.expression = row.expression.slice(1, -1);
1922
+ }
1923
+ }
1924
+ return rows;
1925
+ }
1867
1926
  }
1868
1927
 
1869
1928
  var __defProp = Object.defineProperty;
@@ -1987,7 +2046,8 @@ const getData = async (db) => {
1987
2046
  indexes,
1988
2047
  foreignKeys,
1989
2048
  extensions,
1990
- enums
2049
+ enums,
2050
+ checks
1991
2051
  ] = await Promise.all([
1992
2052
  db.getSchemas(),
1993
2053
  db.getTables(),
@@ -1996,7 +2056,8 @@ const getData = async (db) => {
1996
2056
  db.getIndexes(),
1997
2057
  db.getForeignKeys(),
1998
2058
  db.getExtensions(),
1999
- db.getEnums()
2059
+ db.getEnums(),
2060
+ db.getChecks()
2000
2061
  ]);
2001
2062
  return {
2002
2063
  schemas,
@@ -2006,7 +2067,8 @@ const getData = async (db) => {
2006
2067
  indexes,
2007
2068
  foreignKeys,
2008
2069
  extensions,
2009
- enums
2070
+ enums,
2071
+ checks
2010
2072
  };
2011
2073
  };
2012
2074
  const makeBelongsToTable = (schema, table) => (item) => item.schemaName === schema && item.tableName === table;
@@ -2036,6 +2098,12 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2036
2098
  const primaryKey = data.primaryKeys.find(belongsToTable);
2037
2099
  const tableIndexes = data.indexes.filter(belongsToTable);
2038
2100
  const tableForeignKeys = innerFKeys.filter(belongsToTable);
2101
+ const columnChecks = {};
2102
+ for (const check of data.checks) {
2103
+ if (check.columnNames.length === 1) {
2104
+ columnChecks[check.columnNames[0]] = check;
2105
+ }
2106
+ }
2039
2107
  const shape = {};
2040
2108
  for (let item of columns) {
2041
2109
  const isSerial = getIsSerial(item);
@@ -2098,6 +2166,10 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2098
2166
  }
2099
2167
  );
2100
2168
  }
2169
+ const check = columnChecks[item.name];
2170
+ if (check) {
2171
+ column.data.check = orchidCore.raw(check.expression);
2172
+ }
2101
2173
  delete column.data.name;
2102
2174
  shape[item.name] = column;
2103
2175
  }