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