rake-db 2.33.4 → 2.33.5

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
@@ -1203,6 +1203,22 @@ const buildQuery = (ast, objectType, privileges, grantable, action) => {
1203
1203
  } else parts.push(`REVOKE ${privilegeList} ON ${objectTypeToSql[objectType]} FROM "${ast.grantee}"`);
1204
1204
  return parts.join(" ");
1205
1205
  };
1206
+ const actionToSql = {
1207
+ enable: "ENABLE ROW LEVEL SECURITY",
1208
+ disable: "DISABLE ROW LEVEL SECURITY",
1209
+ force: "FORCE ROW LEVEL SECURITY",
1210
+ noForce: "NO FORCE ROW LEVEL SECURITY"
1211
+ };
1212
+ const setRls = async (migration, tableName, action) => {
1213
+ const [schema, table] = getSchemaAndTableFromName(migration.adapter.getSchema(), tableName);
1214
+ await migration.adapter.arrays(`ALTER TABLE ${quoteTable(schema, table)} ${actionToSql[action]}`);
1215
+ };
1216
+ const enableOrDisableRls = (migration, up, tableName) => {
1217
+ return setRls(migration, tableName, up ? "enable" : "disable");
1218
+ };
1219
+ const forceOrNoForceRls = (migration, up, tableName) => {
1220
+ return setRls(migration, tableName, up ? "force" : "noForce");
1221
+ };
1206
1222
  /**
1207
1223
  * Creates a new `db` instance that is an instance of `pqb` with mixed in migration methods from the `Migration` class.
1208
1224
  * It overrides `query` and `array` db adapter methods to intercept SQL for the logging.
@@ -2064,6 +2080,18 @@ var Migration = class {
2064
2080
  changeDefaultPrivileges(params) {
2065
2081
  return changeDefaultPrivileges(this, this.up, params);
2066
2082
  }
2083
+ enableRls(tableName) {
2084
+ return enableOrDisableRls(this, this.up, tableName);
2085
+ }
2086
+ disableRls(tableName) {
2087
+ return enableOrDisableRls(this, !this.up, tableName);
2088
+ }
2089
+ forceRls(tableName) {
2090
+ return forceOrNoForceRls(this, this.up, tableName);
2091
+ }
2092
+ noForceRls(tableName) {
2093
+ return forceOrNoForceRls(this, !this.up, tableName);
2094
+ }
2067
2095
  };
2068
2096
  const wrapWithEnhancingError = async (text, values, promise) => {
2069
2097
  try {
@@ -3408,6 +3436,11 @@ const astToGenerateItem = (config, ast, currentSchema) => {
3408
3436
  if (ast.owner) deps.push(`role:${ast.owner}`);
3409
3437
  deps.push(`role:${ast.grantee}`);
3410
3438
  break;
3439
+ case "tableRls": {
3440
+ const { schema = currentSchema } = ast;
3441
+ deps.push(schema, `${schema}.${ast.table}`);
3442
+ break;
3443
+ }
3411
3444
  default: exhaustive(ast);
3412
3445
  }
3413
3446
  return {
@@ -3873,6 +3906,13 @@ const astEncoders = {
3873
3906
  code.push(props);
3874
3907
  addCode(code, "});");
3875
3908
  return code;
3909
+ },
3910
+ tableRls(ast, _config, currentSchema) {
3911
+ const table = quoteSchemaTable({
3912
+ schema: ast.schema,
3913
+ name: ast.table
3914
+ }, currentSchema);
3915
+ return `await db.${ast.action === "enable" ? "enableRls" : ast.action === "disable" ? "disableRls" : ast.action === "force" ? "forceRls" : "noForceRls"}(${table});`;
3876
3916
  }
3877
3917
  };
3878
3918
  const roleParams = (name, ast, compare, to) => {
@@ -4005,10 +4045,18 @@ ORDER BY a.attnum`;
4005
4045
  const schemasSql = `SELECT coalesce(json_agg(nspname ORDER BY nspname), '[]')
4006
4046
  FROM pg_catalog.pg_namespace n
4007
4047
  WHERE ${filterSchema("nspname")}`;
4008
- const tablesSql = `SELECT
4048
+ const tablesSql = (rls) => `SELECT
4009
4049
  nspname AS "schemaName",
4010
4050
  relname AS "name",
4011
4051
  obj_description(c.oid) AS comment,
4052
+ ${rls ? `(SELECT json_build_object(
4053
+ 'enable', rc.relrowsecurity,
4054
+ 'force', rc.relforcerowsecurity
4055
+ )
4056
+ FROM pg_class rc
4057
+ JOIN pg_namespace nr ON nr.oid = rc.relnamespace
4058
+ WHERE rc.relname = c.relname
4059
+ AND nr.nspname = n.nspname) AS "rls",` : ""}
4012
4060
  (SELECT coalesce(json_agg(t), '[]') FROM (${columnsSql({
4013
4061
  schema: "n",
4014
4062
  table: "c",
@@ -4328,7 +4376,7 @@ const defaultPrivilegesSql = `SELECT COALESCE(json_agg(t.*), '[]') FROM (
4328
4376
  JOIN LATERAL aclexplode(d.defaclacl) ae ON true
4329
4377
  GROUP BY "grantor", "grantee", "schema", "object"
4330
4378
  ) t`;
4331
- const sql = (version, params) => `SELECT (${schemasSql}) AS "schemas", ${jsonAgg(tablesSql, "tables")}, ${jsonAgg(viewsSql, "views")}, ${jsonAgg(indexesSql, "indexes")}, ${jsonAgg(constraintsSql, "constraints")}, ${jsonAgg(triggersSql, "triggers")}, ${jsonAgg(extensionsSql, "extensions")}, ${jsonAgg(enumsSql, "enums")}, ${jsonAgg(domainsSql, "domains")}, ${jsonAgg(collationsSql(version), "collations")}${params?.roles ? `, (${roleSql(params.roles)}) AS "roles"` : ""}${params?.loadDefaultPrivileges ? `, (${defaultPrivilegesSql}) AS "defaultPrivileges"` : ""}`;
4379
+ const sql = (version, params) => `SELECT (${schemasSql}) AS "schemas", ${jsonAgg(tablesSql(params?.rls), "tables")}, ${jsonAgg(viewsSql, "views")}, ${jsonAgg(indexesSql, "indexes")}, ${jsonAgg(constraintsSql, "constraints")}, ${jsonAgg(triggersSql, "triggers")}, ${jsonAgg(extensionsSql, "extensions")}, ${jsonAgg(enumsSql, "enums")}, ${jsonAgg(domainsSql, "domains")}, ${jsonAgg(collationsSql(version), "collations")}${params?.roles ? `, (${roleSql(params.roles)}) AS "roles"` : ""}${params?.loadDefaultPrivileges ? `, (${defaultPrivilegesSql}) AS "defaultPrivileges"` : ""}`;
4332
4380
  async function getDbVersion(db) {
4333
4381
  const { rows: [{ version: versionString }] } = await db.query("SELECT version()");
4334
4382
  return +versionString.match(/\d+/)[0];
@@ -4475,6 +4523,18 @@ const structureToAst = async (ctx, adapter, config) => {
4475
4523
  for (const table of data.tables) {
4476
4524
  if (table.name === migrationsTable && table.schemaName === migrationsSchema) continue;
4477
4525
  ast.push(tableToAst(ctx, data, table, "create", domains));
4526
+ if (table.rls?.enable) ast.push({
4527
+ type: "tableRls",
4528
+ action: "enable",
4529
+ schema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
4530
+ table: table.name
4531
+ });
4532
+ if (table.rls?.force) ast.push({
4533
+ type: "tableRls",
4534
+ action: "force",
4535
+ schema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
4536
+ table: table.name
4537
+ });
4478
4538
  }
4479
4539
  for (const it of data.extensions) ast.push({
4480
4540
  type: "extension",