uql-orm 0.26.1 → 0.26.2

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.
@@ -1,6 +1,6 @@
1
1
  import { decodeColumn } from '../dialect/hydrateColumn.js';
2
2
  import { getMeta } from '../entity/index.js';
3
- import { buildUpdateResult, clone, getInsertFieldKeys, getRelationRequestSummary, isAutoIncrement, obtainAttrsPaths, throwNoPendingTransaction, throwPendingTransaction, unflatObject, unflatObjects, withoutSoftDeleteFilter, } from '../util/index.js';
3
+ import { buildUpdateResult, cascadesOnDelete, clone, getInsertFieldKeys, getRelationRequestSummary, isAutoIncrement, obtainAttrsPaths, throwNoPendingTransaction, throwPendingTransaction, unflatObject, unflatObjects, withoutSoftDeleteFilter, } from '../util/index.js';
4
4
  import { AbstractQuerier } from './abstractQuerier.js';
5
5
  import { enrichError } from './queryError.js';
6
6
  export class AbstractSqlQuerier extends AbstractQuerier {
@@ -222,6 +222,17 @@ export class AbstractSqlQuerier extends AbstractQuerier {
222
222
  }
223
223
  async internalDeleteMany(entity, q, opts) {
224
224
  const meta = getMeta(entity);
225
+ // Resolving the ids first is what makes the two hard cases work at all: a cascade needs its
226
+ // parents' ids to find their children, and no engine but MySQL accepts `ORDER BY`/`LIMIT` on a
227
+ // DELETE, so a paged delete has to name the rows it settled on. A plain predicate needs neither,
228
+ // and there the round trip buys nothing: the statement can say what the caller already said.
229
+ const hasPagination = q.$sort !== undefined || q.$limit !== undefined || q.$skip !== undefined;
230
+ if (!hasPagination && !cascadesOnDelete(meta)) {
231
+ const ctx = this.dialect.createContext();
232
+ this.dialect.delete(ctx, entity, q, opts);
233
+ const { changes = 0 } = await this.run(ctx.sql, ctx.values);
234
+ return changes;
235
+ }
225
236
  // A hard delete also targets already-soft-deleted rows, so drop the soft-delete filter when finding ids.
226
237
  const findOpts = opts?.hardDelete ? { ...opts, filters: withoutSoftDeleteFilter(opts.filters) } : opts;
227
238
  const findCtx = this.dialect.createContext();
@@ -35,6 +35,11 @@ export declare function fillOnFields<E>(meta: EntityMeta<E>, payload: E | E[], c
35
35
  * or `meta.relations` itself to enumerate every cascadable relation).
36
36
  */
37
37
  export declare function filterPersistableRelationKeys<E>(meta: EntityMeta<E>, payload: object, action: CascadeType): RelationKey<E>[];
38
+ /**
39
+ * Whether deleting this entity has to delete anything else, which is the reason a delete resolves the
40
+ * matching ids before issuing anything: a child is reached through the ids of its parent.
41
+ */
42
+ export declare function cascadesOnDelete<E>(meta: EntityMeta<E>): boolean;
38
43
  export declare function isCascadable(action: CascadeType, configuration?: boolean | CascadeType): boolean;
39
44
  /**
40
45
  * The map form of a `$select` value, or `undefined` for the raw-array form. Centralizes the one
@@ -83,6 +83,13 @@ export function filterPersistableRelationKeys(meta, payload, action) {
83
83
  return relOpts && isCascadable(action, relOpts.cascade);
84
84
  });
85
85
  }
86
+ /**
87
+ * Whether deleting this entity has to delete anything else, which is the reason a delete resolves the
88
+ * matching ids before issuing anything: a child is reached through the ids of its parent.
89
+ */
90
+ export function cascadesOnDelete(meta) {
91
+ return filterPersistableRelationKeys(meta, meta.relations, 'delete').length > 0;
92
+ }
86
93
  export function isCascadable(action, configuration) {
87
94
  if (typeof configuration === 'boolean') {
88
95
  return configuration;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "homepage": "https://uql-orm.dev",
4
4
  "description": "Extremely fast, type-safe TypeScript ORM - one API for every database",
5
5
  "license": "MIT",
6
- "version": "0.26.1",
6
+ "version": "0.26.2",
7
7
  "type": "module",
8
8
  "engines": {
9
9
  "node": ">=24"