rake-db 2.4.6 → 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 } 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[];
@@ -216,8 +219,9 @@ declare const createDb: (arg: MaybeArray<AdapterOptions>, config: RakeDbConfig)
216
219
  declare const dropDb: (arg: MaybeArray<AdapterOptions>) => Promise<void>;
217
220
  declare const resetDb: (arg: MaybeArray<AdapterOptions>, config: RakeDbConfig) => Promise<void>;
218
221
 
219
- declare const writeMigrationFile: (config: RakeDbConfig, name: string, content: string) => Promise<void>;
222
+ declare const writeMigrationFile: (config: RakeDbConfig, version: string, name: string, content: string) => Promise<void>;
220
223
  declare const generate: (config: RakeDbConfig, args: string[]) => Promise<void>;
224
+ declare const makeFileTimeStamp: () => string;
221
225
 
222
226
  declare type ChangeCallback = (db: Migration, up: boolean) => Promise<void>;
223
227
  declare const change: (fn: ChangeCallback) => void;
@@ -229,4 +233,8 @@ declare const rollback: (options: MaybeArray<AdapterOptions>, config: RakeDbConf
229
233
 
230
234
  declare const rakeDb: (options: MaybeArray<AdapterOptions>, partialConfig?: Partial<RakeDbConfig>, args?: string[]) => Promise<void>;
231
235
 
232
- export { AppCodeUpdater, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, DropMode, Migration, MigrationBase, MigrationColumnTypes, RakeDbAst, RakeDbConfig, TableOptions, change, changeCache, createDb, createMigrationInterface, dropDb, generate, migrate, migrateOrRollback, rakeDb, resetDb, rollback, writeMigrationFile };
236
+ declare const saveMigratedVersion: (db: Adapter, version: string, config: RakeDbConfig) => Promise<void>;
237
+ declare const removeMigratedVersion: (db: Adapter, version: string, config: RakeDbConfig) => Promise<void>;
238
+ declare const getMigratedVersionsMap: (db: Adapter, config: RakeDbConfig) => Promise<Record<string, boolean>>;
239
+
240
+ export { AppCodeUpdater, ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnsShapeCallback, DropMode, Migration, MigrationBase, MigrationColumnTypes, RakeDbAst, RakeDbConfig, TableOptions, change, changeCache, createDb, createMigrationInterface, dropDb, generate, getMigratedVersionsMap, makeFileTimeStamp, migrate, migrateOrRollback, rakeDb, removeMigratedVersion, resetDb, rollback, saveMigratedVersion, writeMigrationFile };
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
@@ -1250,6 +1284,36 @@ const queryExists = (db, sql) => {
1250
1284
  return db.adapter.query(sql).then(({ rowCount }) => rowCount > 0);
1251
1285
  };
1252
1286
 
1287
+ const saveMigratedVersion = async (db, version, config) => {
1288
+ await db.query(
1289
+ `INSERT INTO ${quoteWithSchema({
1290
+ name: config.migrationsTable
1291
+ })} VALUES ('${version}')`
1292
+ );
1293
+ };
1294
+ const removeMigratedVersion = async (db, version, config) => {
1295
+ await db.query(
1296
+ `DELETE FROM ${quoteWithSchema({
1297
+ name: config.migrationsTable
1298
+ })} WHERE version = '${version}'`
1299
+ );
1300
+ };
1301
+ const getMigratedVersionsMap = async (db, config) => {
1302
+ try {
1303
+ const result = await db.arrays(
1304
+ `SELECT *
1305
+ FROM ${quoteWithSchema({ name: config.migrationsTable })}`
1306
+ );
1307
+ return Object.fromEntries(result.rows.map((row) => [row[0], true]));
1308
+ } catch (err) {
1309
+ if (err.code === "42P01") {
1310
+ await createSchemaMigrations(db, config);
1311
+ return {};
1312
+ }
1313
+ throw err;
1314
+ }
1315
+ };
1316
+
1253
1317
  var __defProp$1 = Object.defineProperty;
1254
1318
  var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
1255
1319
  var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
@@ -1362,34 +1426,6 @@ const processMigration = async (db, up, file, config, options, appCodeUpdaterCac
1362
1426
  }));
1363
1427
  }
1364
1428
  };
1365
- const saveMigratedVersion = async (db, version, config) => {
1366
- await db.query(
1367
- `INSERT INTO ${quoteWithSchema({
1368
- name: config.migrationsTable
1369
- })} VALUES ('${version}')`
1370
- );
1371
- };
1372
- const removeMigratedVersion = async (db, version, config) => {
1373
- await db.query(
1374
- `DELETE FROM ${quoteWithSchema({
1375
- name: config.migrationsTable
1376
- })} WHERE version = '${version}'`
1377
- );
1378
- };
1379
- const getMigratedVersionsMap = async (db, config) => {
1380
- try {
1381
- const result = await db.arrays(
1382
- `SELECT * FROM ${quoteWithSchema({ name: config.migrationsTable })}`
1383
- );
1384
- return Object.fromEntries(result.rows.map((row) => [row[0], true]));
1385
- } catch (err) {
1386
- if (err.code === "42P01") {
1387
- await createSchemaMigrations(db, config);
1388
- return {};
1389
- }
1390
- throw err;
1391
- }
1392
- };
1393
1429
  const migrate = (options, config, args = []) => migrateOrRollback(options, config, args, true);
1394
1430
  const rollback = (options, config, args = []) => migrateOrRollback(options, config, args, false);
