rake-db 2.4.7 → 2.4.9

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>;
@@ -83,14 +85,16 @@ declare class MigrationBase {
83
85
  dropSchema(schemaName: string): Promise<void>;
84
86
  createExtension(name: string, options?: Omit<RakeDbAst.Extension, 'type' | 'action' | 'name'>): Promise<void>;
85
87
  dropExtension(name: string, options?: Omit<RakeDbAst.Extension, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
86
- createEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
87
- dropEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values'>): Promise<void>;
88
+ createEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values' | 'schema'>): Promise<void>;
89
+ dropEnum(name: string, values: [string, ...string[]], options?: Omit<RakeDbAst.Enum, 'type' | 'action' | 'name' | 'values' | 'schema'>): Promise<void>;
90
+ createDomain(name: string, fn: (t: ColumnTypes) => ColumnType, options?: Omit<RakeDbAst.Domain, 'type' | 'action' | 'schema' | 'name' | 'baseType'>): Promise<void>;
91
+ dropDomain(name: string, fn: (t: ColumnTypes) => ColumnType, options?: Omit<RakeDbAst.Domain, 'type' | 'action' | 'schema' | 'name' | 'baseType'>): Promise<void>;
88
92
  tableExists(tableName: string): Promise<boolean>;
89
93
  columnExists(tableName: string, columnName: string): Promise<boolean>;
90
94
  constraintExists(constraintName: string): Promise<boolean>;
91
95
  }
92
96
 
93
- declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.ForeignKey;
97
+ declare type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameTable | RakeDbAst.Schema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.Domain | RakeDbAst.ForeignKey;
94
98
  declare namespace RakeDbAst {
95
99
  type Table = {
96
100
  type: 'table';
@@ -139,6 +143,7 @@ declare namespace RakeDbAst {
139
143
  comment?: string | null;
140
144
  compression?: string;
141
145
  primaryKey?: boolean;
146
+ check?: RawExpression;
142
147
  foreignKeys?: ({
143
148
  table: string;
144
149
  columns: string[];
@@ -176,6 +181,18 @@ declare namespace RakeDbAst {
176
181
  cascade?: boolean;
177
182
  dropIfExists?: boolean;
178
183
  };
184
+ type Domain = {
185
+ type: 'domain';
186
+ action: 'create' | 'drop';
187
+ schema?: string;
188
+ name: string;
189
+ baseType: ColumnType;
190
+ notNull?: boolean;
191
+ collation?: string;
192
+ default?: RawExpression;
193
+ check?: RawExpression;
194
+ cascade?: boolean;
195
+ };
179
196
  type EnumOptions = {
180
197
  createIfNotExists?: boolean;
181
198
  dropIfExists?: boolean;
package/dist/index.js CHANGED
@@ -302,8 +302,11 @@ var __spreadValues$5 = (a, b) => {
302
302
  return a;
303
303
  };
304
304
  var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
305
+ const columnTypeToSql = (item) => {
306
+ return item.data.isOfCustomType ? `"${item.toSQL()}"` : item.toSQL();
307
+ };
305
308
  const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
306
- const line = [`"${item.data.name || key}" ${item.toSQL()}`];
309
+ const line = [`"${item.data.name || key}" ${columnTypeToSql(item)}`];
307
310
  if (item.data.compression) {
308
311
  line.push(`COMPRESSION ${item.data.compression}`);
309
312
  }
@@ -315,6 +318,9 @@ const columnToSql = (key, item, values, hasMultiplePrimaryKeys) => {
315
318
  } else if (!item.data.isNullable) {
316
319
  line.push("NOT NULL");
317
320
  }
321
+ if (item.data.check) {
322
+ line.push(`CHECK (${pqb.getRaw(item.data.check, values)})`);
323
+ }
318
324
  if (item.data.default !== void 0) {
319
325
  if (typeof item.data.default === "object" && item.data.default && orchidCore.isRaw(item.data.default)) {
320
326
  line.push(`DEFAULT ${pqb.getRaw(item.data.default, values)}`);
@@ -475,6 +481,9 @@ const primaryKeyToSql = (primaryKey) => {
475
481
  const tableMethods = {
476
482
  enum(name) {
477
483
  return new pqb.EnumColumn(this, name, []);
484
+ },
485
+ check(value) {
486
+ return new pqb.UnknownColumn(this).check(value);
478
487
  }
479
488
  };
480
489
 
@@ -502,7 +511,7 @@ var __spreadValues$4 = (a, b) => {
502
511
  return a;
503
512
  };
504
513
  var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
505
- var __objRest = (source, exclude) => {
514
+ var __objRest$1 = (source, exclude) => {
506
515
  var target = {};
507
516
  for (var prop in source)
508
517
  if (__hasOwnProp$4.call(source, prop) && exclude.indexOf(prop) < 0)
@@ -530,7 +539,7 @@ const createTable$1 = async (migration, up, tableName, options, fn) => {
530
539
  validatePrimaryKey(ast);
531
540
  const queries = astToQueries$1(ast);
532
541
  for (const _a of queries) {
533
- const _b = _a, { then } = _b, query = __objRest(_b, ["then"]);
542
+ const _b = _a, { then } = _b, query = __objRest$1(_b, ["then"]);
534
543
  const result = await migration.adapter.arrays(query);
535
544
  then == null ? void 0 : then(result);
536
545
  }
@@ -676,14 +685,7 @@ const mergeTableData = (a, b) => {
676
685
  };
677
686
  function add(item, options) {
678
687
  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
- };
688
+ return addOrDrop(this, "add", item, options);
687
689
  } else if (item === orchidCore.emptyObject) {
688
690
  mergeTableData(changeTableData.add, pqb.getTableData());
689
691
  pqb.resetTableData();
@@ -702,14 +704,7 @@ function add(item, options) {
702
704
  }
703
705
  const drop = function(item, options) {
704
706
  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
- };
707
+ return addOrDrop(this, "drop", item, options);
713
708
  } else if (item === orchidCore.emptyObject) {
714
709
  mergeTableData(changeTableData.drop, pqb.getTableData());
715
710
  pqb.resetTableData();
@@ -726,6 +721,35 @@ const drop = function(item, options) {
726
721
  return result;
727
722
  }
728
723
  };
724
+ const addOrDrop = (types, type, item, options) => {
725
+ if (types[orchidCore.nameKey]) {
726
+ item.data.name = types[orchidCore.nameKey];
727
+ }
728
+ if (item instanceof pqb.UnknownColumn) {
729
+ const empty = columnTypeToColumnChange({
730
+ type: "change",
731
+ from: {},
732
+ to: {}
733
+ });
734
+ const add2 = columnTypeToColumnChange({
735
+ type: "change",
736
+ from: {},
737
+ to: {
738
+ check: item.data.check
739
+ }
740
+ });
741
+ return __spreadValues$3({
742
+ type: "change",
743
+ from: type === "add" ? empty : add2,
744
+ to: type === "add" ? add2 : empty
745
+ }, options);
746
+ }
747
+ return {
748
+ type,
749
+ item,
750
+ dropMode: options == null ? void 0 : options.dropMode
751
+ };
752
+ };
729
753
  const columnTypeToColumnChange = (item) => {
730
754
  if (item instanceof pqb.ColumnType) {
731
755
  const foreignKeys = item.data.foreignKeys;
@@ -877,12 +901,13 @@ const astToQueries = (ast) => {
877
901
  for (const key in ast.shape) {
878
902
  const item = ast.shape[key];
879
903
  if (item.type === "add") {
880
- addColumnIndex(addIndexes, key, item.item);
881
- addColumnComment(comments, key, item.item);
904
+ const column = item.item;
905
+ addColumnIndex(addIndexes, key, column);
906
+ addColumnComment(comments, key, column);
882
907
  alterTable.push(
883
908
  `ADD COLUMN ${columnToSql(
884
909
  key,
885
- item.item,
910
+ column,
886
911
  values,
887
912
  addPrimaryKeys.columns.length > 1
888
913
  )}`
@@ -894,9 +919,10 @@ const astToQueries = (ast) => {
894
919
  );
895
920
  } else if (item.type === "change") {
896
921
  const { from, to } = item;
897
- if (from.type !== to.type || from.collate !== to.collate) {
922
+ if (to.type && (from.type !== to.type || from.collate !== to.collate)) {
923
+ const type = !to.column || to.column.data.isOfCustomType ? `"${to.type}"` : to.type;
898
924
  alterTable.push(
899
- `ALTER COLUMN "${item.name || key}" TYPE ${to.type}${to.collate ? ` COLLATE ${pqb.quote(to.collate)}` : ""}${item.using ? ` USING ${pqb.getRaw(item.using, values)}` : ""}`
925
+ `ALTER COLUMN "${item.name || key}" TYPE ${type}${to.collate ? ` COLLATE ${pqb.quote(to.collate)}` : ""}${item.using ? ` USING ${pqb.getRaw(item.using, values)}` : ""}`
900
926
  );
901
927
  }
902
928
  if (from.default !== to.default) {
@@ -914,6 +940,18 @@ const astToQueries = (ast) => {
914
940
  `ALTER COLUMN "${item.name || key}" SET COMPRESSION ${to.compression || "DEFAULT"}`
915
941
  );
916
942
  }
943
+ if (from.check !== to.check) {
944
+ const name = `${ast.name}_${item.name || key}_check`;
945
+ if (from.check) {
946
+ alterTable.push(`DROP CONSTRAINT "${name}"`);
947
+ }
948
+ if (to.check) {
949
+ alterTable.push(
950
+ `ADD CONSTRAINT "${name}"
951
+ CHECK (${pqb.getRaw(to.check, values)})`
952
+ );
953
+ }
954
+ }
917
955
  const foreignKeysLen = Math.max(
918
956
  ((_a = from.foreignKeys) == null ? void 0 : _a.length) || 0,
919
957
  ((_b = to.foreignKeys) == null ? void 0 : _b.length) || 0
@@ -1152,6 +1190,12 @@ class MigrationBase {
1152
1190
  dropEnum(name, values, options) {
1153
1191
  return createEnum$1(this, !this.up, name, values, options);
1154
1192
  }
1193
+ createDomain(name, fn, options) {
1194
+ return createDomain$1(this, this.up, name, fn, options);
1195
+ }
1196
+ dropDomain(name, fn, options) {
1197
+ return createDomain$1(this, !this.up, name, fn, options);
1198
+ }
1155
1199
  async tableExists(tableName) {
1156
1200
  return queryExists(this, {
1157
1201
  text: `SELECT 1 FROM "information_schema"."tables" WHERE "table_name" = $1`,
@@ -1246,6 +1290,34 @@ const createEnum$1 = async (migration, up, name, values, options = {}) => {
1246
1290
  await migration.adapter.query(query);
1247
1291
  migration.migratedAsts.push(ast);
1248
1292
  };
1293
+ const createDomain$1 = async (migration, up, name, fn, options) => {
1294
+ const [schema, domainName] = getSchemaAndTableFromName(name);
1295
+ const ast = __spreadValues$2({
1296
+ type: "domain",
1297
+ action: up ? "create" : "drop",
1298
+ schema,
1299
+ name: domainName,
1300
+ baseType: fn(pqb.columnTypes)
1301
+ }, options);
1302
+ let query;
1303
+ const values = [];
1304
+ const quotedName = quoteWithSchema(ast);
1305
+ if (ast.action === "create") {
1306
+ query = `CREATE DOMAIN ${quotedName} AS ${columnTypeToSql(ast.baseType)}${ast.collation ? `
1307
+ COLLATION ${orchidCore.singleQuote(ast.collation)}` : ""}${ast.default ? `
1308
+ DEFAULT ${pqb.getRaw(ast.default, values)}` : ""}${ast.notNull || ast.check ? "\n" : ""}${[
1309
+ ast.notNull && "NOT NULL",
1310
+ ast.check && `CHECK ${pqb.getRaw(ast.check, values)}`
1311
+ ].filter(Boolean).join(" ")}`;
1312
+ } else {
1313
+ query = `DROP DOMAIN ${quotedName}${ast.cascade ? " CASCADE" : ""}`;
1314
+ }
1315
+ await migration.adapter.query({
1316
+ text: query,
1317
+ values
1318
+ });
1319
+ migration.migratedAsts.push(ast);
1320
+ };
1249
1321
  const queryExists = (db, sql) => {
1250
1322
  return db.adapter.query(sql).then(({ rowCount }) => rowCount > 0);
1251
1323
  };
@@ -1864,6 +1936,63 @@ GROUP BY n.nspname, t.typname`
1864
1936
  );
1865
1937
  return rows;
1866
1938
  }
1939
+ async getChecks() {
1940
+ const { rows } = await this.db.query(`SELECT
1941
+ s.nspname AS "schemaName",
1942
+ t.relname AS "tableName",
1943
+ c.conname AS "name",
1944
+ (
1945
+ SELECT json_agg(ccu.column_name)
1946
+ FROM information_schema.constraint_column_usage ccu
1947
+ WHERE ccu.constraint_name = c.conname
1948
+ AND ccu.table_schema = cs.nspname
1949
+ ) AS "columnNames",
1950
+ pg_get_expr(conbin, conrelid) AS "expression"
1951
+ FROM pg_catalog.pg_constraint c
1952
+ JOIN pg_class t ON t.oid = conrelid
1953
+ JOIN pg_catalog.pg_namespace s ON s.oid = t.relnamespace
1954
+ JOIN pg_catalog.pg_namespace cs ON cs.oid = c.connamespace
1955
+ WHERE contype = 'c'
1956
+ ORDER BY c.conname`);
1957
+ for (const row of rows) {
1958
+ if (row.expression[0] === "(" && row.expression[row.expression.length - 1] === ")") {
1959
+ row.expression = row.expression.slice(1, -1);
1960
+ }
1961
+ }
1962
+ return rows;
1963
+ }
1964
+ async getDomains() {
1965
+ const { rows } = await this.db.query(`SELECT
1966
+ n.nspname AS "schemaName",
1967
+ d.typname AS "name",
1968
+ t.typname AS "type",
1969
+ s.nspname AS "typeSchema",
1970
+ .typnotnull AS "notNull",
1971
+ d.typcategory = 'A' AS "isArray",
1972
+ character_maximum_length AS "maxChars",
1973
+ numeric_precision AS "numericPrecision",
1974
+ numeric_scale AS "numericScale",
1975
+ datetime_precision AS "dateTimePrecision",
1976
+ collation_name AS "collation",
1977
+ domain_default AS "default",
1978
+ pg_get_expr(conbin, conrelid) AS "expression"
1979
+ FROM pg_catalog.pg_type d
1980
+ JOIN pg_catalog.pg_namespace n ON n.oid = d.typnamespace
1981
+ JOIN information_schema.domains i
1982
+ ON i.domain_schema = nspname
1983
+ AND i.domain_name = d.typname
1984
+ JOIN pg_catalog.pg_type t
1985
+ ON (
1986
+ CASE WHEN d.typcategory = 'A'
1987
+ THEN t.typarray
1988
+ ELSE t.oid
1989
+ END
1990
+ ) = d.typbasetype
1991
+ JOIN pg_catalog.pg_namespace s ON s.oid = t.typnamespace
1992
+ LEFT JOIN pg_catalog.pg_constraint c ON c.contypid = d.oid
1993
+ WHERE d.typtype = 'd' AND ${filterSchema("n.nspname")}`);
1994
+ return rows;
1995
+ }
1867
1996
  }
1868
1997
 
1869
1998
  var __defProp = Object.defineProperty;
@@ -1885,6 +2014,18 @@ var __spreadValues = (a, b) => {
1885
2014
  return a;
1886
2015
  };
1887
2016
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2017
+ var __objRest = (source, exclude) => {
2018
+ var target = {};
2019
+ for (var prop in source)
2020
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
2021
+ target[prop] = source[prop];
2022
+ if (source != null && __getOwnPropSymbols)
2023
+ for (var prop of __getOwnPropSymbols(source)) {
2024
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
2025
+ target[prop] = source[prop];
2026
+ }
2027
+ return target;
2028
+ };
1888
2029
  class RakeDbEnumColumn extends pqb.EnumColumn {
1889
2030
  toCode(t) {
1890
2031
  return pqb.columnCode(this, t, `enum('${this.enumName}')`);
@@ -1928,10 +2069,21 @@ const structureToAst = async (db) => {
1928
2069
  }
1929
2070
  pendingTables[key] = { table, dependsOn };
1930
2071
  }
2072
+ const domains = {};
2073
+ for (const it of data.domains) {
2074
+ domains[`${it.schemaName}.${it.name}`] = getColumn(data, domains, {
2075
+ schemaName: it.schemaName,
2076
+ name: it.name,
2077
+ type: it.type,
2078
+ typeSchema: it.typeSchema,
2079
+ isArray: it.isArray,
2080
+ isSerial: false
2081
+ });
2082
+ }
1931
2083
  for (const key in pendingTables) {
1932
2084
  const { table, dependsOn } = pendingTables[key];
1933
2085
  if (!dependsOn.size) {
1934
- pushTableAst(ast, data, table, pendingTables);
2086
+ pushTableAst(ast, data, domains, table, pendingTables);
1935
2087
  }
1936
2088
  }
1937
2089
  const outerFKeys = [];
@@ -1953,6 +2105,19 @@ const structureToAst = async (db) => {
1953
2105
  values: it.values
1954
2106
  });
1955
2107
  }
2108
+ for (const it of data.domains) {
2109
+ ast.push({
2110
+ type: "domain",
2111
+ action: "create",
2112
+ schema: it.schemaName === "public" ? void 0 : it.schemaName,
2113
+ name: it.name,
2114
+ baseType: domains[`${it.schemaName}.${it.name}`],
2115
+ notNull: it.notNull,
2116
+ collation: it.collation,
2117
+ default: it.default ? orchidCore.raw(it.default) : void 0,
2118
+ check: it.check ? orchidCore.raw(it.check) : void 0
2119
+ });
2120
+ }
1956
2121
  for (const key in pendingTables) {
1957
2122
  const innerFKeys = [];
1958
2123
  const { table } = pendingTables[key];
@@ -1966,7 +2131,7 @@ const structureToAst = async (db) => {
1966
2131
  outerFKeys.push([fkey, table]);
1967
2132
  }
1968
2133
  }
1969
- pushTableAst(ast, data, table, pendingTables, innerFKeys);
2134
+ pushTableAst(ast, data, domains, table, pendingTables, innerFKeys);
1970
2135
  }
1971
2136
  for (const [fkey, table] of outerFKeys) {
1972
2137
  ast.push(__spreadProps(__spreadValues({}, foreignKeyToAst(fkey)), {
@@ -1987,7 +2152,9 @@ const getData = async (db) => {
1987
2152
  indexes,
1988
2153
  foreignKeys,
1989
2154
  extensions,
1990
- enums
2155
+ enums,
2156
+ checks,
2157
+ domains
1991
2158
  ] = await Promise.all([
1992
2159
  db.getSchemas(),
1993
2160
  db.getTables(),
@@ -1996,7 +2163,9 @@ const getData = async (db) => {
1996
2163
  db.getIndexes(),
1997
2164
  db.getForeignKeys(),
1998
2165
  db.getExtensions(),
1999
- db.getEnums()
2166
+ db.getEnums(),
2167
+ db.getChecks(),
2168
+ db.getDomains()
2000
2169
  ]);
2001
2170
  return {
2002
2171
  schemas,
@@ -2006,7 +2175,9 @@ const getData = async (db) => {
2006
2175
  indexes,
2007
2176
  foreignKeys,
2008
2177
  extensions,
2009
- enums
2178
+ enums,
2179
+ checks,
2180
+ domains
2010
2181
  };
2011
2182
  };
2012
2183
  const makeBelongsToTable = (schema, table) => (item) => item.schemaName === schema && item.tableName === table;
@@ -2020,12 +2191,52 @@ const getIsSerial = (item) => {
2020
2191
  }
2021
2192
  return false;
2022
2193
  };
2194
+ const getColumn = (data, domains, _a) => {
2195
+ var _b = _a, {
2196
+ schemaName,
2197
+ tableName,
2198
+ name,
2199
+ type,
2200
+ typeSchema,
2201
+ isArray,
2202
+ isSerial
2203
+ } = _b, params = __objRest(_b, [
2204
+ "schemaName",
2205
+ "tableName",
2206
+ "name",
2207
+ "type",
2208
+ "typeSchema",
2209
+ "isArray",
2210
+ "isSerial"
2211
+ ]);
2212
+ let column;
2213
+ const klass = pqb.columnsByType[getColumnType(type, isSerial)];
2214
+ if (klass) {
2215
+ column = pqb.instantiateColumn(klass, params);
2216
+ } else {
2217
+ const domainColumn = domains[`${typeSchema}.${type}`];
2218
+ if (domainColumn) {
2219
+ column = new pqb.DomainColumn({}, type).as(domainColumn);
2220
+ } else {
2221
+ const enumType = data.enums.find(
2222
+ (item) => item.name === type && item.schemaName === typeSchema
2223
+ );
2224
+ if (!enumType) {
2225
+ throw new Error(
2226
+ `Cannot handle ${tableName ? "column" : "domain"} ${schemaName}${tableName ? `.${tableName}` : ""}.${name}: column type \`${type}\` is not supported`
2227
+ );
2228
+ }
2229
+ column = new RakeDbEnumColumn({}, type, enumType.values);
2230
+ }
2231
+ }
2232
+ return isArray ? new pqb.ArrayColumn({}, column) : column;
2233
+ };
2023
2234
  const getColumnType = (type, isSerial) => {
2024
2235
  if (!isSerial)
2025
2236
  return type;
2026
2237
  return type === "int2" ? "smallserial" : type === "int4" ? "serial" : "bigserial";
2027
2238
  };
2028
- const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreignKeys) => {
2239
+ const pushTableAst = (ast, data, domains, table, pendingTables, innerFKeys = data.foreignKeys) => {
2029
2240
  const { schemaName, name } = table;
2030
2241
  const key = `${schemaName}.${table.name}`;
2031
2242
  delete pendingTables[key];
@@ -2036,32 +2247,24 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2036
2247
  const primaryKey = data.primaryKeys.find(belongsToTable);
2037
2248
  const tableIndexes = data.indexes.filter(belongsToTable);
2038
2249
  const tableForeignKeys = innerFKeys.filter(belongsToTable);
2250
+ const columnChecks = {};
2251
+ for (const check of data.checks) {
2252
+ if (check.columnNames.length === 1) {
2253
+ columnChecks[check.columnNames[0]] = check;
2254
+ }
2255
+ }
2039
2256
  const shape = {};
2040
2257
  for (let item of columns) {
2041
2258
  const isSerial = getIsSerial(item);
2042
2259
  if (isSerial) {
2043
2260
  item = __spreadProps(__spreadValues({}, item), { default: void 0 });
2044
2261
  }
2045
- let column;
2046
2262
  const isArray = item.dataType === "ARRAY";
2047
- const type = isArray ? item.type.slice(1) : item.type;
2048
- const klass = pqb.columnsByType[getColumnType(type, isSerial)];
2049
- if (klass) {
2050
- column = pqb.instantiateColumn(klass, item);
2051
- } else {
2052
- const { type: type2, typeSchema } = item;
2053
- const enumType = data.enums.find(
2054
- (item2) => item2.name === type2 && item2.schemaName === typeSchema
2055
- );
2056
- if (!enumType) {
2057
- throw new Error(
2058
- `Cannot handle column ${item.schemaName}.${item.tableName}.${item.name}: column type \`${item.type}\` is not supported`
2059
- );
2060
- }
2061
- column = new RakeDbEnumColumn({}, type2, enumType.values);
2062
- }
2063
- if (isArray)
2064
- column = new pqb.ArrayColumn({}, column);
2263
+ let column = getColumn(data, domains, __spreadProps(__spreadValues({}, item), {
2264
+ type: isArray ? item.type.slice(1) : item.type,
2265
+ isArray,
2266
+ isSerial
2267
+ }));
2065
2268
  if ((primaryKey == null ? void 0 : primaryKey.columnNames.length) === 1 && (primaryKey == null ? void 0 : primaryKey.columnNames[0]) === item.name) {
2066
2269
  column = column.primaryKey();
2067
2270
  }
@@ -2098,6 +2301,10 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2098
2301
  }
2099
2302
  );
2100
2303
  }
2304
+ const check = columnChecks[item.name];
2305
+ if (check) {
2306
+ column.data.check = orchidCore.raw(check.expression);
2307
+ }
2101
2308
  delete column.data.name;
2102
2309
  shape[item.name] = column;
2103
2310
  }
@@ -2136,7 +2343,7 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2136
2343
  for (const otherKey in pendingTables) {
2137
2344
  const item = pendingTables[otherKey];
2138
2345
  if (item.dependsOn.delete(key) && item.dependsOn.size === 0) {
2139
- pushTableAst(ast, data, item.table, pendingTables);
2346
+ pushTableAst(ast, data, domains, item.table, pendingTables);
2140
2347
  }
2141
2348
  }
2142
2349
  };
@@ -2166,7 +2373,11 @@ const astToMigration = (config, ast) => {
2166
2373
  } else if (item.type === "enum" && item.action === "create") {
2167
2374
  if (first.length)
2168
2375
  first.push([]);
2169
- first.push(...createEnum(item));
2376
+ first.push(createEnum(item));
2377
+ } else if (item.type === "domain" && item.action === "create") {
2378
+ if (first.length)
2379
+ first.push([]);
2380
+ first.push(...createDomain(item));
2170
2381
  } else if (item.type === "table" && item.action === "create") {
2171
2382
  tables.push(createTable(config, item));
2172
2383
  } else if (item.type === "foreignKey") {
@@ -2223,12 +2434,26 @@ const createExtension = (ast) => {
2223
2434
  return code;
2224
2435
  };
2225
2436
  const createEnum = (ast) => {
2437
+ return `await db.createEnum(${quoteSchemaTable(ast)}, [${ast.values.map(orchidCore.singleQuote).join(", ")}]);`;
2438
+ };
2439
+ const createDomain = (ast) => {
2226
2440
  const code = [
2227
- `await db.createEnum(${orchidCore.singleQuote(ast.name)}, [${ast.values.map(orchidCore.singleQuote).join(", ")}]`
2441
+ `await db.createDomain(${quoteSchemaTable(
2442
+ ast
2443
+ )}, (t) => ${ast.baseType.toCode("t")}`
2228
2444
  ];
2229
- if (ast.schema) {
2445
+ if (ast.notNull || ast.collation || ast.default || ast.check) {
2446
+ const props = [];
2447
+ if (ast.notNull)
2448
+ props.push(`notNull: true,`);
2449
+ if (ast.collation)
2450
+ props.push(`collation: ${orchidCore.singleQuote(ast.collation)},`);
2451
+ if (ast.default)
2452
+ props.push(`default: ${pqb.rawToCode("db", ast.default)},`);
2453
+ if (ast.check)
2454
+ props.push(`check: ${pqb.rawToCode("db", ast.check)},`);
2230
2455
  orchidCore.addCode(code, ", {");
2231
- code.push([`schema: ${orchidCore.singleQuote(ast.schema)},`]);
2456
+ code.push(props);
2232
2457
  orchidCore.addCode(code, "}");
2233
2458
  }
2234
2459
  orchidCore.addCode(code, ");");