rake-db 2.36.6 → 2.36.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.mjs CHANGED
@@ -404,7 +404,7 @@ const createTable$1 = async (migration, tableMethods, up, tableName, first, seco
404
404
  });
405
405
  } else shape = tableData = emptyObject;
406
406
  const schema = migration.adapter.getSchema();
407
- const ast = makeAst$4(schema, up, tableName, shape, tableData, options, migration.options.noPrimaryKey);
407
+ const ast = makeAst$5(schema, up, tableName, shape, tableData, options, migration.options.noPrimaryKey);
408
408
  fn && validatePrimaryKey(ast);
409
409
  const queries = astToQueries$1(schema, ast, snakeCase, language);
410
410
  for (const { then, ...query } of queries) {
@@ -419,7 +419,7 @@ const createTable$1 = async (migration, tableMethods, up, tableName, first, seco
419
419
  });
420
420
  } };
421
421
  };
422
- const makeAst$4 = (schema, up, tableName, shape, tableData, options, noPrimaryKey) => {
422
+ const makeAst$5 = (schema, up, tableName, shape, tableData, options, noPrimaryKey) => {
423
423
  const shapePKeys = [];
424
424
  for (const key in shape) if (shape[key].data.primaryKey) shapePKeys.push(key);
425
425
  const { primaryKey } = tableData;
@@ -837,13 +837,13 @@ const changeTable = async (migration, tableChangeMethods, up, tableName, options
837
837
  standaloneCheckChanges.length = 0;
838
838
  const changeData = fn?.(tableChanger) || {};
839
839
  const schema = migration.adapter.getSchema();
840
- const queries = astToQueries(schema, makeAst$3(schema, up, tableName, changeData, changeTableData, options), snakeCase, language);
840
+ const queries = astToQueries(schema, makeAst$4(schema, up, tableName, changeData, changeTableData, options), snakeCase, language);
841
841
  for (const query of queries) {
842
842
  const result = await migration.adapter.arrays(interpolateSqlValues(query));
843
843
  query.then?.(result);
844
844
  }
845
845
  };
846
- const makeAst$3 = (schema, up, name, changeData, changeTableData, options) => {
846
+ const makeAst$4 = (schema, up, name, changeData, changeTableData, options) => {
847
847
  const { comment } = options;
848
848
  const shape = {};
849
849
  const consumedChanges = {};
@@ -1116,10 +1116,10 @@ const renameColumnSql = (from, to) => {
1116
1116
  return `RENAME COLUMN "${from}" TO "${to}"`;
1117
1117
  };
1118
1118
  const createView = async (migration, up, name, options, sql) => {
1119
- const query = astToQuery$1(makeAst$2(migration.adapter.getSchema(), up, name, options, sql));
1119
+ const query = astToQuery$2(makeAst$3(migration.adapter.getSchema(), up, name, options, sql));
1120
1120
  await migration.adapter.arrays(interpolateSqlValues(query));
1121
1121
  };
1122
- const makeAst$2 = (schema, up, fullName, options, sql) => {
1122
+ const makeAst$3 = (schema, up, fullName, options, sql) => {
1123
1123
  if (typeof sql === "string") sql = raw({ raw: sql });
1124
1124
  const [s, name] = getSchemaAndTableFromName(schema, fullName);
1125
1125
  return {
@@ -1133,7 +1133,7 @@ const makeAst$2 = (schema, up, fullName, options, sql) => {
1133
1133
  deps: []
1134
1134
  };
1135
1135
  };
1136
- const astToQuery$1 = (ast) => {
1136
+ const astToQuery$2 = (ast) => {
1137
1137
  const values = [];
1138
1138
  const sql = [];
1139
1139
  const { options } = ast;
@@ -1145,11 +1145,10 @@ const astToQuery$1 = (ast) => {
1145
1145
  if (options?.recursive) sql.push("RECURSIVE");
1146
1146
  sql.push(`VIEW ${sqlName}`);
1147
1147
  if (options?.columns) sql.push(`(${options.columns.map((column) => `"${column}"`).join(", ")})`);
1148
- const withOptions = options?.with;
1149
1148
  const list = [];
1150
- if (withOptions?.checkOption) list.push(`check_option = ${singleQuote(withOptions.checkOption)}`);
1151
- if (withOptions?.securityBarrier) list.push(`security_barrier = true`);
1152
- if (withOptions?.securityInvoker !== false) list.push(`security_invoker = true`);
1149
+ if (options?.checkOption) list.push(`check_option = ${singleQuote(options.checkOption)}`);
1150
+ if (options?.securityBarrier) list.push(`security_barrier = true`);
1151
+ if (options?.securityInvoker !== false) list.push(`security_invoker = true`);
1153
1152
  if (list.length) sql.push(`WITH ( ${list.join(", ")} )`);
1154
1153
  sql.push(`AS (${ast.sql.toSQL({ values })})`);
1155
1154
  } else {
@@ -1163,6 +1162,58 @@ const astToQuery$1 = (ast) => {
1163
1162
  values
1164
1163
  };
1165
1164
  };
1165
+ const createMaterializedView = async (migration, up, name, options, sql) => {
1166
+ const query = astToQuery$1(makeAst$2(migration.adapter.getSchema(), up, name, options, sql));
1167
+ await migration.adapter.arrays(interpolateSqlValues(query));
1168
+ };
1169
+ const refreshMaterializedView = async (migration, name, options = {}) => {
1170
+ if (options.concurrently && options.withData === false) throw new Error("Cannot refresh a materialized view concurrently with WITH NO DATA");
1171
+ const [s, viewName] = getSchemaAndTableFromName(migration.adapter.getSchema(), name);
1172
+ const sql = ["REFRESH MATERIALIZED VIEW"];
1173
+ if (options.concurrently) sql.push("CONCURRENTLY");
1174
+ sql.push(`${s ? `"${s}".` : ""}"${viewName}"`);
1175
+ pushWithData(sql, options);
1176
+ await migration.adapter.arrays(sql.join(" "));
1177
+ };
1178
+ const makeAst$2 = (schema, up, fullName, options, sql) => {
1179
+ if (typeof sql === "string") sql = raw({ raw: sql });
1180
+ const [s, name] = getSchemaAndTableFromName(schema, fullName);
1181
+ return {
1182
+ type: "materializedView",
1183
+ action: up ? "create" : "drop",
1184
+ schema: s,
1185
+ name,
1186
+ shape: {},
1187
+ sql,
1188
+ options,
1189
+ deps: []
1190
+ };
1191
+ };
1192
+ const astToQuery$1 = (ast) => {
1193
+ const values = [];
1194
+ const sql = [];
1195
+ const { options } = ast;
1196
+ const sqlName = `${ast.schema ? `"${ast.schema}".` : ""}"${ast.name}"`;
1197
+ if (ast.action === "create") {
1198
+ sql.push(`CREATE MATERIALIZED VIEW ${sqlName}`);
1199
+ if (options?.columns) sql.push(`(${options.columns.map((column) => `"${column}"`).join(", ")})`);
1200
+ sql.push(`AS (${ast.sql.toSQL({ values })})`);
1201
+ pushWithData(sql, options);
1202
+ } else {
1203
+ sql.push("DROP MATERIALIZED VIEW");
1204
+ if (options?.dropIfExists) sql.push(`IF EXISTS`);
1205
+ sql.push(sqlName);
1206
+ if (options?.dropMode) sql.push(options.dropMode);
1207
+ }
1208
+ return {
1209
+ text: sql.join(" "),
1210
+ values
1211
+ };
1212
+ };
1213
+ const pushWithData = (sql, options) => {
1214
+ if (options.withData === true) sql.push("WITH DATA");
1215
+ else if (options.withData === false) sql.push("WITH NO DATA");
1216
+ };
1166
1217
  const serializers = {
1167
1218
  super: (b) => `${b ? "" : "NO"}SUPERUSER`,
1168
1219
  inherit: (b) => `${b ? "" : "NO"}INHERIT`,
@@ -2360,6 +2411,23 @@ var Migration = class {
2360
2411
  const [options, sql] = args.length === 2 ? args : [emptyObject, args[0]];
2361
2412
  return createView(this, !this.up, name, options, sql);
2362
2413
  }
2414
+ createMaterializedView(name, ...args) {
2415
+ const [options, sql] = args.length === 2 ? args : [emptyObject, args[0]];
2416
+ return createMaterializedView(this, this.up, name, options, sql);
2417
+ }
2418
+ dropMaterializedView(name, ...args) {
2419
+ const [options, sql] = args.length === 2 ? args : [emptyObject, args[0]];
2420
+ return createMaterializedView(this, !this.up, name, options, sql);
2421
+ }
2422
+ /**
2423
+ * Refresh a materialized view.
2424
+ *
2425
+ * @param name - name of the materialized view
2426
+ * @param options - refresh options
2427
+ */
2428
+ refreshMaterializedView(name, options) {
2429
+ return refreshMaterializedView(this, name, options);
2430
+ }
2363
2431
  /**
2364
2432
  * Returns boolean to know if table exists:
2365
2433
  *
@@ -3686,10 +3754,11 @@ const astToGenerateItem = (config, ast, currentSchema) => {
3686
3754
  switch (ast.type) {
3687
3755
  case "table":
3688
3756
  case "changeTable":
3689
- case "view": {
3757
+ case "view":
3758
+ case "materializedView": {
3690
3759
  const schema = ast.schema ?? currentSchema;
3691
3760
  const table = `${schema}.${ast.name}`;
3692
- if (ast.type === "table" || ast.type === "view") {
3761
+ if (ast.type === "table" || ast.type === "view" || ast.type === "materializedView") {
3693
3762
  const keys = ast.action === "create" ? add : drop;
3694
3763
  keys.push(table);
3695
3764
  deps.push(schema);
@@ -4228,31 +4297,41 @@ const astEncoders = {
4228
4297
  })}, ${singleQuote(ast.from)}, ${singleQuote(ast.to)});`];
4229
4298
  },
4230
4299
  view(ast, _, currentSchema) {
4231
- const code = [`await db.createView(${quoteSchemaTable(ast, currentSchema)}`];
4300
+ const code = [`await db.${ast.action}View(${quoteSchemaTable(ast, currentSchema)}`];
4232
4301
  const options = [];
4233
- if (ast.options.recursive) options.push("recursive: true,");
4234
- const w = ast.options.with;
4235
- if (w?.checkOption) options.push(`checkOption: '${w.checkOption}',`);
4236
- if (w?.securityBarrier) options.push(`securityBarrier: ${w.securityBarrier},`);
4237
- if (w?.securityInvoker) options.push(`securityInvoker: ${w.securityInvoker},`);
4302
+ const { options: astOptions } = ast;
4303
+ if (astOptions.createOrReplace !== void 0) options.push(`createOrReplace: ${astOptions.createOrReplace},`);
4304
+ if (astOptions.dropIfExists !== void 0) options.push(`dropIfExists: ${astOptions.dropIfExists},`);
4305
+ if (astOptions.dropMode) options.push(`dropMode: '${astOptions.dropMode}',`);
4306
+ if (astOptions.temporary !== void 0) options.push(`temporary: ${astOptions.temporary},`);
4307
+ if (astOptions.recursive !== void 0) options.push(`recursive: ${astOptions.recursive},`);
4308
+ if (astOptions.columns) options.push(`columns: [${astOptions.columns.map(singleQuote).join(", ")}],`);
4309
+ if (astOptions.checkOption) options.push(`checkOption: '${astOptions.checkOption}',`);
4310
+ if (astOptions.securityBarrier !== void 0) options.push(`securityBarrier: ${astOptions.securityBarrier},`);
4311
+ if (astOptions.securityInvoker !== void 0) options.push(`securityInvoker: ${astOptions.securityInvoker},`);
4238
4312
  if (options.length) {
4239
4313
  addCode(code, ", {");
4240
4314
  code.push(options, "}");
4241
4315
  }
4242
4316
  addCode(code, ", ");
4243
- if (!ast.sql._values) {
4244
- const raw = ast.sql._sql;
4245
- let sql;
4246
- if (typeof raw === "string") sql = raw;
4247
- else {
4248
- sql = "";
4249
- const parts = raw[0];
4250
- const last = parts.length - 1;
4251
- for (let i = 0; i < last; i++) sql += parts[i] + `\${${raw[i + 1]}}`;
4252
- sql += parts[last];
4253
- }
4254
- addCode(code, backtickQuote(sql));
4255
- } else addCode(code, rawSqlToCode(ast.sql, "db"));
4317
+ addViewSqlCode(code, ast.sql);
4318
+ addCode(code, ");");
4319
+ return code;
4320
+ },
4321
+ materializedView(ast, _, currentSchema) {
4322
+ const code = [`await db.${ast.action}MaterializedView(${quoteSchemaTable(ast, currentSchema)}`];
4323
+ const options = [];
4324
+ const { options: astOptions } = ast;
4325
+ if (astOptions.dropIfExists !== void 0) options.push(`dropIfExists: ${astOptions.dropIfExists},`);
4326
+ if (astOptions.dropMode) options.push(`dropMode: '${astOptions.dropMode}',`);
4327
+ if (astOptions.columns) options.push(`columns: [${astOptions.columns.map(singleQuote).join(", ")}],`);
4328
+ if (astOptions.withData !== void 0) options.push(`withData: ${astOptions.withData},`);
4329
+ if (options.length) {
4330
+ addCode(code, ", {");
4331
+ code.push(options, "}");
4332
+ }
4333
+ addCode(code, ", ");
4334
+ addViewSqlCode(code, ast.sql);
4256
4335
  addCode(code, ");");
4257
4336
  return code;
4258
4337
  },
@@ -4428,6 +4507,21 @@ const isPolicyRecreateDefinition = (policy) => {
4428
4507
  const rawSqlStringToCode = (sql) => {
4429
4508
  return `db.sql${backtickQuote(sql)}`;
4430
4509
  };
4510
+ const addViewSqlCode = (code, sqlAst) => {
4511
+ if (!sqlAst._values) {
4512
+ const raw = sqlAst._sql;
4513
+ let sql;
4514
+ if (typeof raw === "string") sql = raw;
4515
+ else {
4516
+ sql = "";
4517
+ const parts = raw[0];
4518
+ const last = parts.length - 1;
4519
+ for (let i = 0; i < last; i++) sql += parts[i] + `\${${raw[i + 1]}}`;
4520
+ sql += parts[last];
4521
+ }
4522
+ addCode(code, backtickQuote(sql));
4523
+ } else addCode(code, rawSqlToCode(sqlAst, "db"));
4524
+ };
4431
4525
  const roleParams = (name, ast, compare, to) => {
4432
4526
  const params = [];
4433
4527
  for (const key of [
@@ -4612,6 +4706,39 @@ JOIN pg_class c
4612
4706
  JOIN pg_rewrite r ON r.ev_class = c.oid
4613
4707
  WHERE ${filterSchema("nc.nspname")}
4614
4708
  ORDER BY c.relname`;
4709
+ const materializedViewsSql = `SELECT
4710
+ nc.nspname AS "schemaName",
4711
+ c.relname AS "name",
4712
+ (
4713
+ SELECT COALESCE(json_agg(t.*), '[]')
4714
+ FROM (
4715
+ SELECT
4716
+ ns.nspname AS "schemaName",
4717
+ obj.relname AS "name"
4718
+ FROM pg_class obj
4719
+ JOIN pg_depend dep ON dep.refobjid = obj.oid
4720
+ JOIN pg_rewrite rew ON rew.oid = dep.objid
4721
+ JOIN pg_namespace ns ON ns.oid = obj.relnamespace
4722
+ WHERE rew.ev_class = c.oid AND obj.oid <> c.oid
4723
+ ) t
4724
+ ) "deps",
4725
+ (SELECT coalesce(json_agg(t), '[]') FROM (${columnsSql({
4726
+ schema: "nc",
4727
+ table: "c",
4728
+ where: "a.attrelid = c.oid"
4729
+ })}) t) AS "columns",
4730
+ pg_get_viewdef(c.oid) AS "sql",
4731
+ c.relispopulated AS "isPopulated",
4732
+ spc.spcname AS "tablespace"
4733
+ FROM pg_namespace nc
4734
+ JOIN pg_class c
4735
+ ON nc.oid = c.relnamespace
4736
+ AND c.relkind = 'm'
4737
+ AND c.relpersistence != 't'
4738
+ JOIN pg_rewrite r ON r.ev_class = c.oid
4739
+ LEFT JOIN pg_tablespace spc ON spc.oid = c.reltablespace
4740
+ WHERE ${filterSchema("nc.nspname")}
4741
+ ORDER BY c.relname`;
4615
4742
  const indexesSql = `SELECT
4616
4743
  n.nspname "schemaName",
4617
4744
  t.relname "tableName",
@@ -4913,7 +5040,7 @@ const grantsSql = `SELECT COALESCE(json_agg(t.* ORDER BY t."target", t."schema",
4913
5040
  FROM pg_class c
4914
5041
  JOIN pg_namespace n ON n.oid = c.relnamespace
4915
5042
  JOIN LATERAL aclexplode(coalesce(c.relacl, acldefault('r', c.relowner))) ae ON true
4916
- WHERE c.relkind IN ('r', 'p')
5043
+ WHERE c.relkind IN ('r', 'p', 'v')
4917
5044
  AND ${filterSchema("n.nspname")}
4918
5045
  AND ae.grantee <> c.relowner
4919
5046
  GROUP BY "grantor", "grantee", "schema", "name", "target"
@@ -5045,7 +5172,7 @@ FROM pg_policy p
5045
5172
  JOIN pg_class c ON c.oid = p.polrelid
5046
5173
  JOIN pg_namespace n ON n.oid = c.relnamespace
5047
5174
  ORDER BY n.nspname, c.relname, p.polname`;
5048
- 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"` : ""}${params?.loadGrants ? `, (${grantsSql}) AS "grants"` : ""}${params?.rls ? `, ${jsonAgg(policiesSql, "policies")}` : ""}`;
5175
+ const sql = (version, params) => `SELECT (${schemasSql}) AS "schemas", ${jsonAgg(tablesSql(params?.rls), "tables")}, ${params?.loadViews ? `${jsonAgg(viewsSql, "views")}, ${jsonAgg(materializedViewsSql, "materializedViews")}, ` : ""}${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"` : ""}${params?.loadGrants ? `, (${grantsSql}) AS "grants"` : ""}${params?.rls ? `, ${jsonAgg(policiesSql, "policies")}` : ""}`;
5049
5176
  async function getDbVersion(db) {
5050
5177
  const { rows: [{ version: versionString }] } = await db.query("SELECT version()");
5051
5178
  return +versionString.match(/\d+/)[0];
@@ -5057,10 +5184,11 @@ async function introspectDbSchema(db, params) {
5057
5184
  domain.checks = domain.checks?.filter((check) => check);
5058
5185
  nullsToUndefined(domain);
5059
5186
  }
5060
- for (const table of raw.tables) for (const column of table.columns) {
5061
- nullsToUndefined(column);
5062
- if (column.identity) nullsToUndefined(column.identity);
5063
- if (column.compression) column.compression = column.compression === "p" ? "pglz" : "lz4";
5187
+ for (const table of raw.tables) processColumns(table.columns);
5188
+ for (const view of raw.views || []) processColumns(view.columns);
5189
+ for (const materializedView of raw.materializedViews || []) {
5190
+ nullsToUndefined(materializedView);
5191
+ processColumns(materializedView.columns);
5064
5192
  }
5065
5193
  const indexes = [];
5066
5194
  const excludes = [];
@@ -5189,6 +5317,13 @@ const mapRawGrant = (raw) => {
5189
5317
  if (grantablePrivileges.length) grant.grantablePrivileges = grantablePrivileges;
5190
5318
  return grant;
5191
5319
  };
5320
+ const processColumns = (columns) => {
5321
+ for (const column of columns) {
5322
+ nullsToUndefined(column);
5323
+ if (column.identity) nullsToUndefined(column.identity);
5324
+ if (column.compression) column.compression = column.compression === "p" ? "pglz" : "lz4";
5325
+ }
5326
+ };
5192
5327
  const nullsToUndefined = (obj) => {
5193
5328
  for (const key in obj) if (obj[key] === null) obj[key] = void 0;
5194
5329
  };
@@ -5286,7 +5421,19 @@ const structureToAst = async (ctx, adapter, config) => {
5286
5421
  tableSchema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
5287
5422
  tableName: fkey.tableName
5288
5423
  });
5289
- for (const view of data.views) ast.push(viewToAst(ctx, data, domains, view));
5424
+ for (const view of data.views || []) ast.push(viewToAst(ctx, data, domains, view));
5425
+ for (const view of data.materializedViews || []) {
5426
+ ast.push(materializedViewToAst(ctx, data, domains, view));
5427
+ const indexes = materializedViewIndexesToAst(view, data);
5428
+ if (indexes.length) ast.push({
5429
+ type: "changeTable",
5430
+ schema: view.schemaName === ctx.currentSchema ? void 0 : view.schemaName,
5431
+ name: view.name,
5432
+ shape: {},
5433
+ add: { indexes },
5434
+ drop: {}
5435
+ });
5436
+ }
5290
5437
  if (data.roles) for (const role of data.roles) ast.push({
5291
5438
  type: "role",
5292
5439
  action: "create",
@@ -5456,13 +5603,22 @@ const isColumnCheck = (it) => {
5456
5603
  const viewToAst = (ctx, data, domains, view) => {
5457
5604
  const shape = makeDbStructureColumnsShape(ctx, data, domains, view);
5458
5605
  const options = {};
5459
- if (view.isRecursive) options.recursive = true;
5460
- if (view.with) {
5461
- const withOptions = {};
5462
- options.with = withOptions;
5463
- for (const pair of view.with) {
5464
- const [key, value] = pair.split("=");
5465
- withOptions[toCamelCase(key)] = value === "true" ? true : value === "false" ? false : value;
5606
+ if (view.isRecursive) {
5607
+ options.recursive = true;
5608
+ options.columns = view.columns.map((column) => column.name);
5609
+ }
5610
+ if (view.with) for (const pair of view.with) {
5611
+ const [key, value] = pair.split("=");
5612
+ switch (toCamelCase(key)) {
5613
+ case "checkOption":
5614
+ if (value === "LOCAL" || value === "CASCADED") options.checkOption = value;
5615
+ break;
5616
+ case "securityBarrier":
5617
+ options.securityBarrier = value === "true";
5618
+ break;
5619
+ case "securityInvoker":
5620
+ options.securityInvoker = value === "true";
5621
+ break;
5466
5622
  }
5467
5623
  }
5468
5624
  return {
@@ -5476,11 +5632,40 @@ const viewToAst = (ctx, data, domains, view) => {
5476
5632
  deps: view.deps
5477
5633
  };
5478
5634
  };
5635
+ const materializedViewToAst = (ctx, data, domains, view) => {
5636
+ const options = {};
5637
+ if (!view.isPopulated) options.withData = false;
5638
+ return {
5639
+ type: "materializedView",
5640
+ action: "create",
5641
+ schema: view.schemaName === ctx.currentSchema ? void 0 : view.schemaName,
5642
+ name: view.name,
5643
+ shape: makeDbStructureColumnsShape(ctx, data, domains, view),
5644
+ sql: raw({ raw: view.sql }),
5645
+ options,
5646
+ deps: view.deps
5647
+ };
5648
+ };
5649
+ const materializedViewIndexesToAst = (view, data) => {
5650
+ return data.indexes.filter(filterByTableSchema(view.name, view.schemaName)).map((index) => ({
5651
+ columns: index.columns.map((column) => ({
5652
+ ..."expression" in column ? { expression: column.expression } : { column: toCamelCase(column.column) },
5653
+ collate: column.collate,
5654
+ opclass: column.opclass,
5655
+ order: column.order
5656
+ })),
5657
+ options: {
5658
+ ...makeIndexOrExcludeOptions(view.name, index, "indexes"),
5659
+ include: index.include?.map(toCamelCase)
5660
+ }
5661
+ }));
5662
+ };
5479
5663
  const makeDbStructureColumnsShape = (ctx, data, domains, table, tableData) => {
5480
5664
  const shape = {};
5481
5665
  const checks = tableData ? getDbTableColumnsChecks(tableData) : void 0;
5666
+ const dbTable = tableData ? table : void 0;
5482
5667
  for (const item of table.columns) {
5483
- const [key, column] = dbColumnToAst(ctx, data, domains, table.name, item, table, tableData, checks);
5668
+ const [key, column] = dbColumnToAst(ctx, data, domains, table.name, item, dbTable, tableData, checks);
5484
5669
  shape[key] = column;
5485
5670
  }
5486
5671
  return shape;