rake-db 2.23.17 → 2.23.19

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.js CHANGED
@@ -7,21 +7,21 @@ var node_url = require('node:url');
7
7
  var fs = require('fs/promises');
8
8
 
9
9
  const getFirstWordAndRest = (input) => {
10
- const index = input.search(/(?=[A-Z])|[-_]/);
11
- if (index !== -1) {
12
- const restStart = input[index] === "-" || input[index] === "_" ? index + 1 : index;
10
+ const i = input.search(/(?=[A-Z])|[-_]/);
11
+ if (i !== -1) {
12
+ const restStart = input[i] === "-" || input[i] === "_" ? i + 1 : i;
13
13
  const rest = input.slice(restStart);
14
- return [input.slice(0, index), rest[0].toLowerCase() + rest.slice(1)];
14
+ return [input.slice(0, i), rest[0].toLowerCase() + rest.slice(1)];
15
15
  } else {
16
16
  return [input];
17
17
  }
18
18
  };
19
19
  const getTextAfterRegExp = (input, regex, length) => {
20
- let index = input.search(regex);
21
- if (index === -1) return;
22
- if (input[index] === "-" || input[index] === "_") index++;
23
- index += length;
24
- const start = input[index] == "-" || input[index] === "_" ? index + 1 : index;
20
+ let i = input.search(regex);
21
+ if (i === -1) return;
22
+ if (input[i] === "-" || input[i] === "_") i++;
23
+ i += length;
24
+ const start = input[i] == "-" || input[i] === "_" ? i + 1 : i;
25
25
  const text = input.slice(start);
26
26
  return text[0].toLowerCase() + text.slice(1);
27
27
  };
@@ -46,8 +46,8 @@ const quoteWithSchema = ({
46
46
  }) => quoteTable(schema, name);
47
47
  const quoteTable = (schema, table) => schema ? `"${schema}"."${table}"` : `"${table}"`;
48
48
  const getSchemaAndTableFromName = (name) => {
49
- const index = name.indexOf(".");
50
- return index !== -1 ? [name.slice(0, index), name.slice(index + 1)] : [void 0, name];
49
+ const i = name.indexOf(".");
50
+ return i !== -1 ? [name.slice(0, i), name.slice(i + 1)] : [void 0, name];
51
51
  };
52
52
  const quoteNameFromString = (string) => {
53
53
  return quoteTable(...getSchemaAndTableFromName(string));
@@ -193,6 +193,16 @@ const addColumnIndex = (indexes, name, item) => {
193
193
  );
194
194
  }
195
195
  };