1395
1431
 
@@ -1493,13 +1529,10 @@ const resetDb = async (arg, config) => {
1493
1529
  await migrate(arg, config);
1494
1530
  };
1495
1531
 
1496
- const writeMigrationFile = async (config, name, content) => {
1532
+ const writeMigrationFile = async (config, version, name, content) => {
1497
1533
  var _a;
1498
1534
  await promises.mkdir(config.migrationsPath, { recursive: true });
1499
- const filePath = path__default["default"].resolve(
1500
- config.migrationsPath,
1501
- `${makeFileTimeStamp()}_${name}.ts`
1502
- );
1535
+ const filePath = path__default["default"].resolve(config.migrationsPath, `${version}_${name}.ts`);
1503
1536
  await promises.writeFile(filePath, content);
1504
1537
  (_a = config.logger) == null ? void 0 : _a.log(`Created ${orchidCore.pathToLog(filePath)}`);
1505
1538
  };
@@ -1507,7 +1540,13 @@ const generate = async (config, args) => {
1507
1540
  const name = args[0];
1508
1541
  if (!name)
1509
1542
  throw new Error("Migration name is missing");
1510
- await writeMigrationFile(config, name, makeContent(name, args.slice(1)));
1543
+ const version = makeFileTimeStamp();
1544
+ await writeMigrationFile(
1545
+ config,
1546
+ version,
1547
+ name,
1548
+ makeContent(name, args.slice(1))
1549
+ );
1511
1550
  };
1512
1551
  const makeFileTimeStamp = () => {
1513
1552
  const now = new Date();
@@ -1859,6 +1898,31 @@ GROUP BY n.nspname, t.typname`
1859
1898
  );
1860
1899
  return rows;
1861
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
+ }
1862
1926
  }
1863
1927
 
1864
1928
  var __defProp = Object.defineProperty;
@@ -1982,7 +2046,8 @@ const getData = async (db) => {
1982
2046
  indexes,
1983
2047
  foreignKeys,
1984
2048
  extensions,
1985
- enums
2049
+ enums,
2050
+ checks
1986
2051
  ] = await Promise.all([
1987
2052
  db.getSchemas(),
1988
2053
  db.getTables(),
@@ -1991,7 +2056,8 @@ const getData = async (db) => {
1991
2056
  db.getIndexes(),
1992
2057
  db.getForeignKeys(),
1993
2058
  db.getExtensions(),
1994
- db.getEnums()
2059
+ db.getEnums(),
2060
+ db.getChecks()
1995
2061
  ]);
1996
2062
  return {
1997
2063
  schemas,
@@ -2001,7 +2067,8 @@ const getData = async (db) => {
2001
2067
  indexes,
2002
2068
  foreignKeys,
2003
2069
  extensions,
2004
- enums
2070
+ enums,
2071
+ checks
2005
2072
  };
2006
2073
  };
2007
2074
  const makeBelongsToTable = (schema, table) => (item) => item.schemaName === schema && item.tableName === table;
@@ -2031,6 +2098,12 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2031
2098
  const primaryKey = data.primaryKeys.find(belongsToTable);
2032
2099
  const tableIndexes = data.indexes.filter(belongsToTable);
2033
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
+ }
2034
2107
  const shape = {};
2035
2108
  for (let item of columns) {
2036
2109
  const isSerial = getIsSerial(item);
@@ -2093,6 +2166,10 @@ const pushTableAst = (ast, data, table, pendingTables, innerFKeys = data.foreign
2093
2166
  }
2094
2167
  );
2095
2168
  }
2169
+ const check = columnChecks[item.name];
2170
+ if (check) {
2171
+ column.data.check = orchidCore.raw(check.expression);
2172
+ }
2096
2173
  delete column.data.name;
2097
2174
  shape[item.name] = column;
2098
2175
  }
@@ -2293,7 +2370,9 @@ const pullDbStructure = async (options, config) => {
2293
2370
  const result = astToMigration(config, ast);
2294
2371
  if (!result)
2295
2372
  return;
2296
- await writeMigrationFile(config, "pull", result);
2373
+ const version = makeFileTimeStamp();
2374
+ await writeMigrationFile(config, version, "pull", result);
2375
+ await saveMigratedVersion(adapter, version, config);
2297
2376
  const cache = {};
2298
2377
  for (const item of ast) {
2299
2378
  await ((_a = config == null ? void 0 : config.appCodeUpdater) == null ? void 0 : _a.call(config, {
@@ -2381,10 +2460,14 @@ exports.createDb = createDb;
2381
2460
  exports.createMigrationInterface = createMigrationInterface;
2382
2461
  exports.dropDb = dropDb;
2383
2462
  exports.generate = generate;
2463
+ exports.getMigratedVersionsMap = getMigratedVersionsMap;
2464
+ exports.makeFileTimeStamp = makeFileTimeStamp;
2384
2465
  exports.migrate = migrate;
2385
2466
  exports.migrateOrRollback = migrateOrRollback;
2386
2467
  exports.rakeDb = rakeDb;
2468
+ exports.removeMigratedVersion = removeMigratedVersion;
2387
2469
  exports.resetDb = resetDb;
2388
2470
  exports.rollback = rollback;
2471
+ exports.saveMigratedVersion = saveMigratedVersion;
2389
2472
  exports.writeMigrationFile = writeMigrationFile;
2390
2473
  //# sourceMappingURL=index.js.map