rake-db 2.37.0 → 2.37.2

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
@@ -371,7 +371,8 @@ const primaryKeyToSql = (primaryKey) => {
371
371
  };
372
372
  const interpolateSqlValues = ({ text, values }) => {
373
373
  return values?.length ? text.replace(/\$(\d+)/g, (_, n) => {
374
- return escapeForMigration(values[+n - 1]);
374
+ const i = +n - 1;
375
+ return escapeForMigration(values[i]);
375
376
  }) : text;
376
377
  };
377
378
  const nameColumnChecks = (table, column, checks) => checks.map((check, i) => ({
@@ -493,7 +494,7 @@ const makeAst$5 = (schema, up, tableName, shape, tableData, options, noPrimaryKe
493
494
  ...tableData,
494
495
  primaryKey: shapePKeys.length <= 1 ? primaryKey : primaryKey ? {
495
496
  ...primaryKey,
496
- columns: [...new Set([...shapePKeys, ...primaryKey.columns])]
497
+ columns: [.../* @__PURE__ */ new Set([...shapePKeys, ...primaryKey.columns])]
497
498
  } : { columns: shapePKeys },
498
499
  ...options,
499
500
  noPrimaryKey: options.noPrimaryKey ? "ignore" : noPrimaryKey || "error"
@@ -879,6 +880,25 @@ const makeTableChangeMethods = (tableMethods) => ({
879
880
  to: { comment }
880
881
  };
881
882
  },
883
+ /**
884
+ * Rename a column:
885
+ *
886
+ * ```ts
887
+ * import { change } from '../dbScript';
888
+ *
889
+ * change(async (db) => {
890
+ * await db.changeTable('table', (t) => ({
891
+ * oldColumnName: t.rename('newColumnName'),
892
+ * }));
893
+ * });
894
+ * ```
895
+ *
896
+ * Note that the renaming `ALTER TABLE` is executed before the rest of alterations,
897
+ * so if you're also adding a new constraint on this column inside the same `changeTable`,
898
+ * refer to it with a new name.
899
+ *
900
+ * @param name
901
+ */
882
902
  rename(name) {
883
903
  return {
884
904
  type: "rename",
@@ -897,7 +917,8 @@ const changeTable = async (migration, tableChangeMethods, up, tableName, options
897
917
  standaloneCheckChanges.length = 0;
898
918
  const changeData = fn?.(tableChanger) || {};
899
919
  const schema = migration.adapter.getSchema();
900
- const queries = astToQueries(schema, makeAst$4(schema, up, tableName, changeData, changeTableData, options), snakeCase, language);
920
+ const ast = makeAst$4(schema, up, tableName, changeData, changeTableData, options);
921
+ const queries = astToQueries(schema, ast, snakeCase, language);
901
922
  for (const query of queries) {
902
923
  const result = await migration.adapter.arrays(interpolateSqlValues(query));
903
924
  query.then?.(result);
@@ -1176,7 +1197,9 @@ const renameColumnSql = (from, to) => {
1176
1197
  return `RENAME COLUMN "${from}" TO "${to}"`;
1177
1198
  };
1178
1199
  const createView = async (migration, up, name, options, sql) => {
1179
- const query = astToQuery$2(makeAst$3(migration.adapter.getSchema(), up, name, options, sql));
1200
+ const schema = migration.adapter.getSchema();
1201
+ const ast = makeAst$3(schema, up, name, options, sql);
1202
+ const query = astToQuery$2(ast);
1180
1203
  await migration.adapter.arrays(interpolateSqlValues(query));
1181
1204
  };
1182
1205
  const makeAst$3 = (schema, up, fullName, options, sql) => {
@@ -1223,12 +1246,15 @@ const astToQuery$2 = (ast) => {
1223
1246
  };
1224
1247
  };
1225
1248
  const createMaterializedView = async (migration, up, name, options, sql) => {
1226
- const query = astToQuery$1(makeAst$2(migration.adapter.getSchema(), up, name, options, sql));
1249
+ const schema = migration.adapter.getSchema();
1250
+ const ast = makeAst$2(schema, up, name, options, sql);
1251
+ const query = astToQuery$1(ast);
1227
1252
  await migration.adapter.arrays(interpolateSqlValues(query));
1228
1253
  };
1229
1254
  const refreshMaterializedView = async (migration, name, options = {}) => {
1230
1255
  if (options.concurrently && options.withData === false) throw new Error("Cannot refresh a materialized view concurrently with WITH NO DATA");
1231
- const [s, viewName] = getSchemaAndTableFromName(migration.adapter.getSchema(), name);
1256
+ const schema = migration.adapter.getSchema();
1257
+ const [s, viewName] = getSchemaAndTableFromName(schema, name);
1232
1258
  const sql = ["REFRESH MATERIALIZED VIEW"];
1233
1259
  if (options.concurrently) sql.push("CONCURRENTLY");
1234
1260
  sql.push(`${s ? `"${s}".` : ""}"${viewName}"`);
@@ -1286,7 +1312,8 @@ const serializers = {
1286
1312
  validUntil: (value) => `VALID UNTIL '${value === void 0 ? "infinity" : value}'`
1287
1313
  };
1288
1314
  const createOrDropRole = async (migration, up, name, params) => {
1289
- const sql = astToQuery(makeAst$1(up, name, params));
1315
+ const ast = makeAst$1(up, name, params);
1316
+ const sql = astToQuery(ast);
1290
1317
  await migration.adapter.arrays(sql);
1291
1318
  };
1292
1319
  const makeAst$1 = (up, name, params) => {
@@ -1338,7 +1365,8 @@ const changeRole = async (migration, up, name, from, to) => {
1338
1365
  for (const key in from.config) if (!(key in config)) config[key] = void 0;
1339
1366
  }
1340
1367
  }
1341
- const sql = changeAstToQuery(makeChangeAst(name, from, to));
1368
+ const ast = makeChangeAst(name, from, to);
1369
+ const sql = changeAstToQuery(ast);
1342
1370
  if (sql) await migration.adapter.arrays(sql);
1343
1371
  };
1344
1372
  const makeChangeAst = (name, from, to) => {
@@ -1377,7 +1405,8 @@ const renameRole = async (migration, up, from, to) => {
1377
1405
  from = to;
1378
1406
  to = f;
1379
1407
  }
1380
- const sql = renameAstToQuery(makeRenameAst(from, to));
1408
+ const ast = makeRenameAst(from, to);
1409
+ const sql = renameAstToQuery(ast);
1381
1410
  if (sql) await migration.adapter.arrays(sql);
1382
1411
  };
1383
1412
  const makeRenameAst = (from, to) => ({
@@ -1429,7 +1458,8 @@ const filterAndTransformConfig = (config, schema) => {
1429
1458
  return Object.keys(result).length ? result : void 0;
1430
1459
  };
1431
1460
  const changeDefaultPrivileges = async (migration, up, arg) => {
1432
- const sql = astToSql(makeAst(up, arg));
1461
+ const ast = makeAst(up, arg);
1462
+ const sql = astToSql(ast);
1433
1463
  if (sql.length) await migration.adapter.arrays(sql.join(";\n"));
1434
1464
  };
1435
1465
  const makeAst = (up, arg) => {
@@ -1582,7 +1612,9 @@ const recreatePolicy = async (migration, tableName, policyName, from, to) => {
1582
1612
  const fromTable = from.table ?? tableName;
1583
1613
  const fromName = from.name ?? policyName;
1584
1614
  await migration.adapter.arrays(dropPolicySql(migration, fromTable, fromName));
1585
- const { text, values } = createPolicySql(migration, to.table ?? tableName, to.name ?? policyName, to);
1615
+ const toTable = to.table ?? tableName;
1616
+ const toName = to.name ?? policyName;
1617
+ const { text, values } = createPolicySql(migration, toTable, toName, to);
1586
1618
  await migration.adapter.arrays(text, values);
1587
1619
  };
1588
1620
  const changePolicy = async (migration, up, tableName, policyName, params) => {
@@ -1610,18 +1642,19 @@ const schemaOrDatabaseTargetKeyToSql = {
1610
1642
  schemas: "SCHEMA",
1611
1643
  databases: "DATABASE"
1612
1644
  };
1613
- const specialRoleSpecs = new Set([
1645
+ const specialRoleSpecs = /* @__PURE__ */ new Set([
1614
1646
  "PUBLIC",
1615
1647
  "CURRENT_ROLE",
1616
1648
  "CURRENT_USER",
1617
1649
  "SESSION_USER"
1618
1650
  ]);
1619
1651
  const changeGrant = async (migration, up, params) => {
1620
- const sql = privilegeToSql(migration, {
1652
+ const ast = {
1621
1653
  ...params,
1622
1654
  to: typeof params.to === "string" ? [params.to] : params.to,
1623
1655
  action: up ? "grant" : "revoke"
1624
- });
1656
+ };
1657
+ const sql = privilegeToSql(migration, ast);
1625
1658
  if (sql.length) await migration.adapter.arrays(sql.join(";\n"));
1626
1659
  };
1627
1660
  const privilegeToSql = (migration, ast) => {
@@ -1746,7 +1779,10 @@ const createMigrationInterface = (tx, up, config) => {
1746
1779
  var Migration = class {
1747
1780
  getTableMethods() {
1748
1781
  let { tableMethods } = this;
1749
- if (!tableMethods) tableMethods = makeTableMethods(defaultSchemaConfig());
1782
+ if (!tableMethods) {
1783
+ const schemaConfig = defaultSchemaConfig();
1784
+ tableMethods = makeTableMethods(schemaConfig);
1785
+ }
1750
1786
  return tableMethods;
1751
1787
  }
1752
1788
  getTableChangeMethods() {
@@ -2827,7 +2863,8 @@ const addOrDropEnumValues = async (migration, up, enumName, values, options) =>
2827
2863
  return;
2828
2864
  }
2829
2865
  const { rows: valuesRows } = await migration.adapter.query(`SELECT unnest(enum_range(NULL::${quotedName}))::text value`);
2830
- await recreateEnum(migration, ast, valuesRows.map((r) => r.value).filter((v) => !ast.values.includes(v)), (quotedName, table, column) => `Cannot drop ${quotedName} enum values [${ast.values.map(singleQuote).join(", ")}]: table ${table} has a row with such value in the column "${column}"`);
2866
+ const existingValues = valuesRows.map((r) => r.value);
2867
+ await recreateEnum(migration, ast, existingValues.filter((v) => !ast.values.includes(v)), (quotedName, table, column) => `Cannot drop ${quotedName} enum values [${ast.values.map(singleQuote).join(", ")}]: table ${table} has a row with such value in the column "${column}"`);
2831
2868
  };
2832
2869
  const changeEnumValues = async (migration, enumName, fromValues, toValues) => {
2833
2870
  const [schema, name] = getSchemaAndTableFromName(migration.adapter.getSchema(), enumName);
@@ -2884,11 +2921,13 @@ GROUP BY n.nspname, c.relname`);
2884
2921
  const writeMigrationFile = async (config, version, name, migrationCode) => {
2885
2922
  await mkdir(config.migrationsPath, { recursive: true });
2886
2923
  const filePath = path.resolve(config.migrationsPath, `${version}_${name.replaceAll(" ", "-")}.ts`);
2887
- await writeFile(filePath, `import { change } from '${getImportPath(filePath, path.join(config.basePath, config.dbScript))}';\n${migrationCode}`);
2924
+ const importPath = getImportPath(filePath, path.join(config.basePath, config.dbScript));
2925
+ await writeFile(filePath, `import { change } from '${importPath}';\n${migrationCode}`);
2888
2926
  config.logger?.log(`Created ${pathToLog(filePath)}`);
2889
2927
  };
2890
2928
  const newMigration = async (config, name) => {
2891
- await writeMigrationFile(config, await makeFileVersion({}, config), name, makeContent(name));
2929
+ const version = await makeFileVersion({}, config);
2930
+ await writeMigrationFile(config, version, name, makeContent(name));
2892
2931
  };
2893
2932
  const makeFileVersion = async (ctx, config) => {
2894
2933
  if (config.migrationId === "timestamp") return generateTimeStamp();
@@ -3203,7 +3242,8 @@ const saveMigratedVersion = async (db, version, name, config) => {
3203
3242
  await db.silentArrays(`INSERT INTO ${migrationsSchemaTableSql(db, config)}(version, name) VALUES ($1, $2)`, [version, name]);
3204
3243
  };
3205
3244
  const createMigrationsSchemaAndTable = async (db, config) => {
3206
- const { schema, table } = getMigrationsSchemaAndTable(getMaybeTransactionAdapter(db), config);
3245
+ const adapter = getMaybeTransactionAdapter(db);
3246
+ const { schema, table } = getMigrationsSchemaAndTable(adapter, config);
3207
3247
  if (schema) {
3208
3248
  if (await createSchema(db, schema) === "done") config.logger?.log(`Created schema "${schema}"`);
3209
3249
  }
@@ -3316,12 +3356,14 @@ function makeMigrateFn(up, defaultCount, fn) {
3316
3356
  let migrations;
3317
3357
  try {
3318
3358
  await transactionIfSingle(adapter, config, async (trx) => {
3319
- migrations = await fn(trx, config, set, await getMigratedVersionsMap(ctx, trx, config, set.renameTo), count, force);
3359
+ const versions = await getMigratedVersionsMap(ctx, trx, config, set.renameTo);
3360
+ migrations = await fn(trx, config, set, versions, count, force);
3320
3361
  });
3321
3362
  } catch (err) {
3322
3363
  if (err instanceof NoMigrationsTableError) await transactionIfSingle(adapter, config, async (trx) => {
3323
3364
  await createMigrationsSchemaAndTable(trx, config);
3324
- migrations = await fn(trx, config, set, await getMigratedVersionsMap(ctx, trx, config, set.renameTo), count, force);
3365
+ const versions = await getMigratedVersionsMap(ctx, trx, config, set.renameTo);
3366
+ migrations = await fn(trx, config, set, versions, count, force);
3325
3367
  });
3326
3368
  else throw err;
3327
3369
  }
@@ -3357,9 +3399,11 @@ async function runMigration(db, ...args) {
3357
3399
  ...rawConfig,
3358
3400
  ...handleConfigLogger(rawConfig)
3359
3401
  };
3360
- await transaction(getMaybeTransactionAdapter(db), config, async (trx) => {
3402
+ const adapter = getMaybeTransactionAdapter(db);
3403
+ await transaction(adapter, config, async (trx) => {
3361
3404
  clearChanges();
3362
- await applyMigration(trx, true, await getChanges({ load: migration }), config);
3405
+ const changes = await getChanges({ load: migration });
3406
+ await applyMigration(trx, true, changes, config);
3363
3407
  });
3364
3408
  }
3365
3409
  /**
@@ -3442,7 +3486,8 @@ const migrateOrRollback = async (trx, config, set, versions, count, up, redo, fo
3442
3486
  loggedAboutStarting = true;
3443
3487
  config.logger?.log(`${redo ? "Reapplying migrations for" : up ? "Migrating" : "Rolling back"} database ${getAdapterDatabase$1(trx)}\n`);
3444
3488
  }
3445
- await changeMigratedVersion(await migrationRunner(trx, up, await getChanges(file, config), config), up, file, config);
3489
+ const adapter = await migrationRunner(trx, up, await getChanges(file, config), config);
3490
+ await changeMigratedVersion(adapter, up, file, config);
3446
3491
  (migrations ??= []).push(file);
3447
3492
  if (up) {
3448
3493
  const name = path.basename(file.path);
@@ -3823,11 +3868,12 @@ const astToGenerateItem = (config, ast, currentSchema) => {
3823
3868
  const keys = ast.action === "create" ? add : drop;
3824
3869
  keys.push(table);
3825
3870
  deps.push(schema);
3826
- analyzeTableColumns(config, currentSchema, schema, table, deps, resolveType, Object.entries(ast.shape).map(([name, column]) => [
3871
+ const columns = Object.entries(ast.shape).map(([name, column]) => [
3827
3872
  keys,
3828
3873
  name,
3829
3874
  { column }
3830
- ]));
3875
+ ]);
3876
+ analyzeTableColumns(config, currentSchema, schema, table, deps, resolveType, columns);
3831
3877
  if (ast.type === "table") analyzeTableData(config, currentSchema, schema, table, keys, deps, ast);
3832
3878
  else deps.push(...ast.deps.map(({ schemaName, name }) => `${schemaName}.${name}`));
3833
3879
  } else {
@@ -5687,9 +5733,7 @@ const viewToAst = (ctx, data, domains, view) => {
5687
5733
  case "securityBarrier":
5688
5734
  options.securityBarrier = value === "true";
5689
5735
  break;
5690
- case "securityInvoker":
5691
- options.securityInvoker = value === "true";
5692
- break;
5736
+ case "securityInvoker": options.securityInvoker = value === "true";
5693
5737
  }
5694
5738
  }
5695
5739
  return {
@@ -5837,14 +5881,16 @@ const checkIfIsOuterRecursiveFkey = (data, table, references) => {
5837
5881
  const pullDbStructure = async (adapter, config) => {
5838
5882
  const currentSchema = adapter.getSearchPath?.() ?? adapter.searchPath ?? "public";
5839
5883
  const ctx = makeStructureToAstCtx(config, currentSchema);
5840
- const result = astToMigration(currentSchema, config, await structureToAst(ctx, adapter, config));
5884
+ const ast = await structureToAst(ctx, adapter, config);
5885
+ const result = astToMigration(currentSchema, config, ast);
5841
5886
  if (!result) return;
5842
5887
  const version = await makeFileVersion({}, config);
5843
5888
  await writeMigrationFile(config, version, "pull", result);
5844
- await saveMigratedVersion(Object.assign(adapter, {
5889
+ const silentQueries = Object.assign(adapter, {
5845
5890
  silentQuery: adapter.query,
5846
5891
  silentArrays: adapter.arrays
5847
- }), version, "pull", config);
5892
+ });
5893
+ await saveMigratedVersion(silentQueries, version, "pull", config);
5848
5894
  const unsupportedEntries = Object.entries(ctx.unsupportedTypes);
5849
5895
  if (unsupportedEntries.length) {
5850
5896
  let count = 0;
@@ -6094,7 +6140,8 @@ const rakeDbCommands = {
6094
6140
  },
6095
6141
  status: {
6096
6142
  run(adapters, config, args) {
6097
- return listMigrationsStatuses(adapters, config, { showUrl: args.includes("p") || args.includes("path") });
6143
+ const showUrl = args.includes("p") || args.includes("path");
6144
+ return listMigrationsStatuses(adapters, config, { showUrl });
6098
6145
  },
6099
6146
  help: "list migrations statuses",
6100
6147
  helpArguments: {