rake-db 2.4.39 → 2.4.41

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
@@ -1,5 +1,5 @@
1
- import { quote, getRaw, EnumColumn, columnTypes, getColumnTypes, getTableData, ColumnType, resetTableData, UnknownColumn, TransactionAdapter, logParamToLogObject, createDb as createDb$1, Adapter, simplifyColumnDefault, columnsByType, instantiateColumn, DomainColumn, CustomTypeColumn, ArrayColumn, getConstraintKind, primaryKeyToCode, indexToCode, constraintToCode, TimestampColumn, referencesArgsToCode, constraintPropsToCode } from 'pqb';
2
- import { singleQuote, toSnakeCase, isRaw, toArray, snakeCaseKey, nameKey, emptyObject, deepCompare, pathToLog, raw, toCamelCase, codeToString, addCode, rawToCode, quoteObjectKey } from 'orchid-core';
1
+ import { quote, getRaw, EnumColumn, columnTypes, getColumnTypes, getTableData, ColumnType, resetTableData, UnknownColumn, TransactionAdapter, logParamToLogObject, createDb as createDb$1, Adapter, simplifyColumnDefault, columnsByType, instantiateColumn, DomainColumn, CustomTypeColumn, ArrayColumn, getConstraintKind, primaryKeyToCode, indexToCode, constraintToCode, TimestampTzColumn, referencesArgsToCode, constraintPropsToCode } from 'pqb';
2
+ import { singleQuote, toSnakeCase, isRaw, toArray, snakeCaseKey, nameKey, emptyObject, deepCompare, raw, pathToLog, toCamelCase, codeToString, addCode, rawToCode, quoteObjectKey, backtickQuote } from 'orchid-core';
3
3
  import path from 'path';
4
4
  import { readdir, mkdir, writeFile } from 'fs/promises';
5
5
  import prompts from 'prompts';
