pqb 0.19.0 → 0.20.0

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
@@ -1032,38 +1032,40 @@ const windowToSql = (ctx, data, window, quotedAs) => {
1032
1032
  };
1033
1033
 
1034
1034
  const pushWhereStatementSql = (ctx, table, query, quotedAs) => {
1035
- const res = whereToSql(ctx, table, query, quotedAs, false);
1035
+ const res = whereToSql(ctx, table, query, quotedAs);
1036
1036
  if (res) {
1037
1037
  ctx.sql.push("WHERE", res);
1038
1038
  }
1039
1039
  };
1040
- const pushWhereToSql = (sql, ctx, table, query, quotedAs, not) => {
1041
- const res = whereToSql(ctx, table, query, quotedAs, not);
1040
+ const pushWhereToSql = (sql, ctx, table, query, quotedAs, parens) => {
1041
+ const res = whereToSql(ctx, table, query, quotedAs, parens);
1042
1042
  if (res) {
1043
1043
  sql.push(res);
1044
1044
  }
1045
1045
  };
1046
- const whereToSql = (ctx, table, query, quotedAs, not) => {
1046
+ const whereToSql = (ctx, table, query, quotedAs, parens) => {
1047
1047
  var _a;
1048
+ let sql;
1048
1049
  if (query.or) {
1049
1050
  const ors = ((_a = query.and) == null ? void 0 : _a.length) ? [query.and, ...query.or] : query.or;
1050
- return ors.map((and) => processAnds(and, ctx, table, query, quotedAs, not)).join(" OR ");
1051
+ sql = ors.map((and) => processAnds(and, ctx, table, query, quotedAs)).join(" OR ");
1051
1052
  } else if (query.and) {
1052
- return processAnds(query.and, ctx, table, query, quotedAs, not);
1053
+ sql = processAnds(query.and, ctx, table, query, quotedAs);
1053
1054
  } else {
1054
- return void 0;
1055
+ return;
1055
1056
  }
1057
+ return parens ? `(${sql})` : sql;
1056
1058
  };
1057
- const processAnds = (and, ctx, table, query, quotedAs, not) => {
1059
+ const processAnds = (and, ctx, table, query, quotedAs, parens) => {
1058
1060
  const ands = [];
1059
1061
  for (const data of and) {
1060
- processWhere(ands, ctx, table, query, data, quotedAs, not);
1062
+ processWhere(ands, ctx, table, query, data, quotedAs);
1061
1063
  }
1062
- return ands.join(" AND ");
1064
+ const sql = ands.join(" AND ");
1065
+ return parens && ands.length > 1 ? `(${sql})` : sql;
1063
1066
  };
1064
- const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1067
+ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
1065
1068
  var _a, _b;
1066
- const prefix = not ? "NOT " : "";
1067
1069
  if (typeof data === "function") {
1068
1070
  const qb = Object.create(table);
1069
1071
  qb.q = getClonedQueryData(query);
@@ -1074,9 +1076,9 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1074
1076
  if (!(res instanceof Expression) && res.q.expr) {
1075
1077
  const q = "relationConfig" in res ? res.relationConfig.joinQuery(res, table) : res.clone();
1076
1078
  q.q.select = [expr];
1077
- ands.push(`${prefix}(${makeSQL(q, ctx).text})`);
1079
+ ands.push(`(${makeSQL(q, ctx).text})`);
1078
1080
  } else {
1079
- pushWhereToSql(ands, ctx, res, res.q, quotedAs, not);
1081
+ pushWhereToSql(ands, ctx, res, res.q, quotedAs, true);
1080
1082
  }
1081
1083
  return;
1082
1084
  }
@@ -1089,12 +1091,12 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1089
1091
  query2.table && `"${query2.table}"`
1090
1092
  );
1091
1093
  if (sql) {
1092
- ands.push(`${prefix}(${sql})`);
1094
+ ands.push(`(${sql})`);
1093
1095
  }
1094
1096
  return;
1095
1097
  }
1096
1098
  if (isExpression(data)) {
1097
- ands.push(`${prefix}(${data.toSQL(ctx, quotedAs)})`);
1099
+ ands.push(`(${data.toSQL(ctx, quotedAs)})`);
1098
1100
  return;
1099
1101
  }
1100
1102
  for (const key in data) {
@@ -1103,15 +1105,15 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1103
1105
  continue;
1104
1106
  if (key === "AND") {
1105
1107
  const arr = toArray(value);
1106
- ands.push(processAnds(arr, ctx, table, query, quotedAs, not));
1108
+ ands.push(processAnds(arr, ctx, table, query, quotedAs));
1107
1109
  } else if (key === "OR") {
1108
1110
  const arr = value.map(toArray);
1109
1111
  ands.push(
1110
- arr.map((and) => processAnds(and, ctx, table, query, quotedAs, not)).join(" OR ")
1112
+ arr.map((and) => processAnds(and, ctx, table, query, quotedAs)).join(" OR ")
1111
1113
  );
1112
1114
  } else if (key === "NOT") {
1113
1115
  const arr = toArray(value);
1114
- ands.push(processAnds(arr, ctx, table, query, quotedAs, !not));
1116
+ ands.push(`NOT ${processAnds(arr, ctx, table, query, quotedAs, true)}`);
1115
1117
  } else if (key === "ON") {
1116
1118
  if (Array.isArray(value)) {
1117
1119
  const item = value;
@@ -1132,7 +1134,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1132
1134
  );
1133
1135
  const rightPath = item[3];
1134
1136
  ands.push(
1135
- `${prefix}jsonb_path_query_first(${leftColumn}, ${addValue(
1137
+ `jsonb_path_query_first(${leftColumn}, ${addValue(
1136
1138
  ctx.values,
1137
1139
  leftPath
1138
1140
  )}) = jsonb_path_query_first(${rightColumn}, ${addValue(
@@ -1172,11 +1174,11 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1172
1174
  `"${joinTo}"`
1173
1175
  );
1174
1176
  }
1175
- ands.push(`${prefix}${leftColumn} ${op} ${rightColumn}`);
1177
+ ands.push(`${leftColumn} ${op} ${rightColumn}`);
1176
1178
  }
1177
1179
  } else if (key === "IN") {
1178
1180
  toArray(value).forEach((item) => {
1179
- pushIn(ctx, query, ands, prefix, quotedAs, item);
1181
+ pushIn(ctx, query, ands, quotedAs, item);
1180
1182
  });
1181
1183
  } else if (key === "EXISTS") {
1182
1184
  const joinItems = Array.isArray(value[0]) ? value : [value];
@@ -1188,17 +1190,15 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1188
1190
  args,
1189
1191
  quotedAs
1190
1192
  );
1191
- ands.push(
1192
- `${prefix}EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`
1193
- );
1193
+ ands.push(`EXISTS (SELECT 1 FROM ${target} WHERE ${conditions})`);
1194
1194
  }
1195
1195
  } else if (key === "SEARCH") {
1196
1196
  const search = value;
1197
- ands.push(`${prefix}${search.vectorSQL} @@ "${search.as}"`);
1197
+ ands.push(`${search.vectorSQL} @@ "${search.as}"`);
1198
1198
  } else if (typeof value === "object" && value && !(value instanceof Date)) {
1199
1199
  if (isExpression(value)) {
1200
1200
  ands.push(
1201
- `${prefix}${columnToSql(
1201
+ `${columnToSql(
1202
1202
  ctx,
1203
1203
  query,
1204
1204
  query.shape,
@@ -1227,9 +1227,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1227
1227
  }
1228
1228
  }
1229
1229
  if (value instanceof ctx.queryBuilder.constructor) {
1230
- ands.push(
1231
- `${prefix}${quotedColumn} = (${value.toSQL(ctx).text})`
1232
- );
1230
+ ands.push(`${quotedColumn} = (${value.toSQL(ctx).text})`);
1233
1231
  } else {
1234
1232
  for (const op in value) {
1235
1233
  const operator = column.operators[op];
@@ -1239,7 +1237,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1239
1237
  if (value[op] === void 0)
1240
1238
  continue;
1241
1239
  ands.push(
1242
- `${prefix}${operator._op(
1240
+ `${operator._op(
1243
1241
  quotedColumn,
1244
1242
  value[op],
1245
1243
  ctx,
@@ -1251,7 +1249,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1251
1249
  }
1252
1250
  } else {
1253
1251
  ands.push(
1254
- `${prefix}${columnToSql(ctx, query, query.shape, key, quotedAs)} ${value === null ? "IS NULL" : `= ${addValue(ctx.values, value)}`}`
1252
+ `${columnToSql(ctx, query, query.shape, key, quotedAs)} ${value === null ? "IS NULL" : `= ${addValue(ctx.values, value)}`}`
1255
1253
  );
1256
1254
  }
1257
1255
  }
@@ -1259,7 +1257,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs, not) => {
1259
1257
  const getJoinItemSource = (joinItem) => {
1260
1258
  return typeof joinItem === "string" ? joinItem : getQueryAs(joinItem);
1261
1259
  };
1262
- const pushIn = (ctx, query, ands, prefix, quotedAs, arg) => {
1260
+ const pushIn = (ctx, query, ands, quotedAs, arg) => {
1263
1261
  const multiple = arg.columns.length > 1;
1264
1262
  let value;
1265
1263
  if (Array.isArray(arg.values)) {
@@ -1274,9 +1272,7 @@ const pushIn = (ctx, query, ands, prefix, quotedAs, arg) => {
1274
1272
  value = `(${sql.text})`;
1275
1273
  }
1276
1274
  const columnsSql = arg.columns.map((column) => columnToSql(ctx, query, query.shape, column, quotedAs)).join(", ");
1277
- ands.push(
1278
- `${prefix}${multiple ? `(${columnsSql})` : columnsSql} IN ${value}`
1279
- );
1275
+ ands.push(`${multiple ? `(${columnsSql})` : columnsSql} IN ${value}`);
1280
1276
  };
1281
1277
 
1282
1278
  var __defProp$e = Object.defineProperty;
@@ -6524,7 +6520,6 @@ const addOrNot = (q, args) => {
6524
6520
  );
6525
6521
  };
6526
6522
  const addWhereIn = (q, and, arg, values, not) => {
6527
- const op = not ? "notIn" : "in";
6528
6523
  let item;
6529
6524
  if (values) {
6530
6525
  if (Array.isArray(arg)) {
@@ -6534,17 +6529,17 @@ const addWhereIn = (q, and, arg, values, not) => {
6534
6529
  values
6535
6530
  }
6536
6531
  };
6537
- if (not)
6538
- item = { NOT: item };
6539
6532
  } else {
6540
- item = { [arg]: { [op]: values } };
6533
+ item = { [arg]: { in: values } };
6541
6534
  }
6542
6535
  } else {
6543
6536
  item = {};
6544
6537
  for (const key in arg) {
6545
- item[key] = { [op]: arg[key] };
6538
+ item[key] = { in: arg[key] };
6546
6539
  }
6547
6540
  }
6541
+ if (not)
6542
+ item = { NOT: item };
6548
6543
  if (and) {
6549
6544
  pushQueryValue(q, "and", item);
6550
6545
  } else {
@@ -9325,6 +9320,63 @@ const noneMethods = {
9325
9320
  catch: () => new Promise(noop)
9326
9321
  };
9327
9322
 
9323
+ class ScopeMethods {
9324
+ /**
9325
+ * See {@link ScopeMethods}
9326
+ *
9327
+ * Use the `scope` method to apply a pre-defined scope.
9328
+ *
9329
+ * ```ts
9330
+ * // use the `active` scope that is defined in the table:
9331
+ * await db.some.scope('active');
9332
+ * ```
9333
+ *
9334
+ * @param scope - name of the scope to apply
9335
+ */
9336
+ scope(scope) {
9337
+ var _a;
9338
+ const q = this.clone();
9339
+ if (!((_a = q.q.scopes) == null ? void 0 : _a[scope])) {
9340
+ const s = this.internal.scopes[scope];
9341
+ if (s.and)
9342
+ pushQueryArray(q, "and", s.and);
9343
+ if (s.or)
9344
+ pushQueryArray(q, "or", s.or);
9345
+ setQueryObjectValue(q, "scopes", scope, s);
9346
+ }
9347
+ return q;
9348
+ }
9349
+ /**
9350
+ * See {@link ScopeMethods}
9351
+ *
9352
+ * Remove conditions that were added by the scope from the query.
9353
+ *
9354
+ * ```ts
9355
+ * // SomeTable has a default scope, ignore it for this query:
9356
+ * await db.some.unScope('default');
9357
+ * ```
9358
+ *
9359
+ * @param scope - name of the scope to remove from the query
9360
+ */
9361
+ unScope(scope) {
9362
+ var _a;
9363
+ const q = this.clone();
9364
+ const data = q.q;
9365
+ const s = (_a = q.q.scopes) == null ? void 0 : _a[scope];
9366
+ if (s) {
9367
+ const { and, or } = s;
9368
+ if (and) {
9369
+ data.and = data.and.filter((x) => !and.includes(x));
9370
+ }
9371
+ if (or) {
9372
+ data.or = data.or.filter((x) => !or.includes(x));
9373
+ }
9374
+ delete q.q.scopes[scope];
9375
+ }
9376
+ return q;
9377
+ }
9378
+ }
9379
+
9328
9380
  class ColumnRefExpression extends Expression {
9329
9381
  constructor(_type, name) {
9330
9382
  super();
@@ -9961,7 +10013,8 @@ applyMixins(QueryMethods, [
9961
10013
  MergeQueryMethods,
9962
10014
  RawSqlMethods,
9963
10015
  CopyMethods,
9964
- TransformMethods
10016
+ TransformMethods,
10017
+ ScopeMethods
9965
10018
  ]);
9966
10019
 
9967
10020
  var __defProp = Object.defineProperty;
@@ -10004,10 +10057,12 @@ class Db {
10004
10057
  this.shape = shape;
10005
10058
  this.columnTypes = columnTypes2;
10006
10059
  var _a, _b;
10007
- const tableData = getTableData();
10008
10060
  const self = this;
10061
+ const scopes = options.scopes ? {} : emptyObject;
10062
+ const tableData = getTableData();
10009
10063
  this.internal = __spreadProps(__spreadValues({}, tableData), {
10010
- transactionStorage
10064
+ transactionStorage,
10065
+ scopes
10011
10066
  });
10012
10067
  this.baseQuery = this;
10013
10068
  const logger = options.logger || console;
@@ -10110,6 +10165,21 @@ class Db {
10110
10165
  super(self, message);
10111
10166
  }
10112
10167
  };
10168
+ if (options.scopes) {
10169
+ for (const key in options.scopes) {
10170
+ const q = options.scopes[key](this).q;
10171
+ const s = {};
10172
+ if (q.and)
10173
+ s.and = q.and;
10174
+ if (q.or)
10175
+ s.or = q.or;
10176
+ scopes[key] = s;
10177
+ }
10178
+ if (scopes.default) {
10179
+ Object.assign(this.q, scopes.default);
10180
+ this.q.scopes = { default: scopes.default };
10181
+ }
10182
+ }
10113
10183
  }
10114
10184
  [inspect.custom]() {
10115
10185
  return `QueryObject<${this.table}>`;
@@ -10258,21 +10328,19 @@ const createDb = (_a) => {
10258
10328
  commonOptions
10259
10329
  );
10260
10330
  qb.queryBuilder = qb;
10261
- const db = Object.assign(
10262
- (table, shape, options2) => {
10263
- return new Db(
10264
- adapter,
10265
- qb,
10266
- table,
10267
- typeof shape === "function" ? getColumnTypes(ct, shape, nowSQL, options2 == null ? void 0 : options2.language) : shape,
10268
- ct,
10269
- transactionStorage,
10270
- __spreadValues(__spreadValues({}, commonOptions), options2)
10271
- );
10272
- },
10331
+ const tableConstructor = (table, shape, options2) => new Db(
10332
+ adapter,
10273
10333
  qb,
10274
- { adapter, close: () => adapter.close() }
10334
+ table,
10335
+ typeof shape === "function" ? getColumnTypes(ct, shape, nowSQL, options2 == null ? void 0 : options2.language) : shape,
10336
+ ct,
10337
+ transactionStorage,
10338
+ __spreadValues(__spreadValues({}, commonOptions), options2)
10275
10339
  );
10340
+ const db = Object.assign(tableConstructor, qb, {
10341
+ adapter,
10342
+ close: () => adapter.close()
10343
+ });
10276
10344
  for (const name of Object.getOwnPropertyNames(Db.prototype)) {
10277
10345
  db[name] = Db.prototype[name];
10278
10346
  }