orchid-orm 1.47.1 → 1.49.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
@@ -1,6 +1,6 @@
1
- import { makeColumnTypes, QueryHooks, defaultSchemaConfig, raw, getColumnTypes, parseTableData, _queryHookAfterCreate, _queryHookAfterUpdate, getQueryAs, setQueryObjectValueImmutable, pushQueryOnForOuter, _queryWhere, _queryDefaults, VirtualColumn, pushQueryValueImmutable, _queryCreateMany, isQueryReturnsAll, _queryHookBeforeUpdate, _queryFindBy, _queryCreate, _queryRows, _queryUpdate, _queryDelete, _queryUpdateOrThrow, OrchidOrmInternalError, _queryJoinOn, _queryCreateFrom, NotFoundError, _queryFindByOptional, _querySelect, _queryWhereExists, _queryTake, _queryTakeOptional, Adapter, _initQueryBuilder, Db, getClonedQueryData } from 'pqb';
1
+ import { makeColumnTypes, QueryHooks, defaultSchemaConfig, raw, getColumnTypes, parseTableData, _queryHookAfterCreate, _queryHookAfterUpdate, getQueryAs, setQueryObjectValueImmutable, pushQueryOnForOuter, cloneQueryBaseUnscoped, DynamicRawSQL, RawSQL, getShapeFromSelect, _queryWhere, _queryDefaults, getPrimaryKeys, VirtualColumn, pushQueryValueImmutable, _queryCreateMany, isQueryReturnsAll, _queryHookBeforeUpdate, _queryFindBy, _queryCreate, _queryRows, _queryUpdate, _queryDelete, _queryUpdateOrThrow, OrchidOrmInternalError, _queryJoinOn, _queryCreateFrom, NotFoundError, _queryFindByOptional, _querySelect, _queryWhereExists, _queryTake, _queryTakeOptional, Adapter, _initQueryBuilder, Db, getClonedQueryData } from 'pqb';
2
2
  export * from 'pqb';
3
- import { getStackTrace, applyMixins, getCallerFilePath, snakeCaseKey, toSnakeCase, emptyObject, emptyArray, toArray, objectHasValues, pick } from 'orchid-core';
3
+ import { getStackTrace, applyMixins, getCallerFilePath, snakeCaseKey, toSnakeCase, emptyObject, emptyArray, isExpression, toArray, objectHasValues, pick } from 'orchid-core';
4
4
  export * from 'orchid-core';
5
5
  import { AsyncLocalStorage } from 'node:async_hooks';
6
6
 
@@ -206,7 +206,10 @@ const selectIfNotSelected = (q, columns) => {
206
206
  };