@@ -554,7 +554,7 @@ const createTable$1 = async (migration, up, tableName, options, fn) => {
554
554
  types[snakeCaseKey] = snakeCase;
555
555
  const shape = getColumnTypes(types, fn);
556
556
  const tableData = getTableData();
557
- const ast = makeAst$1(
557
+ const ast = makeAst$2(
558
558
  up,
559
559
  tableName,
560
560
  shape,
@@ -580,7 +580,7 @@ const createTable$1 = async (migration, up, tableName, options, fn) => {
580
580
  }
581
581
  };
582
582
  };
583
- const makeAst$1 = (up, tableName, shape, tableData, options, noPrimaryKey) => {
583
+ const makeAst$2 = (up, tableName, shape, tableData, options, noPrimaryKey) => {
584
584
  const shapePKeys = [];
585
585
  for (const key in shape) {
586
586
  const column = shape[key];
@@ -879,7 +879,7 @@ const changeTable = async (migration, up, tableName, options, fn) => {
879
879
  const snakeCase = "snakeCase" in options ? options.snakeCase : migration.options.snakeCase;
880
880
  tableChanger[snakeCaseKey] = snakeCase;
881
881
  const changeData = (fn == null ? void 0 : fn(tableChanger)) || {};
882
- const ast = makeAst(up, tableName, changeData, changeTableData, options);
882
+ const ast = makeAst$1(up, tableName, changeData, changeTableData, options);
883
883
  const queries = astToQueries(ast, snakeCase);
884
884
  for (const query of queries) {
885
885
  const result = await migration.adapter.arrays(query);
@@ -887,7 +887,7 @@ const changeTable = async (migration, up, tableName, options, fn) => {
887
887
  }
888
888
  migration.migratedAsts.push(ast);
889
889
  };
890
- const makeAst = (up, name, changeData, changeTableData2, options) => {
890
+ const makeAst$1 = (up, name, changeData, changeTableData2, options) => {
891
891
  const { comment } = options;
892
892
  const shape = {};
893
893
  for (const key in changeData) {
@@ -1183,6 +1183,68 @@ const mapConstraintsToSnakeCase = (foreignKeys, snakeCase) => {
1183
1183
  }))) || [];
1184
1184
  };
1185
1185
 
1186
+ const createView$1 = async (migration, up, name, options, sql) => {
1187
+ const ast = makeAst(up, name, options, sql);
1188
+ const query = astToQuery(ast);
1189
+ await migration.adapter.query(query);
1190
+ migration.migratedAsts.push(ast);
1191
+ };
1192
+ const makeAst = (up, name, options, sql) => {
1193
+ if (typeof sql === "string") {
1194
+ sql = raw(sql);
1195
+ }
1196
+ return {
1197
+ type: "view",
1198
+ action: up ? "create" : "drop",
1199
+ name,
1200
+ shape: {},
1201
+ sql,
1202
+ options
1203
+ };
1204
+ };
1205
+ const astToQuery = (ast) => {
1206
+ const values = [];
1207
+ const sql = [];
1208
+ const { options } = ast;
1209
+ if (ast.action === "create") {
1210
+ sql.push("CREATE");
1211
+ if (options == null ? void 0 : options.createOrReplace)
1212
+ sql.push("OR REPLACE");
1213
+ if (options == null ? void 0 : options.temporary)
1214
+ sql.push("TEMPORARY");
1215
+ if (options == null ? void 0 : options.recursive)
1216
+ sql.push("RECURSIVE");
1217
+ sql.push(`VIEW "${ast.name}"`);
1218
+ if (options == null ? void 0 : options.columns) {
1219
+ sql.push(
1220
+ `(${options.columns.map((column) => `"${column}"`).join(", ")})`
1221
+ );
1222
+ }
1223
+ if (options == null ? void 0 : options.with) {
1224
+ const list = [];
1225
+ if (options.with.checkOption)
1226
+ list.push(`check_option = ${singleQuote(options.with.checkOption)}`);
1227
+ if (options.with.securityBarrier)
1228
+ list.push(`security_barrier = true`);
1229
+ if (options.with.securityInvoker)
1230
+ list.push(`security_invoker = true`);
1231
+ sql.push(`WITH ( ${list.join(", ")} )`);
1232
+ }
1233
+ sql.push(`AS (${getRaw(ast.sql, values)})`);
1234
+ } else {
1235
+ sql.push("DROP VIEW");
1236
+ if (options == null ? void 0 : options.dropIfExists)
1237
+ sql.push(`IF EXISTS`);
1238
+ sql.push(`"${ast.name}"`);
1239
+ if (options == null ? void 0 : options.dropMode)
1240
+ sql.push(options.dropMode);
1241
+ }
1242
+ return {
1243
+ text: sql.join(" "),
1244
+ values
1245
+ };
1246
+ };
1247
+
1186
1248
  var __defProp$2 = Object.defineProperty;
1187
1249
  var __defProps$1 = Object.defineProperties;
1188
1250
  var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
@@ -1343,6 +1405,26 @@ class MigrationBase {
1343
1405
  dropDomain(name, fn, options) {
1344
1406
  return createDomain$1(this, !this.up, name, fn, options);
1345
1407
  }
1408
+ createView(name, ...args) {
1409
+ const [options, sql] = args.length === 2 ? args : [emptyObject, args[0]];
1410
+ return createView$1(
1411
+ this,
1412
+ this.up,
1413
+ name,
1414
+ options,
1415
+ sql
1416
+ );
1417
+ }
1418
+ dropView(name, ...args) {
1419
+ const [options, sql] = args.length === 2 ? args : [emptyObject, args[0]];
1420
+ return createView$1(
1421
+ this,
1422
+ !this.up,
1423
+ name,
1424
+ options,
1425
+ sql
1426
+ );
1427
+ }
1346
1428
  async tableExists(tableName) {
1347
1429
  return queryExists(this, {
1348
1430
  text: `SELECT 1 FROM "information_schema"."tables" WHERE "table_name" = $1`,
@@ -1798,79 +1880,14 @@ const makeColumnsContent = (args, method) => {
1798
1880
  };
1799
1881
 
1800
1882
  const filterSchema = (table) => `${table} !~ '^pg_' AND ${table} != 'information_schema'`;
1801
- class DbStructure {
1802
- constructor(db) {
1803
- this.db = db;
1804
- }
1805
- async getSchemas() {
1806
- const { rows } = await this.db.arrays(
1807
- `SELECT n.nspname "name"
1808
- FROM pg_catalog.pg_namespace n
1809
- WHERE ${filterSchema("n.nspname")}
1810
- ORDER BY "name"`
1811
- );
1812
- return rows.flat();
1813
- }
1814
- async getTables() {
1815
- const { rows } = await this.db.query(
1816
- `SELECT
1817
- nspname AS "schemaName",
1818
- relname AS "name",
1819
- obj_description(c.oid) AS comment
1820
- FROM pg_class c
1821
- JOIN pg_catalog.pg_namespace n ON n.oid = relnamespace
1822
- WHERE relkind = 'r'
1823
- AND ${filterSchema("nspname")}
1824
- ORDER BY relname`
1825
- );
1826
- return rows;
1827
- }
1828
- async getViews() {
1829
- const { rows } = await this.db.query(
1830
- `SELECT
1831
- table_schema "schemaName",
1832
- table_name "name"
1833
- FROM information_schema.tables
1834
- WHERE table_type = 'VIEW'
1835
- AND ${filterSchema("table_schema")}
1836
- ORDER BY table_name`
1837
- );
1838
- return rows;
1839
- }
1840
- async getProcedures() {
1841
- const { rows } = await this.db.query(
1842
- `SELECT
1843
- n.nspname AS "schemaName",
1844
- proname AS name,
1845
- proretset AS "returnSet",
1846
- (
1847
- SELECT typname FROM pg_type WHERE oid = prorettype
1848
- ) AS "returnType",
1849
- prokind AS "kind",
1850
- coalesce((
1851
- SELECT true FROM information_schema.triggers
1852
- WHERE n.nspname = trigger_schema AND trigger_name = proname
1853
- LIMIT 1
1854
- ), false) AS "isTrigger",
1855
- coalesce((
1856
- SELECT json_agg(pg_type.typname)
1857
- FROM unnest(coalesce(proallargtypes, proargtypes)) typeId
1858
- JOIN pg_type ON pg_type.oid = typeId
1859
- ), '[]') AS "types",
1860
- coalesce(to_json(proallargtypes::int[]), to_json(proargtypes::int[])) AS "argTypes",
1861
- coalesce(to_json(proargmodes), '[]') AS "argModes",
1862
- to_json(proargnames) AS "argNames"
1863
- FROM pg_proc p
1864
- JOIN pg_namespace n ON p.pronamespace = n.oid
1865
- WHERE ${filterSchema("n.nspname")}`
1866
- );
1867
- return rows;
1868
- }
1869
- async getColumns() {
1870
- const { rows } = await this.db.query(
1871
- `SELECT
1872
- nc.nspname AS "schemaName",
1873
- c.relname AS "tableName",
1883
+ const columnsSql = ({
1884
+ schema,
1885
+ table,
1886
+ join = "",
1887
+ where
1888
+ }) => `SELECT
1889
+ ${schema}.nspname AS "schemaName",
1890
+ ${table}.relname AS "tableName",
1874
1891
  a.attname AS "name",
1875
1892
  COALESCE(et.typname, t.typname) AS "type",
1876
1893
  tn.nspname AS "typeSchema",
@@ -1928,9 +1945,8 @@ WHERE ${filterSchema("n.nspname")}`
1928
1945
  ) END
1929
1946
  ) "identity"
1930
1947
  FROM pg_attribute a
1948
+ ${join}
1931
1949
  LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
1932
- JOIN pg_class c ON a.attrelid = c.oid
1933
- JOIN pg_namespace nc ON c.relnamespace = nc.oid
1934
1950
  JOIN pg_type t ON a.atttypid = t.oid
1935
1951
  LEFT JOIN pg_type et ON t.typelem = et.oid
1936
1952
  JOIN pg_namespace tn ON tn.oid = t.typnamespace
@@ -1940,12 +1956,99 @@ LEFT JOIN pg_catalog.pg_description pgd
1940
1956
  ON pgd.objoid = a.attrelid
1941
1957
  AND pgd.objsubid = a.attnum
1942
1958
  LEFT JOIN (pg_depend dep JOIN pg_sequence seq ON (dep.classid = 'pg_class'::regclass AND dep.objid = seq.seqrelid AND dep.deptype = 'i'))
1943
- ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = c.oid AND dep.refobjsubid = a.attnum)
1959
+ ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = ${table}.oid AND dep.refobjsubid = a.attnum)
1944
1960
  WHERE a.attnum > 0
1945
1961
  AND NOT a.attisdropped
1946
- AND c.relkind IN ('r', 'v', 'f', 'p')
1947
- AND ${filterSchema("nc.nspname")}
1948
- ORDER BY a.attnum`
1962
+ AND ${where}
1963
+ ORDER BY a.attnum`;
1964
+ class DbStructure {
1965
+ constructor(db) {
1966
+ this.db = db;
1967
+ }
1968
+ async getSchemas() {
1969
+ const { rows } = await this.db.arrays(
1970
+ `SELECT n.nspname "name"
1971
+ FROM pg_catalog.pg_namespace n
1972
+ WHERE ${filterSchema("n.nspname")}
1973
+ ORDER BY "name"`
1974
+ );
1975
+ return rows.flat();
1976
+ }
1977
+ async getTables() {
1978
+ const { rows } = await this.db.query(
1979
+ `SELECT
1980
+ nspname AS "schemaName",
1981
+ relname AS "name",
1982
+ obj_description(c.oid) AS comment
1983
+ FROM pg_class c
1984
+ JOIN pg_catalog.pg_namespace n ON n.oid = relnamespace
1985
+ WHERE relkind = 'r'
1986
+ AND ${filterSchema("nspname")}
1987
+ ORDER BY relname`
1988
+ );
1989
+ return rows;
1990
+ }
1991
+ async getViews() {
1992
+ const { rows } = await this.db.query(
1993
+ `SELECT
1994
+ nc.nspname AS "schemaName",
1995
+ c.relname AS "name",
1996
+ right(substring(r.ev_action from ':hasRecursive w'), 1)::bool AS "isRecursive",
1997
+ array_to_json(c.reloptions) AS "with",
1998
+ (SELECT coalesce(json_agg(t), '[]') FROM (${columnsSql({
1999
+ schema: "nc",
2000
+ table: "c",
2001
+ where: "a.attrelid = c.oid"
2002
+ })}) t) AS "columns",
2003
+ pg_get_viewdef(c.oid) AS "sql"
2004
+ FROM pg_namespace nc
2005
+ JOIN pg_class c
2006
+ ON nc.oid = c.relnamespace
2007
+ AND c.relkind = 'v'
2008
+ AND c.relpersistence != 't'
2009
+ JOIN pg_rewrite r ON r.ev_class = c.oid
2010
+ WHERE ${filterSchema("nc.nspname")}
2011
+ ORDER BY c.relname`
2012
+ );
2013
+ return rows;
2014
+ }
2015
+ async getProcedures() {
2016
+ const { rows } = await this.db.query(
2017
+ `SELECT
2018
+ n.nspname AS "schemaName",
2019
+ proname AS name,
2020
+ proretset AS "returnSet",
2021
+ (
2022
+ SELECT typname FROM pg_type WHERE oid = prorettype
2023
+ ) AS "returnType",
2024
+ prokind AS "kind",
2025
+ coalesce((
2026
+ SELECT true FROM information_schema.triggers
2027
+ WHERE n.nspname = trigger_schema AND trigger_name = proname
2028
+ LIMIT 1
2029
+ ), false) AS "isTrigger",
2030
+ coalesce((
2031
+ SELECT json_agg(pg_type.typname)
2032
+ FROM unnest(coalesce(proallargtypes, proargtypes)) typeId
2033
+ JOIN pg_type ON pg_type.oid = typeId
2034
+ ), '[]') AS "types",
2035
+ coalesce(to_json(proallargtypes::int[]), to_json(proargtypes::int[])) AS "argTypes",
2036
+ coalesce(to_json(proargmodes), '[]') AS "argModes",
2037
+ to_json(proargnames) AS "argNames"
2038
+ FROM pg_proc p
2039
+ JOIN pg_namespace n ON p.pronamespace = n.oid
2040
+ WHERE ${filterSchema("n.nspname")}`
2041
+ );
2042
+ return rows;
2043
+ }
2044
+ async getColumns() {
2045
+ const { rows } = await this.db.query(
2046
+ columnsSql({
2047
+ schema: "nc",
2048
+ table: "c",
2049
+ join: `JOIN pg_class c ON a.attrelid = c.oid AND c.relkind = 'r' JOIN pg_namespace nc ON nc.oid = c.relnamespace`,
2050
+ where: filterSchema("nc.nspname")
2051
+ })
1949
2052
  );
1950
2053
  return rows;
1951
2054
  }
@@ -2349,12 +2452,16 @@ const structureToAst = async (ctx, db) => {
2349
2452
  tableName: fkey.tableName
2350
2453
  }));
2351
2454
  }
2455
+ for (const view of data.views) {
2456
+ ast.push(viewToAst(ctx, data, domains, view));
2457
+ }
2352
2458
  return ast;
2353
2459
  };
2354
2460
  const getData = async (db) => {
2355
2461
  const [
2356
2462
  schemas,
2357
2463
  tables,
2464
+ views,
2358
2465
  columns,
2359
2466
  constraints,
2360
2467
  indexes,
@@ -2364,6 +2471,7 @@ const getData = async (db) => {
2364
2471
  ] = await Promise.all([
2365
2472
  db.getSchemas(),
2366
2473
  db.getTables(),
2474
+ db.getViews(),
2367
2475
  db.getColumns(),
2368
2476
  db.getConstraints(),
2369
2477
  db.getIndexes(),
@@ -2374,6 +2482,7 @@ const getData = async (db) => {
2374
2482
  return {
2375
2483
  schemas,
2376
2484
  tables,
2485
+ views,
2377
2486
  columns,
2378
2487
  constraints,
2379
2488
  indexes,
@@ -2442,7 +2551,6 @@ const getColumnType = (type, isSerial) => {
2442
2551
  return type === "int2" ? "smallserial" : type === "int4" ? "serial" : "bigserial";
2443
2552
  };
2444
2553
  const pushTableAst = (ctx, ast, data, domains, table, pendingTables, innerConstraints = data.constraints) => {
2445
- var _a, _b;
2446
2554
  const { schemaName, name: tableName } = table;
2447
2555
  const key = `${schemaName}.${table.name}`;
2448
2556
  delete pendingTables[key];
@@ -2458,7 +2566,7 @@ const pushTableAst = (ctx, ast, data, domains, table, pendingTables, innerConstr
2458
2566
  const tableIndexes = data.indexes.filter(belongsToTable);
2459
2567
  const tableConstraints = innerConstraints.reduce(
2460
2568
  (acc, item) => {
2461
- var _a2;
2569
+ var _a;
2462
2570
  const { references, check } = item;
2463
2571
  if (belongsToTable(item) && (references || check && !isColumnCheck(item))) {
2464
2572
  const constraint = {
@@ -2477,7 +2585,7 @@ const pushTableAst = (ctx, ast, data, domains, table, pendingTables, innerConstr
2477
2585
  const name = item.name && item.name !== getConstraintName(tableName, constraint) ? item.name : void 0;
2478
2586
  if (name) {
2479
2587
  constraint.name = name;
2480
- if ((_a2 = constraint.references) == null ? void 0 : _a2.options) {
2588
+ if ((_a = constraint.references) == null ? void 0 : _a.options) {
2481
2589
  constraint.references.options.name = name;
2482
2590
  }
2483
2591
  }
@@ -2496,66 +2604,17 @@ const pushTableAst = (ctx, ast, data, domains, table, pendingTables, innerConstr
2496
2604
  },
2497
2605
  {}
2498
2606
  );
2499
- const shape = {};
2500
- for (let item of columns) {
2501
- const isSerial = getIsSerial(item);
2502
- if (isSerial) {
2503
- item = __spreadProps(__spreadValues({}, item), { default: void 0 });
2504
- }
2505
- let column = getColumn(ctx, data, domains, __spreadProps(__spreadValues({}, item), {
2506
- type: item.type,
2507
- isArray: item.isArray,
2508
- isSerial
2509
- }));
2510
- if (item.identity) {
2511
- column.data.identity = item.identity;
2512
- if (!item.identity.always)
2513
- (_a = column.data.identity) == null ? true : delete _a.always;
2514
- }
2515
- if (((_b = primaryKey == null ? void 0 : primaryKey.columns) == null ? void 0 : _b.length) === 1 && (primaryKey == null ? void 0 : primaryKey.columns[0]) === item.name) {
2516
- column = column.primaryKey();
2517
- }
2518
- const indexes = tableIndexes.filter(
2519
- (it) => it.columns.length === 1 && "column" in it.columns[0] && it.columns[0].column === item.name
2520
- );
2521
- for (const index of indexes) {
2522
- const options = index.columns[0];
2523
- column = column.index({
2524
- collate: options.collate,
2525
- opclass: options.opclass,
2526
- order: options.order,
2527
- name: index.name !== getIndexName(tableName, index.columns) ? index.name : void 0,
2528
- using: index.using === "btree" ? void 0 : index.using,
2529
- unique: index.isUnique,
2530
- include: index.include,
2531
- nullsNotDistinct: index.nullsNotDistinct,
2532
- with: index.with,
2533
- tablespace: index.tablespace,
2534
- where: index.where
2535
- });
2536
- }
2537
- for (const it of tableConstraints) {
2538
- if (!isColumnFkey(it) || it.references.columns[0] !== item.name)
2539
- continue;
2540
- column = column.foreignKey(
2541
- it.references.fnOrTable,
2542
- it.references.foreignColumns[0],
2543
- it.references.options
2544
- );
2545
- }
2546
- const check = columnChecks[item.name];
2547
- if (check) {
2548
- column.data.check = raw(check);
2549
- }
2550
- const camelCaseName = toCamelCase(item.name);
2551
- if (ctx.snakeCase) {
2552
- const snakeCaseName = toSnakeCase(camelCaseName);
2553
- column.data.name = snakeCaseName === item.name ? void 0 : item.name;
2554
- } else {
2555
- column.data.name = camelCaseName === item.name ? void 0 : item.name;
2556
- }
2557
- shape[camelCaseName] = column;
2558
- }
2607
+ const shape = makeColumnsShape(
2608
+ ctx,
2609
+ data,
2610
+ domains,
2611
+ tableName,
2612
+ columns,
2613
+ primaryKey,
2614
+ tableIndexes,
2615
+ tableConstraints,
2616
+ columnChecks
2617
+ );
2559
2618
  ast.push({
2560
2619
  type: "table",
2561
2620
  action: "create",
@@ -2642,10 +2701,101 @@ const isColumnFkey = (it) => {
2642
2701
  var _a;
2643
2702
  return !it.check && ((_a = it.references) == null ? void 0 : _a.columns.length) === 1;
2644
2703
  };
2704
+ const viewToAst = (ctx, data, domains, view) => {
2705
+ const shape = makeColumnsShape(ctx, data, domains, view.name, view.columns);
2706
+ const options = {};
2707
+ if (view.isRecursive)
2708
+ options.recursive = true;
2709
+ if (view.with) {
2710
+ const withOptions = {};
2711
+ options.with = withOptions;
2712
+ for (const pair of view.with) {
2713
+ const [key, value] = pair.split("=");
2714
+ withOptions[toCamelCase(key)] = value === "true" ? true : value === "false" ? false : value;
2715
+ }
2716
+ }
2717
+ return {
2718
+ type: "view",
2719
+ action: "create",
2720
+ schema: view.schemaName === "public" ? void 0 : view.schemaName,
2721
+ name: view.name,
2722
+ shape,
2723
+ sql: raw(view.sql),
2724
+ options
2725
+ };
2726
+ };
2727
+ const makeColumnsShape = (ctx, data, domains, tableName, columns, primaryKey, indexes, constraints, checks) => {
2728
+ var _a, _b;
2729
+ const shape = {};
2730
+ for (let item of columns) {
2731
+ const isSerial = getIsSerial(item);
2732
+ if (isSerial) {
2733
+ item = __spreadProps(__spreadValues({}, item), { default: void 0 });
2734
+ }
2735
+ let column = getColumn(ctx, data, domains, __spreadProps(__spreadValues({}, item), {
2736
+ type: item.type,
2737
+ isArray: item.isArray,
2738
+ isSerial
2739
+ }));
2740
+ if (item.identity) {
2741
+ column.data.identity = item.identity;
2742
+ if (!item.identity.always)
2743
+ (_a = column.data.identity) == null ? true : delete _a.always;
2744
+ }
2745
+ if (((_b = primaryKey == null ? void 0 : primaryKey.columns) == null ? void 0 : _b.length) === 1 && (primaryKey == null ? void 0 : primaryKey.columns[0]) === item.name) {
2746
+ column = column.primaryKey();
2747
+ }
2748
+ if (indexes) {
2749
+ const columnIndexes = indexes.filter(
2750
+ (it) => it.columns.length === 1 && "column" in it.columns[0] && it.columns[0].column === item.name
2751
+ );
2752
+ for (const index of columnIndexes) {
2753
+ const options = index.columns[0];
2754
+ column = column.index({
2755
+ collate: options.collate,
2756
+ opclass: options.opclass,
2757
+ order: options.order,
2758
+ name: index.name !== getIndexName(tableName, index.columns) ? index.name : void 0,
2759
+ using: index.using === "btree" ? void 0 : index.using,
2760
+ unique: index.isUnique,
2761
+ include: index.include,
2762
+ nullsNotDistinct: index.nullsNotDistinct,
2763
+ with: index.with,
2764
+ tablespace: index.tablespace,
2765
+ where: index.where
2766
+ });
2767
+ }
2768
+ }
2769
+ if (constraints) {
2770
+ for (const it of constraints) {
2771
+ if (!isColumnFkey(it) || it.references.columns[0] !== item.name)
2772
+ continue;
2773
+ column = column.foreignKey(
2774
+ it.references.fnOrTable,
2775
+ it.references.foreignColumns[0],
2776
+ it.references.options
2777
+ );
2778
+ }
2779
+ }
2780
+ const check = checks == null ? void 0 : checks[item.name];
2781
+ if (check) {
2782
+ column.data.check = raw(check);
2783
+ }
2784
+ const camelCaseName = toCamelCase(item.name);
2785
+ if (ctx.snakeCase) {
2786
+ const snakeCaseName = toSnakeCase(camelCaseName);
2787
+ column.data.name = snakeCaseName === item.name ? void 0 : item.name;
2788
+ } else {
2789
+ column.data.name = camelCaseName === item.name ? void 0 : item.name;
2790
+ }
2791
+ shape[camelCaseName] = column;
2792
+ }
2793
+ return shape;
2794
+ };
2645
2795
 
2646
2796
  const astToMigration = (config, ast) => {
2647
2797
  const first = [];
2648
- const tables = [];
2798
+ const tablesAndViews = [];
2649
2799
  const constraints = [];
2650
2800
  for (const item of ast) {
2651
2801
  if (item.type === "schema" && item.action === "create") {
@@ -2663,14 +2813,16 @@ const astToMigration = (config, ast) => {
2663
2813
  first.push([]);
2664
2814
  first.push(...createDomain(item));
2665
2815
  } else if (item.type === "table" && item.action === "create") {
2666
- tables.push(createTable(config, item));
2816
+ tablesAndViews.push(createTable(config, item));
2817
+ } else if (item.type === "view" && item.action === "create") {
2818
+ tablesAndViews.push(createView(item));
2667
2819
  } else if (item.type === "constraint") {
2668
2820
  if (constraints.length)
2669
2821
  constraints.push([]);
2670
2822
  constraints.push(...createConstraint(item));
2671
2823
  }
2672
2824
  }
2673
- if (!first.length && !tables.length && !constraints.length)
2825
+ if (!first.length && !tablesAndViews.length && !constraints.length)
2674
2826
  return;
2675
2827
  let code = `import { change } from 'rake-db';
2676
2828
  `;
@@ -2681,8 +2833,8 @@ ${codeToString(first, " ", " ")}
2681
2833
  });
2682
2834
  `;
2683
2835
  }
2684
- if (tables.length) {
2685
- for (const table of tables) {
2836
+ if (tablesAndViews.length) {
2837
+ for (const table of tablesAndViews) {
2686
2838
  code += `
2687
2839
  change(async (db) => {
2688
2840
  ${codeToString(table, " ", " ")}
@@ -2788,7 +2940,7 @@ const isTimestamp = (column) => {
2788
2940
  if (!column)
2789
2941
  return false;
2790
2942
  const { default: def } = column.data;
2791
- return column instanceof TimestampColumn && !column.data.isNullable && def && typeof def === "object" && isRaw(def) && def.__raw === "now()";
2943
+ return column instanceof TimestampTzColumn && !column.data.isNullable && def && typeof def === "object" && isRaw(def) && def.__raw === "now()";
2792
2944
  };
2793
2945
  const createConstraint = (item) => {
2794
2946
  const kind = getConstraintKind(item);
@@ -2812,6 +2964,31 @@ const createConstraint = (item) => {
2812
2964
  "});"
2813
2965
  ];
2814
2966
  };
2967
+ const createView = (ast) => {
2968
+ const code = [`await db.createView(${quoteSchemaTable(ast)}`];
2969
+ const options = [];
2970
+ if (ast.options.recursive)
2971
+ options.push("recursive: true,");
2972
+ const w = ast.options.with;
2973
+ if (w == null ? void 0 : w.checkOption)
2974
+ options.push(`checkOption: '${w.checkOption}',`);
2975
+ if (w == null ? void 0 : w.securityBarrier)
2976
+ options.push(`securityBarrier: ${w.securityBarrier},`);
2977
+ if (w == null ? void 0 : w.securityInvoker)
2978
+ options.push(`securityInvoker: ${w.securityInvoker},`);
2979
+ if (options.length) {
2980
+ addCode(code, ", {");
2981
+ code.push(options, "}");
2982
+ }
2983
+ addCode(code, ", ");
2984
+ if (!ast.sql.__values) {
2985
+ addCode(code, backtickQuote(ast.sql.__raw));
2986
+ } else {
2987
+ addCode(code, rawToCode("db", ast.sql));
2988
+ }
2989
+ addCode(code, ");");
2990
+ return code;
2991
+ };
2815
2992
 
2816
2993
  const pullDbStructure = async (options, config) => {
2817
2994
  var _a, _b, _c;