196
+ const addColumnExclude = (excludes, name, item) => {
197
+ if (item.data.excludes) {
198
+ excludes.push(
199
+ ...item.data.excludes.map(({ with: w, ...exclude }) => ({
200
+ columns: [{ ...exclude.options, column: name, with: w }],
201
+ ...exclude
202
+ }))
203
+ );
204
+ }
205
+ };
196
206
  const addColumnComment = (comments, name, item) => {
197
207
  if (item.data.comment) {
198
208
  comments.push({ column: name, comment: item.data.comment });
@@ -283,29 +293,27 @@ const makeConstraintName = (table, columns, suffix) => {
283
293
  }
284
294
  return `long_ass_table_${suffix}`;
285
295
  };
286
- const getIndexName = (table, columns) => {
287
- return makeConstraintName(
288
- table,
289
- columns.map(
290
- (it) => "column" in it ? it.column : "expression"
291
- ),
292
- "idx"
293
- );
294
- };
296
+ const getIndexOrExcludeName = (table, columns, suffix) => makeConstraintName(
297
+ table,
298
+ columns.map(
299
+ (it) => "column" in it ? it.column : "expression"
300
+ ),
301
+ suffix
302
+ );
303
+ const getIndexName = (table, columns) => getIndexOrExcludeName(table, columns, "idx");
304
+ const getExcludeName = (table, columns) => getIndexOrExcludeName(table, columns, "exclude");
295
305
  const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, language) => {
296
- return indexes.map(({ columns, options, name }) => {
297
- let include = options.include ? orchidCore.toArray(options.include) : void 0;
298
- if (snakeCase) {
299
- columns = columns.map(
300
- (c) => "column" in c ? { ...c, column: orchidCore.toSnakeCase(c.column) } : c
301
- );
302
- if (include) include = include.map(orchidCore.toSnakeCase);
303
- }
304
- const indexName = name || getIndexName(tableName, columns);
306
+ return indexes.map((index) => {
307
+ const { options } = index;
308
+ const { columns, include, name } = getIndexOrExcludeMainOptions(
309
+ tableName,
310
+ index,
311
+ getIndexName,
312
+ snakeCase
313
+ );
305
314
  if (!up) {
306
315
  return {
307
- text: `DROP INDEX "${indexName}"${options.dropMode ? ` ${options.dropMode}` : ""}`,
308
- values: []
316
+ text: `DROP INDEX "${name}"${options.dropMode ? ` ${options.dropMode}` : ""}`
309
317
  };
310
318
  }
311
319
  const values = [];
@@ -313,28 +321,20 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
313
321
  if (options.unique) {
314
322
  sql.push("UNIQUE");
315
323
  }
316
- sql.push(`INDEX "${indexName}" ON ${quoteTable(schema, tableName)}`);
324
+ sql.push(`INDEX "${name}" ON ${quoteTable(schema, tableName)}`);
317
325
  const u = options.using || options.tsVector && "GIN";
318
326
  if (u) {
319
327
  sql.push(`USING ${u}`);
320
328
  }
321
- const columnsSql = [];
322
329
  const lang = options.tsVector && options.languageColumn ? `"${options.languageColumn}"` : options.language ? `'${options.language}'` : `'${language || "english"}'`;
323
330
  let hasWeight = options.tsVector && columns.some((column) => !!column.weight);
324
- for (const column of columns) {
325
- const columnSql = [
326
- "column" in column ? `"${column.column}"` : `(${column.expression})`
327
- ];
328
- if (column.collate) {
329
- columnSql.push(`COLLATE ${quoteNameFromString(column.collate)}`);
330
- }
331
- if (column.opclass) {
332
- columnSql.push(column.opclass);
333
- }
334
- if (column.order) {
335
- columnSql.push(column.order);
336
- }
337
- let sql2 = columnSql.join(" ");
331
+ const columnsSql = columns.map((column) => {
332
+ let sql2 = [
333
+ "column" in column ? `"${column.column}"` : `(${column.expression})`,
334
+ column.collate && `COLLATE ${quoteNameFromString(column.collate)}`,
335
+ column.opclass,
336
+ column.order
337
+ ].filter((x) => !!x).join(" ");
338
338
  if (hasWeight) {
339
339
  sql2 = `to_tsvector(${lang}, coalesce(${sql2}, ''))`;
340
340
  if (column.weight) {
@@ -342,8 +342,8 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
342
342
  sql2 = `setweight(${sql2}, '${column.weight}')`;
343
343
  }
344
344
  }
345
- columnsSql.push(sql2);
346
- }
345
+ return sql2;
346
+ });
347
347
  let columnList;
348
348
  if (hasWeight) {
349
349
  columnList = `(${columnsSql.join(" || ")})`;
@@ -353,9 +353,9 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
353
353
  columnList = columnsSql.join(", ");
354
354
  }
355
355
  sql.push(`(${columnList})`);
356
- if (options.include) {
356
+ if (include && include.length) {
357
357
  sql.push(
358
- `INCLUDE (${orchidCore.toArray(include).map((column) => `"${column}"`).join(", ")})`
358
+ `INCLUDE (${include.map((column) => `"${column}"`).join(", ")})`
359
359
  );
360
360
  }
361
361
  if (options.nullsNotDistinct) {
@@ -375,6 +375,63 @@ const indexesToQuery = (up, { schema, name: tableName }, indexes, snakeCase, lan
375
375
  return { text: sql.join(" "), values };
376
376
  });
377
377
  };
378
+ const excludesToQuery = (up, { schema, name: tableName }, excludes, snakeCase) => {
379
+ return excludes.map((exclude) => {
380
+ const { options } = exclude;
381
+ const { columns, include, name } = getIndexOrExcludeMainOptions(
382
+ tableName,
383
+ exclude,
384
+ getExcludeName,
385
+ snakeCase
386
+ );
387
+ if (!up) {
388
+ return {
389
+ text: `ALTER TABLE ${quoteTable(
390
+ schema,
391
+ tableName
392
+ )} DROP CONSTRAINT "${name}"${options.dropMode ? ` ${options.dropMode}` : ""}`
393
+ };
394
+ }
395
+ const columnList = columns.map(
396
+ (column) => [
397
+ "column" in column ? `"${column.column}"` : `(${column.expression})`,
398
+ column.collate && `COLLATE ${quoteNameFromString(column.collate)}`,
399
+ column.opclass,
400
+ column.order,
401
+ `WITH ${column.with}`
402
+ ].filter((x) => !!x).join(" ")
403
+ ).join(", ");
404
+ const values = [];
405
+ const text = [
406
+ `ALTER TABLE ${quoteTable(
407
+ schema,
408
+ tableName
409
+ )} ADD CONSTRAINT "${name}" EXCLUDE`,
410
+ options.using && `USING ${options.using}`,
411
+ `(${columnList})`,
412
+ include?.length && `INCLUDE (${include.map((column) => `"${column}"`).join(", ")})`,
413
+ options.with && `WITH (${options.with})`,
414
+ options.tablespace && `USING INDEX TABLESPACE ${options.tablespace}`,
415
+ options.where && `WHERE ${orchidCore.isRawSQL(options.where) ? options.where.toSQL({ values }) : options.where}`
416
+ ].filter((x) => !!x).join(" ");
417
+ return { text, values };
418
+ });
419
+ };
420
+ const getIndexOrExcludeMainOptions = (tableName, item, getName, snakeCase) => {
421
+ let include = item.options.include ? orchidCore.toArray(item.options.include) : void 0;
422
+ let { columns } = item;
423
+ if (snakeCase) {
424
+ columns = columns.map(
425
+ (c) => "column" in c ? { ...c, column: orchidCore.toSnakeCase(c.column) } : c
426
+ );
427
+ if (include) include = include.map(orchidCore.toSnakeCase);
428
+ }
429
+ return {
430
+ columns,
431
+ include,
432
+ name: item.name || getName(tableName, columns)
433
+ };
434
+ };
378
435
  const commentsToQuery = (schemaTable, comments) => {
379
436
  return comments.map(({ column, comment }) => ({
380
437
  text: `COMMENT ON COLUMN ${quoteWithSchema(
@@ -537,11 +594,13 @@ const astToQueries$1 = (ast, snakeCase, language) => {
537
594
  const lines = [];
538
595
  const values = [];
539
596
  const indexes = [];
597
+ const excludes = [];
540
598
  const comments = [];
541
599
  for (const key in shape) {
542
600
  const item = shape[key];
543
601
  const name = getColumnName(item, key, snakeCase);
544
602
  addColumnIndex(indexes, name, item);
603
+ addColumnExclude(excludes, name, item);
545
604
  addColumnComment(comments, name, item);
546
605
  lines.push(
547
606
  `
@@ -579,17 +638,8 @@ const astToQueries$1 = (ast, snakeCase, language) => {
579
638
  )}`
580
639
  );
581
640
  });
582
- indexes.push(
583
- ...ast.indexes?.map((index) => ({
584
- ...index,
585
- columns: index.columns.map((item) => ({
586
- ...item,
587
- ..."column" in item ? {
588
- column: getColumnName(shape[item.column], item.column, snakeCase)
589
- } : {}
590
- }))
591
- })) || []
592
- );
641
+ pushIndexesOrExcludesFromAst(indexes, ast.indexes, shape, snakeCase);
642
+ pushIndexesOrExcludesFromAst(excludes, ast.excludes, shape, snakeCase);
593
643
  queries.push(
594
644
  {
595
645
  text: `CREATE TABLE${ast.createIfNotExists ? " IF NOT EXISTS" : ""} ${quoteWithSchema(ast)} (${lines.join(",")}
@@ -597,6 +647,7 @@ const astToQueries$1 = (ast, snakeCase, language) => {
597
647
  values
598
648
  },
599
649
  ...indexesToQuery(true, ast, indexes, snakeCase, language),
650
+ ...excludesToQuery(true, ast, excludes, snakeCase),
600
651
  ...commentsToQuery(ast, comments)
601
652
  );
602
653
  if (ast.comment) {
@@ -608,6 +659,19 @@ const astToQueries$1 = (ast, snakeCase, language) => {
608
659
  }
609
660
  return queries;
610
661
  };
662
+ const pushIndexesOrExcludesFromAst = (arr, inAst, shape, snakeCase) => {
663
+ arr.push(
664
+ ...inAst?.map((x) => ({
665
+ ...x,
666
+ columns: x.columns.map((item) => ({
667
+ ...item,
668
+ ..."column" in item ? {
669
+ column: getColumnName(shape[item.column], item.column, snakeCase)
670
+ } : {}
671
+ }))
672
+ })) || []
673
+ );
674
+ };
611
675
 
612
676
  const newChangeTableData = () => ({
613
677
  add: {},
@@ -929,6 +993,8 @@ const astToQueries = (ast, snakeCase, language) => {
929
993
  const values = [];
930
994
  const addIndexes = ast.add.indexes ?? [];
931
995
  const dropIndexes = ast.drop.indexes ?? [];
996
+ const addExcludes = ast.add.excludes ?? [];
997
+ const dropExcludes = ast.drop.excludes ?? [];
932
998
  const addConstraints = ast.add.constraints ?? [];
933
999
  const dropConstraints = ast.drop.constraints ?? [];
934
1000
  const comments = [];
@@ -946,6 +1012,8 @@ const astToQueries = (ast, snakeCase, language) => {
946
1012
  addPrimaryKeys,
947
1013
  addIndexes,
948
1014
  dropIndexes,
1015
+ addExcludes,
1016
+ dropExcludes,
949
1017
  addConstraints,
950
1018
  dropConstraints,
951
1019
  comments,
@@ -963,6 +1031,8 @@ const astToQueries = (ast, snakeCase, language) => {
963
1031
  addPrimaryKeys,
964
1032
  addIndexes,
965
1033
  dropIndexes,
1034
+ addExcludes,
1035
+ dropExcludes,
966
1036
  addConstraints,
967
1037
  dropConstraints,
968
1038
  comments,
@@ -1014,6 +1084,8 @@ const astToQueries = (ast, snakeCase, language) => {
1014
1084
  }
1015
1085
  queries.push(...indexesToQuery(false, ast, dropIndexes, snakeCase, language));
1016
1086
  queries.push(...indexesToQuery(true, ast, addIndexes, snakeCase, language));
1087
+ queries.push(...excludesToQuery(false, ast, dropExcludes, snakeCase));
1088
+ queries.push(...excludesToQuery(true, ast, addExcludes, snakeCase));
1017
1089
  queries.push(...commentsToQuery(ast, comments));
1018
1090
  return queries;
1019
1091
  };
@@ -1058,11 +1130,12 @@ const handlePrerequisitesForTableItem = (key, item, queries, addPrimaryKeys, dro
1058
1130
  }
1059
1131
  }
1060
1132
  };
1061
- const handleTableItemChange = (key, item, ast, alterTable, renameItems, values, addPrimaryKeys, addIndexes, dropIndexes, addConstraints, dropConstraints, comments, snakeCase) => {
1133
+ const handleTableItemChange = (key, item, ast, alterTable, renameItems, values, addPrimaryKeys, addIndexes, dropIndexes, addExcludes, dropExcludes, addConstraints, dropConstraints, comments, snakeCase) => {
1062
1134
  if (item.type === "add") {
1063
1135
  const column = item.item;
1064
1136
  const name = getColumnName(column, key, snakeCase);
1065
1137
  addColumnIndex(addIndexes, name, column);
1138
+ addColumnExclude(addExcludes, name, column);
1066
1139
  addColumnComment(comments, name, column);
1067
1140
  alterTable.push(
1068
1141
  `ADD COLUMN ${columnToSql(
@@ -1167,38 +1240,15 @@ const handleTableItemChange = (key, item, ast, alterTable, renameItems, values,
1167
1240
  }
1168
1241
  }
1169
1242
  }
1170
- const indexesLen = Math.max(
1171
- from.indexes?.length || 0,
1172
- to.indexes?.length || 0
1243
+ pushIndexesOrExcludes("indexes", from, to, name, addIndexes, dropIndexes);
1244
+ pushIndexesOrExcludes(
1245
+ "excludes",
1246
+ from,
1247
+ to,
1248
+ name,
1249
+ addExcludes,
1250
+ dropExcludes
1173
1251
  );
1174
- for (let i = 0; i < indexesLen; i++) {
1175
- const fromIndex = from.indexes?.[i];
1176
- const toIndex = to.indexes?.[i];
1177
- if ((fromIndex || toIndex) && (!fromIndex || !toIndex || !orchidCore.deepCompare(fromIndex, toIndex))) {
1178
- if (fromIndex) {
1179
- dropIndexes.push({
1180
- ...fromIndex,
1181
- columns: [
1182
- {
1183
- column: name,
1184
- ...fromIndex.options
1185
- }
1186
- ]
1187
- });
1188
- }
1189
- if (toIndex) {
1190
- addIndexes.push({
1191
- ...toIndex,
1192
- columns: [
1193
- {
1194
- column: name,
1195
- ...toIndex.options
1196
- }
1197
- ]
1198
- });
1199
- }
1200
- }
1201
- }
1202
1252
  if (from.comment !== to.comment) {
1203
1253
  comments.push({ column: name, comment: to.comment || null });
1204
1254
  }
@@ -1208,6 +1258,39 @@ const handleTableItemChange = (key, item, ast, alterTable, renameItems, values,
1208
1258
  );
1209
1259
  }
1210
1260
  };
1261
+ const pushIndexesOrExcludes = (key, from, to, name, add2, drop2) => {
1262
+ const len = Math.max(from[key]?.length || 0, to[key]?.length || 0);
1263
+ for (let i = 0; i < len; i++) {
1264
+ const fromItem = from[key]?.[i];
1265
+ const toItem = to[key]?.[i];
1266
+ if ((fromItem || toItem) && (!fromItem || !toItem || !orchidCore.deepCompare(fromItem, toItem))) {
1267
+ if (fromItem) {
1268
+ drop2.push({
1269
+ ...fromItem,
1270
+ columns: [
1271
+ {
1272
+ column: name,
1273
+ ...fromItem.options,
1274
+ with: fromItem.with
1275
+ }
1276
+ ]
1277
+ });
1278
+ }
1279
+ if (toItem) {
1280
+ add2.push({
1281
+ ...toItem,
1282
+ columns: [
1283
+ {
1284
+ column: name,
1285
+ ...toItem.options,
1286
+ with: toItem.with
1287
+ }
1288
+ ]
1289
+ });
1290
+ }
1291
+ }
1292
+ }
1293
+ };
1211
1294
  const getChangeColumnName = (what, change, key, snakeCase) => {
1212
1295
  return change.name || (change[what].column ? (
1213
1296
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -3912,9 +3995,8 @@ async function introspectDbSchema(db) {
3912
3995
  }
3913
3996
  }
3914
3997
  const indexes = [];
3998
+ const excludes = [];
3915
3999
  for (const index of result.indexes) {
3916
- if (index.exclude) continue;
3917
- indexes.push(index);
3918
4000
  nullsToUndefined(index);
3919
4001
  for (const column of index.columns) {
3920
4002
  if (!("expression" in column)) continue;
@@ -3972,8 +4054,10 @@ async function introspectDbSchema(db) {
3972
4054
  }
3973
4055
  }
3974
4056
  }
4057
+ (index.exclude ? excludes : indexes).push(index);
3975
4058
  }
3976
4059
  result.indexes = indexes;
4060
+ result.excludes = excludes;
3977
4061
  return result;
3978
4062
  }
3979
4063
  const nullsToUndefined = (obj) => {
@@ -4173,7 +4257,7 @@ const instantiateColumnByDbType = (ctx, type, isSerial, params) => {
4173
4257
  const tableToAst = (ctx, data, table, action, domains) => {
4174
4258
  const { schemaName, name: tableName } = table;
4175
4259
  const tableData = getDbStructureTableData(data, table);
4176
- const { primaryKey, indexes, constraints } = tableData;
4260
+ const { primaryKey, constraints } = tableData;
4177
4261
  return {
4178
4262
  type: "table",
4179
4263
  action,
@@ -4183,25 +4267,16 @@ const tableToAst = (ctx, data, table, action, domains) => {
4183
4267
  shape: makeDbStructureColumnsShape(ctx, data, domains, table, tableData),
4184
4268
  noPrimaryKey: tableData.primaryKey ? "error" : "ignore",
4185
4269
  primaryKey: primaryKey && primaryKey.columns.length > 1 ? { ...primaryKey, columns: primaryKey.columns.map(orchidCore.toCamelCase) } : void 0,
4186
- indexes: indexes.reduce((acc, index) => {
4187
- if (index.columns.length > 1 || index.columns.some((it) => "expression" in it)) {
4188
- const { name, ...options } = makeIndexOptions(tableName, index);
4189
- acc.push({
4190
- columns: index.columns.map((it) => ({
4191
- ..."column" in it ? { column: orchidCore.toCamelCase(it.column) } : { expression: it.expression },
4192
- collate: it.collate,
4193
- opclass: it.opclass,
4194
- order: it.order
4195
- })),
4196
- options: {
4197
- ...options,
4198
- include: index.include?.map(orchidCore.toCamelCase)
4199
- },
4200
- name
4201
- });
4202
- }
4203
- return acc;
4204
- }, []),
4270
+ indexes: indexesOrExcludesToAst(
4271
+ tableName,
4272
+ tableData,
4273
+ "indexes"
4274
+ ),
4275
+ excludes: indexesOrExcludesToAst(
4276
+ tableName,
4277
+ tableData,
4278
+ "excludes"
4279
+ ),
4205
4280
  constraints: constraints.reduce((acc, it) => {
4206
4281
  if (it.check && it.references || it.check && it.check.columns?.length !== 1 || it.references && it.references.columns.length !== 1 && !checkIfIsOuterRecursiveFkey(data, table, it.references)) {
4207
4282
  acc.push(dbConstraintToTableConstraint(ctx, table, it));
@@ -4210,22 +4285,47 @@ const tableToAst = (ctx, data, table, action, domains) => {
4210
4285
  }, [])
4211
4286
  };
4212
4287
  };
4288
+ const indexesOrExcludesToAst = (tableName, tableData, key) => {
4289
+ return tableData[key].reduce((acc, item) => {
4290
+ if (item.columns.length > 1 || item.columns.some((it) => "expression" in it)) {
4291
+ const { name, ...options } = makeIndexOrExcludeOptions(
4292
+ tableName,
4293
+ item,
4294
+ key
4295
+ );
4296
+ acc.push({
4297
+ columns: item.columns.map((it, i) => ({
4298
+ with: "exclude" in item && item.exclude ? item.exclude[i] : void 0,
4299
+ ..."column" in it ? { column: orchidCore.toCamelCase(it.column) } : { expression: it.expression },
4300
+ collate: it.collate,
4301
+ opclass: it.opclass,
4302
+ order: it.order
4303
+ })),
4304
+ options: {
4305
+ ...options,
4306
+ include: item.include?.map(orchidCore.toCamelCase)
4307
+ },
4308
+ name
4309
+ });
4310
+ }
4311
+ return acc;
4312
+ }, []);
4313
+ };
4213
4314
  const getDbStructureTableData = (data, { name, schemaName }) => {
4214
- const constraints = data.constraints.filter(
4215
- (c) => c.tableName === name && c.schemaName === schemaName
4216
- );
4315
+ const filterFn = filterByTableSchema(name, schemaName);
4316
+ const constraints = data.constraints.filter(filterFn);
4217
4317
  const primaryKey = constraints.find((c) => c.primaryKey);
4218
4318
  return {
4219
4319
  primaryKey: primaryKey?.primaryKey ? {
4220
4320
  columns: primaryKey.primaryKey,
4221
4321
  name: primaryKey.name === `${name}_pkey` ? void 0 : primaryKey.name
4222
4322
  } : void 0,
4223
- indexes: data.indexes.filter(
4224
- (it) => it.tableName === name && it.schemaName === schemaName
4225
- ),
4323
+ indexes: data.indexes.filter(filterFn),
4324
+ excludes: data.excludes.filter(filterFn),
4226
4325
  constraints
4227
4326
  };
4228
4327
  };
4328
+ const filterByTableSchema = (tableName, schemaName) => (x) => x.tableName === tableName && x.schemaName === schemaName;
4229
4329
  const constraintToAst = (ctx, item) => {
4230
4330
  const result = {};
4231
4331
  const { references, check } = item;
@@ -4309,7 +4409,6 @@ const getDbTableColumnsChecks = (tableData) => tableData.constraints.reduce((acc
4309
4409
  return acc;
4310
4410
  }, {});
4311
4411
  const dbColumnToAst = (ctx, data, domains, tableName, item, table, tableData, checks) => {
4312
- var _a;
4313
4412
  let column = instantiateDbColumn(ctx, data, domains, item);
4314
4413
  column.data.name = item.name;
4315
4414
  if (item.identity) {
@@ -4319,24 +4418,14 @@ const dbColumnToAst = (ctx, data, domains, tableName, item, table, tableData, ch
4319
4418
  if (tableData?.primaryKey?.columns?.length === 1 && tableData?.primaryKey?.columns[0] === item.name) {
4320
4419
  column = column.primaryKey();
4321
4420
  }
4322
- if (tableData?.indexes) {
4323
- const columnIndexes = tableData?.indexes.filter(
4324
- (it) => it.columns.length === 1 && "column" in it.columns[0] && it.columns[0].column === item.name
4325
- );
4326
- for (const index of columnIndexes) {
4327
- const columnOptions = index.columns[0];
4328
- const { name, ...indexOptions } = makeIndexOptions(tableName, index);
4329
- ((_a = column.data).indexes ?? (_a.indexes = [])).push({
4330
- options: {
4331
- collate: columnOptions.collate,
4332
- opclass: columnOptions.opclass,
4333
- order: columnOptions.order,
4334
- ...indexOptions
4335
- },
4336
- name
4337
- });
4338
- }
4339
- }
4421
+ collectColumnIndexesOrExcludes(item, column, tableName, tableData, "indexes");
4422
+ collectColumnIndexesOrExcludes(
4423
+ item,
4424
+ column,
4425
+ tableName,
4426
+ tableData,
4427
+ "excludes"
4428
+ );
4340
4429
  if (table) {
4341
4430
  for (const it of data.constraints) {
4342
4431
  if (it.tableName !== table.name || it.schemaName !== table.schemaName || it.check || it.references?.columns.length !== 1 || it.references.columns[0] !== item.name || checkIfIsOuterRecursiveFkey(data, table, it.references)) {
@@ -4365,6 +4454,32 @@ const dbColumnToAst = (ctx, data, domains, tableName, item, table, tableData, ch
4365
4454
  }
4366
4455
  return [camelCaseName, column];
4367
4456
  };
4457
+ const collectColumnIndexesOrExcludes = (dbColumn, column, tableName, tableData, key) => {
4458
+ var _a;
4459
+ const items = tableData?.[key];
4460
+ if (!items) return;
4461
+ const columnItems = items.filter(
4462
+ (it) => it.columns.length === 1 && "column" in it.columns[0] && it.columns[0].column === dbColumn.name
4463
+ );
4464
+ for (const item of columnItems) {
4465
+ const columnOptions = item.columns[0];
4466
+ const { name, ...itemOptions } = makeIndexOrExcludeOptions(
4467
+ tableName,
4468
+ item,
4469
+ key
4470
+ );
4471
+ ((_a = column.data)[key] ?? (_a[key] = [])).push({
4472
+ with: "exclude" in item && item.exclude ? item.exclude[0] : void 0,
4473
+ options: {
4474
+ collate: columnOptions.collate,
4475
+ opclass: columnOptions.opclass,
4476
+ order: columnOptions.order,
4477
+ ...itemOptions
4478
+ },
4479
+ name
4480
+ });
4481
+ }
4482
+ };
4368
4483
  const dbConstraintToTableConstraint = (ctx, table, item) => {
4369
4484
  const { references, check } = item;
4370
4485
  const constraint = {
@@ -4389,9 +4504,12 @@ const dbConstraintToTableConstraint = (ctx, table, item) => {
4389
4504
  }
4390
4505
  return constraint;
4391
4506
  };
4392
- const makeIndexOptions = (tableName, index) => {
4507
+ const makeIndexOrExcludeOptions = (tableName, index, key) => {
4393
4508
  return {
4394
- name: index.name !== getIndexName(tableName, index.columns) ? index.name : void 0,
4509
+ name: index.name !== (key === "indexes" ? getIndexName : getExcludeName)(
4510
+ tableName,
4511
+ index.columns
4512
+ ) ? index.name : void 0,
4395
4513
  using: index.using === "btree" ? void 0 : index.using,
4396
4514
  unique: index.unique || void 0,
4397
4515
  include: index.include,
@@ -4605,16 +4723,8 @@ const analyzeTableColumns = (config, currentSchema, schema, table, deps, resolve
4605
4723
  if (primaryKey) {
4606
4724
  keys.push(`${table}_pkey`);
4607
4725
  }
4608
- const indexes = change.indexes || change.column?.data.indexes;
4609
- if (indexes) {
4610
- for (const index of indexes) {
4611
- keys.push(
4612
- index.name ? `${schema}.${index.name}` : getIndexName(table, [
4613
- { column: change.column?.data.name ?? name }
4614
- ])
4615
- );
4616
- }
4617
- }
4726
+ pushIndexOrExcludeKeys(change, keys, schema, table, name, "indexes");
4727
+ pushIndexOrExcludeKeys(change, keys, schema, table, name, "excludes");
4618
4728
  const foreignKeys = change.foreignKeys || change.column?.data.foreignKeys;
4619
4729
  if (foreignKeys) {
4620
4730
  for (const fkey of foreignKeys) {
@@ -4633,18 +4743,33 @@ const analyzeTableColumns = (config, currentSchema, schema, table, deps, resolve
4633
4743
  }
4634
4744
  }
4635
4745
  };
4746
+ const pushIndexOrExcludeKeys = (change, keys, schema, table, name, key) => {
4747
+ const items = change[key] || change.column?.data[key];
4748
+ if (items) {
4749
+ const getName = key === "indexes" ? getIndexName : getExcludeName;
4750
+ for (const x of items) {
4751
+ keys.push(
4752
+ x.name ? `${schema}.${x.name}` : getName(table, [{ column: change.column?.data.name ?? name }])
4753
+ );
4754
+ }
4755
+ }
4756
+ };
4757
+ const pushIndexesOrExcludesKeys = (keys, schema, table, data, key) => {
4758
+ const arr = data[key];
4759
+ if (arr) {
4760
+ const getName = key === "indexes" ? getIndexName : getExcludeName;
4761
+ for (const x of arr) {
4762
+ keys.push(x.name ? `${schema}.${x.name}` : getName(table, x.columns));
4763
+ }
4764
+ }
4765
+ };
4636
4766
  const analyzeTableData = (config, currentSchema, schema, table, keys, deps, data) => {
4637
4767
  if (data.primaryKey) {
4638
4768
  const name = data.primaryKey.name;
4639
4769
  keys.push(name ? `${schema}.${name}` : `${table}_pkey`);
4640
4770
  }
4641
- if (data.indexes) {
4642
- for (const index of data.indexes) {
4643
- keys.push(
4644
- index.name ? `${schema}.${index.name}` : getIndexName(table, index.columns)
4645
- );
4646
- }
4647
- }
4771
+ pushIndexesOrExcludesKeys(keys, schema, table, data, "indexes");
4772
+ pushIndexesOrExcludesKeys(keys, schema, table, data, "excludes");
4648
4773
  if (data.constraints) {
4649
4774
  for (const constraint of data.constraints) {
4650
4775
  keys.push(
@@ -4781,7 +4906,7 @@ const astEncoders = {
4781
4906
  const result = code;
4782
4907
  const hasOptions = Boolean(ast.comment || ast.noPrimaryKey === "ignore");
4783
4908
  const hasTableData = Boolean(
4784
- ast.primaryKey || ast.indexes?.length || ast.constraints?.length
4909
+ ast.primaryKey || ast.indexes?.length || ast.excludes?.length || ast.constraints?.length
4785
4910
  );
4786
4911
  const isShifted = hasOptions || hasTableData;
4787
4912
  if (isShifted) {
@@ -4938,15 +5063,20 @@ const astEncoders = {
4938
5063
  if (timestamps.hasAnyTimestamps) {
4939
5064
  orchidCore.addCode(code, [`...t.${key}(${timestampsToCode(timestamps)}),`]);
4940
5065
  }
4941
- const { primaryKey, indexes, constraints } = ast[key];
5066
+ const { primaryKey, indexes, excludes, constraints } = ast[key];
4942
5067
  if (primaryKey) {
4943
5068
  orchidCore.addCode(code, [
4944
5069
  `...t.${key}(${pqb.primaryKeyInnerToCode(primaryKey, "t")}),`
4945
5070
  ]);
4946
5071
  }
4947
5072
  if (indexes) {
4948
- for (const index of indexes) {
4949
- orchidCore.addCode(code, [`...t.${key}(`, pqb.indexInnerToCode(index, "t"), "),"]);
5073
+ for (const item of indexes) {
5074
+ orchidCore.addCode(code, [`...t.${key}(`, pqb.indexInnerToCode(item, "t"), "),"]);
5075
+ }
5076
+ }
5077
+ if (excludes) {
5078
+ for (const item of excludes) {
5079
+ orchidCore.addCode(code, [`...t.${key}(`, pqb.excludeInnerToCode(item, "t"), "),"]);
4950
5080
  }
4951
5081
  }
4952
5082
  if (constraints) {
@@ -5655,6 +5785,7 @@ exports.Migration = Migration;
5655
5785
  exports.NoMigrationsTableError = NoMigrationsTableError;
5656
5786
  exports.RAKE_DB_LOCK_KEY = RAKE_DB_LOCK_KEY;
5657
5787
  exports.addColumnComment = addColumnComment;
5788
+ exports.addColumnExclude = addColumnExclude;
5658
5789
  exports.addColumnIndex = addColumnIndex;
5659
5790
  exports.addOrDropEnumValues = addOrDropEnumValues;
5660
5791
  exports.astToMigration = astToMigration;
@@ -5673,6 +5804,7 @@ exports.dbColumnToAst = dbColumnToAst;
5673
5804
  exports.deleteMigratedVersion = deleteMigratedVersion;
5674
5805
  exports.dropDb = dropDb;
5675
5806
  exports.encodeColumnDefault = encodeColumnDefault;
5807
+ exports.excludesToQuery = excludesToQuery;
5676
5808
  exports.exhaustive = exhaustive;
5677
5809
  exports.generateTimeStamp = generateTimeStamp;
5678
5810
  exports.getColumnName = getColumnName;
@@ -5681,6 +5813,7 @@ exports.getCurrentChanges = getCurrentChanges;
5681
5813
  exports.getDatabaseAndUserFromOptions = getDatabaseAndUserFromOptions;
5682
5814
  exports.getDbStructureTableData = getDbStructureTableData;
5683
5815
  exports.getDbTableColumnsChecks = getDbTableColumnsChecks;
5816
+ exports.getExcludeName = getExcludeName;
5684
5817
  exports.getFirstWordAndRest = getFirstWordAndRest;
5685
5818
  exports.getForeignKeyTable = getForeignKeyTable;
5686
5819
  exports.getIndexName = getIndexName;