207
207
  function joinHasThrough(q, baseQuery, joiningQuery, throughRelation, sourceRelation) {
208
208
  return q.whereExists(
209
- throughRelation.joinQuery(throughRelation.query, baseQuery),
209
+ throughRelation.joinQuery(
210
+ throughRelation.query,
211
+ baseQuery
212
+ ),
210
213
  () => {
211
214
  const as = getQueryAs(joiningQuery);
212
215
  return sourceRelation.joinQuery(
@@ -231,17 +234,6 @@ function joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len)
231
234
  }
232
235
  return q;
233
236
  }
234
- const joinQueryChainingHOF = (reverseJoin, joinQuery) => (joiningQuery, baseQuery) => {
235
- const chain = joiningQuery.q.relChain;
236
- if (!chain || chain.length === 1) {
237
- return joinQuery(joiningQuery, baseQuery);
238
- }
239
- const last = chain[chain.length - 1];
240
- const query = "relationConfig" in last ? last.relationConfig.joinQuery(last, baseQuery) : last;
241
- return joiningQuery.where({
242
- EXISTS: { q: reverseJoin(query, joiningQuery) }
243
- });
244
- };
245
237
  const addAutoForeignKey = (tableConfig, from, to, primaryKeys, foreignKeys, options) => {
246
238
  var _a;
247
239
  const toTable = to.table;
@@ -298,6 +290,66 @@ const getColumnKeyFromDbName = (query, name) => {
298
290
  return name;
299
291
  };
300
292
 
293
+ const joinQueryChainHOF = (relPKeys, reverseJoin, joinQuery) => (joiningQuery, baseQuery) => {
294
+ const jq = joiningQuery;
295
+ const chain = jq.q.relChain;
296
+ if (!chain || chain.length === 1) {
297
+ return joinQuery(jq, baseQuery);
298
+ }
299
+ const last = chain[chain.length - 1];
300
+ const query = "relationConfig" in last ? last.relationConfig.joinQuery(last, baseQuery) : last;
301
+ const result = jq.join(
302
+ { _internalJoin: reverseJoin(query, jq) },
303
+ void 0
304
+ );
305
+ if (!query.q.chainMultiple) {
306
+ return result;
307
+ }
308
+ const item = selectRowNumber(result, relPKeys);
309
+ combineOrdering(result, query);
310
+ return wrapQuery(jq, result, item);
311
+ };
312
+ const selectRowNumber = (result, relPKeys) => {
313
+ const hookSelect = result.q.hookSelect = new Map(
314
+ result.q.hookSelect && [...result.q.hookSelect]
315
+ );
316
+ const as = `"${getQueryAs(result)}"`;
317
+ const partitionColumns = relPKeys.map(
318
+ (key) => `${as}."${result.shape[key]?.data.name || key}"`
319
+ );
320
+ const item = {
321
+ select: {
322
+ sql: `row_number() OVER (PARTITION BY ${partitionColumns.join(", ")})`
323
+ }
324
+ };
325
+ hookSelect.set("r", item);
326
+ return item;
327
+ };
328
+ const combineOrdering = (result, joined) => {
329
+ const { order } = joined.q;
330
+ if (order) {
331
+ const as = getQueryAs(joined);
332
+ const add = order.map(
333
+ (o) => typeof o === "string" ? `${as}.${o}` : isExpression(o) ? o : Object.fromEntries(
334
+ Object.entries(o).map(([key, value]) => [`${as}.${key}`, value])
335
+ )
336
+ );
337
+ const arr = result.q.order;
338
+ result.q.order = arr ? [...add, ...arr] : add;
339
+ }
340
+ };
341
+ const wrapQuery = (joiningQuery, result, item) => {
342
+ const baseOuterQuery = cloneQueryBaseUnscoped(joiningQuery);
343
+ const outer = baseOuterQuery.clone();
344
+ outer.q.and = [new DynamicRawSQL(() => new RawSQL(`${item.as || "r"} = 1`))];
345
+ outer.q.useFromLimitOffset = true;
346
+ outer.shape = getShapeFromSelect(result, true);
347
+ outer.q.select = Object.keys(outer.shape);
348
+ outer.q.returnType = result.q.returnType;
349
+ result.q.returnsOne = true;
350
+ return result.wrap(outer);
351
+ };
352
+
301
353
  class BelongsToVirtualColumn extends VirtualColumn {
302
354
  constructor(schema, key, state) {
303
355
  super(schema);
@@ -404,9 +456,15 @@ const makeBelongsToMethod = (tableConfig, table, relation, relationName, query)
404
456
  relationName,
405
457
  state
406
458
  ),
407
- joinQuery: joinQueryChainingHOF(
459
+ joinQuery: joinQueryChainHOF(
460
+ getPrimaryKeys(query),
408
461
  reverseJoin,
409
- (joiningQuery, baseQuery) => join(baseQuery, joiningQuery, primaryKeys, foreignKeys)
462
+ (joiningQuery, baseQuery) => join(
463
+ baseQuery,
464
+ joiningQuery,
465
+ primaryKeys,
466
+ foreignKeys
467
+ )
410
468
  ),
411
469
  reverseJoin
412
470
  };
@@ -643,6 +701,7 @@ class HasOneVirtualColumn extends VirtualColumn {
643
701
  }
644
702
  }
645
703
  const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
704
+ const relPKeys = getPrimaryKeys(query);
646
705
  if ("through" in relation.options) {
647
706
  const { through, source } = relation.options;
648
707
  const throughRelation = getThroughRelation(table, through);
@@ -670,7 +729,8 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
670
729
  const throughQuery = table.queryRelated(through, params);
671
730
  return query.whereExists(throughQuery, whereExistsCallback);
672
731
  },
673
- joinQuery: joinQueryChainingHOF(
732
+ joinQuery: joinQueryChainHOF(
733
+ relPKeys,
674
734
  reverseJoin2,
675
735
  (joiningQuery, baseQuery) => joinHasThrough(
676
736
  joiningQuery,
@@ -728,7 +788,8 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
728
788
  relationName,
729
789
  state
730
790
  ),
731
- joinQuery: joinQueryChainingHOF(
791
+ joinQuery: joinQueryChainHOF(
792
+ relPKeys,
732
793
  reverseJoin,
733
794
  (joiningQuery, baseQuery) => joinHasRelation(
734
795
  baseQuery,
@@ -911,6 +972,7 @@ class HasManyVirtualColumn extends VirtualColumn {
911
972
  }
912
973
  }
913
974
  const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
975
+ const relPKeys = getPrimaryKeys(query);
914
976
  if ("through" in relation.options) {
915
977
  const { through, source } = relation.options;
916
978
  const throughRelation = getThroughRelation(table, through);
@@ -941,7 +1003,8 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
941
1003
  whereExistsCallback
942
1004
  );
943
1005
  },
944
- joinQuery: joinQueryChainingHOF(
1006
+ joinQuery: joinQueryChainHOF(
1007
+ relPKeys,
945
1008
  reverseJoin2,
946
1009
  (joiningQuery, baseQuery) => joinHasThrough(
947
1010
  joiningQuery,
@@ -999,7 +1062,8 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
999
1062
  relationName,
1000
1063
  state
1001
1064
  ),
1002
- joinQuery: joinQueryChainingHOF(
1065
+ joinQuery: joinQueryChainHOF(
1066
+ relPKeys,
1003
1067
  reverseJoin,
1004
1068
  (joiningQuery, baseQuery) => joinHasRelation(
1005
1069
  baseQuery,
@@ -1388,7 +1452,8 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
1388
1452
  relationName,
1389
1453
  state
1390
1454
  ),
1391
- joinQuery: joinQueryChainingHOF(
1455
+ joinQuery: joinQueryChainHOF(
1456
+ getPrimaryKeys(query),
1392
1457
  reverseJoin,
1393
1458
  (joiningQuery, baseQuery2) => joinQuery(
1394
1459
  joiningQuery,