@spinajs/orm 2.0.491 → 2.0.495

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.
Files changed (86) hide show
  1. package/README.md +80 -80
  2. package/lib/cjs/builders.d.ts +1 -2
  3. package/lib/cjs/builders.d.ts.map +1 -1
  4. package/lib/cjs/builders.js +2 -0
  5. package/lib/cjs/builders.js.map +1 -1
  6. package/lib/cjs/decorators.d.ts +22 -0
  7. package/lib/cjs/decorators.d.ts.map +1 -1
  8. package/lib/cjs/decorators.js +29 -0
  9. package/lib/cjs/decorators.js.map +1 -1
  10. package/lib/cjs/descriptor.d.ts.map +1 -1
  11. package/lib/cjs/descriptor.js +2 -0
  12. package/lib/cjs/descriptor.js.map +1 -1
  13. package/lib/cjs/driver.d.ts +12 -0
  14. package/lib/cjs/driver.d.ts.map +1 -1
  15. package/lib/cjs/driver.js +12 -0
  16. package/lib/cjs/driver.js.map +1 -1
  17. package/lib/cjs/interfaces.d.ts +35 -24
  18. package/lib/cjs/interfaces.d.ts.map +1 -1
  19. package/lib/cjs/interfaces.js.map +1 -1
  20. package/lib/cjs/model.d.ts +26 -5
  21. package/lib/cjs/model.d.ts.map +1 -1
  22. package/lib/cjs/model.js +32 -9
  23. package/lib/cjs/model.js.map +1 -1
  24. package/lib/cjs/orm.d.ts.map +1 -1
  25. package/lib/cjs/orm.js +4 -1
  26. package/lib/cjs/orm.js.map +1 -1
  27. package/lib/cjs/relation-objects.d.ts +76 -163
  28. package/lib/cjs/relation-objects.d.ts.map +1 -1
  29. package/lib/cjs/relation-objects.js +223 -192
  30. package/lib/cjs/relation-objects.js.map +1 -1
  31. package/lib/cjs/schema-providers.d.ts +34 -0
  32. package/lib/cjs/schema-providers.d.ts.map +1 -1
  33. package/lib/cjs/schema-providers.js +59 -3
  34. package/lib/cjs/schema-providers.js.map +1 -1
  35. package/lib/cjs/schema.d.ts +20 -3
  36. package/lib/cjs/schema.d.ts.map +1 -1
  37. package/lib/cjs/schema.js +59 -9
  38. package/lib/cjs/schema.js.map +1 -1
  39. package/lib/cjs/snapshot.d.ts +1 -1
  40. package/lib/cjs/snapshot.d.ts.map +1 -1
  41. package/lib/cjs/snapshot.js +9 -2
  42. package/lib/cjs/snapshot.js.map +1 -1
  43. package/lib/mjs/builders.d.ts +1 -2
  44. package/lib/mjs/builders.d.ts.map +1 -1
  45. package/lib/mjs/builders.js +2 -0
  46. package/lib/mjs/builders.js.map +1 -1
  47. package/lib/mjs/decorators.d.ts +22 -0
  48. package/lib/mjs/decorators.d.ts.map +1 -1
  49. package/lib/mjs/decorators.js +28 -0
  50. package/lib/mjs/decorators.js.map +1 -1
  51. package/lib/mjs/descriptor.d.ts.map +1 -1
  52. package/lib/mjs/descriptor.js +2 -0
  53. package/lib/mjs/descriptor.js.map +1 -1
  54. package/lib/mjs/driver.d.ts +12 -0
  55. package/lib/mjs/driver.d.ts.map +1 -1
  56. package/lib/mjs/driver.js +12 -0
  57. package/lib/mjs/driver.js.map +1 -1
  58. package/lib/mjs/interfaces.d.ts +35 -24
  59. package/lib/mjs/interfaces.d.ts.map +1 -1
  60. package/lib/mjs/interfaces.js.map +1 -1
  61. package/lib/mjs/model.d.ts +26 -5
  62. package/lib/mjs/model.d.ts.map +1 -1
  63. package/lib/mjs/model.js +32 -9
  64. package/lib/mjs/model.js.map +1 -1
  65. package/lib/mjs/orm.d.ts.map +1 -1
  66. package/lib/mjs/orm.js +4 -1
  67. package/lib/mjs/orm.js.map +1 -1
  68. package/lib/mjs/relation-objects.d.ts +76 -163
  69. package/lib/mjs/relation-objects.d.ts.map +1 -1
  70. package/lib/mjs/relation-objects.js +225 -194
  71. package/lib/mjs/relation-objects.js.map +1 -1
  72. package/lib/mjs/schema-providers.d.ts +34 -0
  73. package/lib/mjs/schema-providers.d.ts.map +1 -1
  74. package/lib/mjs/schema-providers.js +59 -3
  75. package/lib/mjs/schema-providers.js.map +1 -1
  76. package/lib/mjs/schema.d.ts +20 -3
  77. package/lib/mjs/schema.d.ts.map +1 -1
  78. package/lib/mjs/schema.js +59 -9
  79. package/lib/mjs/schema.js.map +1 -1
  80. package/lib/mjs/snapshot.d.ts +1 -1
  81. package/lib/mjs/snapshot.d.ts.map +1 -1
  82. package/lib/mjs/snapshot.js +9 -2
  83. package/lib/mjs/snapshot.js.map +1 -1
  84. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  85. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  86. package/package.json +75 -73
@@ -1 +1 @@
1
- {"version":3,"file":"relation-objects.d.ts","sourceRoot":"","sources":["../../src/relation-objects.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relation-objects.d.ts","sourceRoot":"","sources":["../../src/relation-objects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAmB,kBAAkB,EAAE,SAAS,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACzJ,OAAO,EAAM,WAAW,EAAe,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAe,kBAAkB,EAAsB,MAAM,eAAe,CAAC;AACpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA2CxC;;;GAGG;AACH,qBAAa,OAAO;IAClB;;;;;;OAMG;WACW,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,IAC5D,UAAU,CAAC,EAAE,EAAE,MAAM,MAAM,EAAE;IAcvC;;;;;;OAMG;WACW,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,IACpE,UAAU,CAAC,EAAE,EAAE,MAAM,MAAM,EAAE;IAOvC;;;;;;;;OAQG;WACW,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,IAC7D,UAAU,CAAC,EAAE,EAAE,MAAM,MAAM,EAAE;CAcxC;AAED;;;;GAIG;AACH,8BACsB,QAAQ,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,CAAC,CAAE,YAAW,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IAuBjK,SAAS,CAAC,KAAK,EAAE,CAAC;IAAE,SAAS,CAAC,QAAQ,EAAE,mBAAmB;IAtBhE,qBAAqB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAE/C,SAAS,EAAE,OAAO,CAAS;IAElC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAE5B,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC;IAErD;;;;;;;;;OASG;IACH,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,qBAE1B;gBAEqB,KAAK,EAAE,CAAC,EAAY,QAAQ,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE;IAetF;;;;;;;;;;OAUG;IACH,SAAS,KAAK,cAAc,IAAI,GAAG,CAGlC;IAED;;;;;OAKG;IACI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IAE9C;;;;;OAKG;IACI,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE;IAiBhC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC;;OAEG;IACI,KAAK;IAIZ;;;;;;OAMG;aACa,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErC;;;;OAIG;aACa,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAEvC;;;;;;;OAOG;IACI,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IAI1E;;;;;;;OAOG;IACI,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI;IAIpE;;;;;;;OAOG;IACI,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IAIlE;;;;;;OAMG;IACI,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAMjE;;OAEG;aACa,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CACjH;AAED,qBACa,cAAc,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,GAAG,SAAS;IASlE,SAAS,CAAC,MAAM,EAAE,CAAC;IAAE,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,kBAAkB,GAAG,IAAI;IAAE,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IARrI,qBAAqB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAEtD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEZ,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAE5B,SAAS,EAAE,OAAO,CAAS;gBAEZ,MAAM,EAAE,CAAC,EAAY,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,kBAAkB,GAAG,IAAI,EAAY,QAAQ,EAAE,mBAAmB,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;IAOxJ;;;OAGG;IACU,GAAG,CAAC,GAAG,EAAE,CAAC;IAOvB;;;;;;;;OAQG;IACI,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;IAcpB,MAAM;IAIb;;;;OAIG;IACU,MAAM;IASnB;;;;;;;;;;;OAWG;IACU,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAoB1F;AAED,qBAAa,qBAAqB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IACxC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE;IAI1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAGrB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAGvB,YAAY,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IAGrE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI;IAG/D,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE;IAG7D,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAG3D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAGrF,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE;CAInE;AAED,qBAAa,mBAAmB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,SAAQ,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrG,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;CAIhC;AAED,qBACa,sBAAsB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IAEvH,SAAS,CAAC,uBAAuB,EAAE,gBAAgB,GAAG,IAAI,CAAC;gBAE/C,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE;IASlE;;;;;MAKE;cACc,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE;IAwBjC;;;;;;;QAOI;IACS,IAAI;IAOjB;;;;OAIG;IACU,MAAM;IAMnB;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,kBAAkB,GAAG,mBAAmB;IAWtG;;;;;;;OAOG;cACa,OAAO;IA4BV,QAAQ,CAAC,CAAC,SAAS,OAAO,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,IAAI;CAsB1H;AAED,qBACa,qBAAqB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACtH;;;;;OAKG;cACa,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE;IAyCjC;;;;;;;OAOG;IACU,QAAQ,CAAC,CAAC,SAAS,OAAO,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBzI;;;;;;;;;;;OAWG;IACU,IAAI;IAOjB;;;;OAIG;IACU,MAAM;IAMnB,qFAAqF;cACrE,OAAO;CAkBxB"}
@@ -9,60 +9,104 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  /* eslint-disable prettier/prettier */
11
11
  import { InsertBehaviour } from './interfaces.js';
12
- import { DI, isConstructor, NewInstance } from '@spinajs/di';
13
- import { createQuery, SelectQueryBuilder } from './builders.js';
12
+ import { DI, NewInstance } from '@spinajs/di';
13
+ import { DateTime } from 'luxon';
14
+ import { createQuery, SelectQueryBuilder, UpdateQueryBuilder } from './builders.js';
14
15
  import { Orm } from './orm.js';
15
16
  import _ from 'lodash';
16
17
  import { extractModelDescriptor } from './descriptor.js';
17
18
  import { isCompositePk, pkColumns, pkKeyStringFor, pkValueOf, whereNotAnyPk } from './primary-keys.js';
18
19
  import { OrmException } from './exceptions.js';
19
20
  /**
20
- * Builds a lodash iteratee for the given primary key columns. A single column stays a plain
21
- * property name ( lodash's fast path ); a composite key becomes a function that flattens the
22
- * tuple, because an array iteratee would be read as a property PATH `_.differenceBy(a, b,
23
- * ['TenantId','Code'])` resolves `obj['TenantId']['Code']`, undefined for every row, so every
24
- * row would compare equal.
21
+ * Builds the equality used by every keyed set operation.
22
+ *
23
+ * Same reference is always equal. Two DIFFERENT rows are equal only when every key column is
24
+ * set on both and the flattened key strings match — a fresh, unsaved model ( undefined key )
25
+ * never equals another row, so two new models are two members, not one. The previous
26
+ * `differenceBy` iteratee stringified undefined keys and collapsed all unsaved rows into one.
25
27
  */
26
- function pkIteratee(pKey) {
27
- if (pKey.length === 1) {
28
- return pKey[0];
28
+ function pkComparator(pKey) {
29
+ return (a, b) => {
30
+ if (a === b) {
31
+ return true;
32
+ }
33
+ if (pKey.length === 0) {
34
+ return false;
35
+ }
36
+ const isSet = (x) => pKey.every((k) => x?.[k] !== null && x?.[k] !== undefined);
37
+ if (!isSet(a) || !isSet(b)) {
38
+ return false;
39
+ }
40
+ return pkKeyStringFor(a, pKey) === pkKeyStringFor(b, pKey);
41
+ };
42
+ }
43
+ /**
44
+ * A set operation with no comparator falls back to primary key equality, which needs key
45
+ * columns to exist. Comparing keyless rows silently matches nothing ( or everything ), so
46
+ * fail loudly instead.
47
+ */
48
+ function assertSetOpKeys(pKey, callback) {
49
+ if (!callback && pKey.length === 0) {
50
+ throw new OrmException('set operation compares by primary key, but the model declares no primary key columns; pass an explicit comparator callback');
29
51
  }
30
- return (x) => pkKeyStringFor(x, pKey);
31
52
  }
53
+ /**
54
+ * Pure, in-memory set algebra over model collections. Nothing here touches the database —
55
+ * apply a result with `relation.set(...)` and persist it with `sync()` / `update()` / `save()`.
56
+ */
32
57
  export class Dataset {
33
58
  /**
34
- *
35
- * Calculates difference between data in this relation and provides set. Result is saved to db.
59
+ * Calculates the symmetric difference between the relation data and the provided dataset —
60
+ * members of either set that are not in the other. In-memory only; persist with `sync()`.
36
61
  *
37
62
  * @param dataset - data to compare
38
- * @param callback - function to compare objects, if none provideded - primary key value is used
63
+ * @param callback - function to compare objects, if none provided - primary key value is used
39
64
  */
40
65
  static diff(dataset, callback) {
41
66
  return (datasetB, pKey) => {
42
- // TODO: maybe refactor for speedup, this is not optimal
43
- // two calls to _.difference is not optimal, but it is easy to implement
44
- const iteratee = pkIteratee(pKey);
45
- // calculate difference between this data in relation and dataset ( objects from this relation)
46
- const result = callback ? _.differenceWith(dataset, [...datasetB], callback) : _.differenceBy(dataset, [...datasetB], iteratee);
47
- // calculate difference between dataset and data in this relation ( objects from dataset )
48
- const result2 = callback ? _.differenceWith([...datasetB], dataset, callback) : _.differenceBy([...datasetB], dataset, iteratee);
49
- // combine difference from two sets
50
- const finalDiff = [...result, ...result2];
51
- return finalDiff;
67
+ assertSetOpKeys(pKey, callback);
68
+ const eq = callback ?? pkComparator(pKey);
69
+ // members of dataset that are not in the relation data
70
+ const result = _.differenceWith(dataset, [...datasetB], eq);
71
+ // members of the relation data that are not in dataset
72
+ const result2 = _.differenceWith([...datasetB], dataset, eq);
73
+ return [...result, ...result2];
52
74
  };
53
75
  }
54
76
  /**
55
- *
56
- * Calculates intersection between data in this relation and provided dataset
57
- * It saves result to db
77
+ * Calculates the intersection between the relation data and the provided dataset.
78
+ * In-memory only; persist with `sync()`.
58
79
  *
59
80
  * @param dataset - dataset to compare
60
81
  * @param callback - function to compare models, if not set it is compared by primary key value
61
82
  */
62
83
  static intersection(dataset, callback) {
63
84
  return (datasetB, pKey) => {
64
- const iteratee = pkIteratee(pKey);
65
- return callback ? _.intersectionWith(dataset, [...datasetB], callback) : _.intersectionBy(dataset, [...datasetB], iteratee);
85
+ assertSetOpKeys(pKey, callback);
86
+ const eq = callback ?? pkComparator(pKey);
87
+ return _.intersectionWith(dataset, [...datasetB], eq);
88
+ };
89
+ }
90
+ /**
91
+ * Calculates the union of the relation data and the provided dataset. Members already
92
+ * present ( by primary key or comparator ) are kept once, the relation's own instance
93
+ * winning over the incoming duplicate. Unsaved models compare by reference, so they are
94
+ * always appended. In-memory only; persist with `sync()`.
95
+ *
96
+ * @param dataset - data to add
97
+ * @param callback - function to compare models, if not set it is compared by primary key value
98
+ */
99
+ static union(dataset, callback) {
100
+ return (datasetB, pKey) => {
101
+ assertSetOpKeys(pKey, callback);
102
+ const eq = callback ?? pkComparator(pKey);
103
+ const result = [...datasetB];
104
+ for (const item of dataset) {
105
+ if (!result.some((existing) => eq(existing, item))) {
106
+ result.push(item);
107
+ }
108
+ }
109
+ return result;
66
110
  };
67
111
  }
68
112
  }
@@ -73,15 +117,14 @@ export class Dataset {
73
117
  */
74
118
  let Relation = class Relation extends Array {
75
119
  /**
76
- * Array methods that derive a new collection ( `splice`, `filter`, `slice`, `concat`, … )
77
- * construct `new this.constructor[Symbol.species](len)` by default. That would call this
78
- * class's constructor with no relation descriptor, and the very next line dereferences
79
- * `this.Relation.TargetModel` — so `order.Items.splice(0, 1)` threw
120
+ * Array methods that derive a new collection ( `splice`, `filter`, `slice`, `concat`,
121
+ * `map`, … ) construct `new this.constructor[Symbol.species](len)` by default. That would
122
+ * call this class's constructor with no relation descriptor, and the very next line
123
+ * dereferences `this.Relation.TargetModel` — so `order.Items.splice(0, 1)` threw
80
124
  * `Cannot read properties of undefined (reading 'TargetModel')`.
81
125
  *
82
126
  * Deriving plain arrays is also the right semantics: a slice of a relation is a list of
83
- * models, not a relation with an owner. ( The hand-written `map()` below predates this and
84
- * worked around the same thing for one method. )
127
+ * models, not a relation with an owner.
85
128
  */
86
129
  static get [Symbol.species]() {
87
130
  return Array;
@@ -99,7 +142,6 @@ let Relation = class Relation extends Array {
99
142
  if (this.TargetModelDescriptor) {
100
143
  this.Driver = DI.resolve('OrmConnection', [this.TargetModelDescriptor.Connection]);
101
144
  }
102
- this.IsModelAForwardRef = !isConstructor(this.Model);
103
145
  }
104
146
  /**
105
147
  * The owner-side value this relation joins on.
@@ -116,13 +158,18 @@ let Relation = class Relation extends Array {
116
158
  const key = this.Relation?.PrimaryKey;
117
159
  return key ? this.Owner[key] : this.Owner.PrimaryKeyValue;
118
160
  }
119
- map(callbackfn, thisArg) {
120
- const result = [];
121
- for (let index = 0; index < this.length; index++) {
122
- const element = this[index];
123
- result.push(callbackfn.call(thisArg, element, index, this));
161
+ remove(obj) {
162
+ let toRemove;
163
+ if (_.isFunction(obj)) {
164
+ toRemove = [...this].filter(obj);
165
+ }
166
+ else {
167
+ const candidates = Array.isArray(obj) ? obj : [obj];
168
+ const eq = pkComparator(pkColumns(this.TargetModelDescriptor));
169
+ toRemove = [...this].filter((member) => candidates.some((c) => eq(member, c)));
124
170
  }
125
- return result;
171
+ this.set((data) => data.filter((d) => !toRemove.includes(d)));
172
+ return toRemove;
126
173
  }
127
174
  /**
128
175
  * Delete all objects from relation ( alias for empty )
@@ -136,6 +183,51 @@ let Relation = class Relation extends Array {
136
183
  empty() {
137
184
  this.length = 0;
138
185
  }
186
+ /**
187
+ * Calculates the intersection between this relation and the provided dataset. Pure
188
+ * computation — apply it with `set()` and persist with `sync()` / `save()`.
189
+ *
190
+ * @param dataset - dataset to compare
191
+ * @param callback - function to compare models, if not set it is compared by primary key value
192
+ * @returns members present in both sets
193
+ */
194
+ intersection(dataset, callback) {
195
+ return Dataset.intersection(dataset, callback)([...this], pkColumns(this.TargetModelDescriptor));
196
+ }
197
+ /**
198
+ * Adds the dataset's members to this relation, skipping members already present ( compared
199
+ * by primary key, or by the callback ). In-memory only — nothing is written until `sync()`,
200
+ * `update()` or `save()`.
201
+ *
202
+ * @param dataset - data to add
203
+ * @param callback - function to compare models, if not set it is compared by primary key value
204
+ */
205
+ union(dataset, callback) {
206
+ this.set(Dataset.union(dataset, callback)([...this], pkColumns(this.TargetModelDescriptor)));
207
+ }
208
+ /**
209
+ * Calculates the symmetric difference between this relation and the dataset — members of
210
+ * this relation that are not in the dataset, plus members of the dataset that are not in
211
+ * this relation. Pure computation — apply it with `set()` and persist with `sync()`.
212
+ *
213
+ * @param dataset - data to compare
214
+ * @param callback - function to compare objects, if none provided - primary key value is used
215
+ */
216
+ diff(dataset, callback) {
217
+ return Dataset.diff(dataset, callback)([...this], pkColumns(this.TargetModelDescriptor));
218
+ }
219
+ /**
220
+ * Clears the relation and replaces its members with the new dataset ( or with the result of
221
+ * a `Dataset.diff` / `Dataset.intersection` / `Dataset.union` closure ). In-memory only —
222
+ * persist with `sync()` / `update()` / `save()`.
223
+ *
224
+ * @param obj - replacement data, or a closure receiving the current members and the primary key columns
225
+ */
226
+ set(obj) {
227
+ const toPush = _.isFunction(obj) ? obj([...this], pkColumns(this.TargetModelDescriptor)) : obj;
228
+ this.empty();
229
+ this.push(...toPush);
230
+ }
139
231
  };
140
232
  Relation = __decorate([
141
233
  NewInstance(),
@@ -236,30 +328,29 @@ SingleRelation = __decorate([
236
328
  ], SingleRelation);
237
329
  export { SingleRelation };
238
330
  export class ManyQueryRelationList extends Relation {
239
- /* eslint-disable prettier/prettier */
240
331
  remove(_obj) {
241
- throw new Error('Query relations cannot be removed. This relation is used only for query purposes and it is always populated.');
332
+ throw new OrmException('Query relations cannot be removed. This relation is used only for query purposes and it is always populated.');
242
333
  }
243
334
  sync() {
244
- throw new Error('Query relations cannot be synced. This relation is used only for query purposes and it is always populated.');
335
+ throw new OrmException('Query relations cannot be synced. This relation is used only for query purposes and it is always populated.');
245
336
  }
246
337
  update() {
247
- throw new Error('Query relations cannot be updated. This relation is used only for query purposes and it is always populated.');
338
+ throw new OrmException('Query relations cannot be updated. This relation is used only for query purposes and it is always populated.');
248
339
  }
249
340
  intersection(_dataset, _callback) {
250
- throw new Error('Query relations cannot be intersected. This relation is used only for query purposes and it is always populated.');
341
+ throw new OrmException('Query relations cannot be intersected. This relation is used only for query purposes and it is always populated.');
251
342
  }
252
- union(_dataset, _mode) {
253
- throw new Error('Query relations cannot be unioned. This relation is used only for query purposes and it is always populated.');
343
+ union(_dataset, _callback) {
344
+ throw new OrmException('Query relations cannot be unioned. This relation is used only for query purposes and it is always populated.');
254
345
  }
255
346
  diff(_dataset, _callback) {
256
- throw new Error('Query relations cannot be diffed. This relation is used only for query purposes and it is always populated.');
347
+ throw new OrmException('Query relations cannot be diffed. This relation is used only for query purposes and it is always populated.');
257
348
  }
258
349
  set(_obj) {
259
- throw new Error('Query relations cannot be set. This relation is used only for query purposes and it is always populated.');
350
+ throw new OrmException('Query relations cannot be set. This relation is used only for query purposes and it is always populated.');
260
351
  }
261
352
  populate(_callback) {
262
- throw new Error('Query relations cannot be populated. This relation is used only for query purposes and it is always populated.');
353
+ throw new OrmException('Query relations cannot be populated. This relation is used only for query purposes and it is always populated.');
263
354
  }
264
355
  constructor(owner, relation, objects) {
265
356
  super(owner, relation, objects);
@@ -279,58 +370,6 @@ let ManyToManyRelationList = class ManyToManyRelationList extends Relation {
279
370
  this.junctionModelDescriptor = extractModelDescriptor(this.Relation.JunctionModel);
280
371
  }
281
372
  }
282
- /**
283
- * Calculates intersection between data in this relation and provided dataset
284
- *
285
- * `[...this]` rather than `this`: these delegate into lodash, and `Relation extends Array`
286
- * with a three-argument constructor, so anything that derives a new collection has to work
287
- * on a plain array. ( `OneToManyRelationList` sidesteps the same problem by overriding
288
- * `filter`/`map`; this class has no such overrides. )
289
- *
290
- * @param obj - dataset to compare with
291
- * @param callback - compare function, if not set the target model's primary key is used
292
- * @returns members present in both sets
293
- */
294
- intersection(obj, callback) {
295
- return Dataset.intersection(obj, callback)([...this], this.TargetModelDescriptor.PrimaryKey);
296
- }
297
- /**
298
- * Appends `obj` to this relation. Shorthand for push — nothing is removed and nothing is
299
- * written to the database until `sync()`, `update()` or `save()` runs.
300
- *
301
- * @param obj - members to add
302
- */
303
- union(obj, _mode) {
304
- this.push(...obj);
305
- }
306
- /**
307
- * Calculates the symmetric difference between this relation and `dataset` — members of this
308
- * relation that are not in the dataset, plus members of the dataset that are not in this
309
- * relation.
310
- *
311
- * @param obj - dataset to compare with
312
- * @param callback - compare function, if not set the target model's primary key is used
313
- */
314
- diff(obj, callback) {
315
- return Dataset.diff(obj, callback)([...this], this.TargetModelDescriptor.PrimaryKey);
316
- }
317
- /**
318
- * Sets data in relation ( clear data and replace with new dataset )
319
- *
320
- * @param obj
321
- */
322
- set(obj) {
323
- const toPush = _.isFunction(obj) ? obj([...this], pkColumns(this.TargetModelDescriptor)) : obj;
324
- this.empty();
325
- this.push(...toPush);
326
- }
327
- remove(obj) {
328
- const toRemove = _.isFunction(obj) ? this.filter(obj) : Array.isArray(obj) ? obj : [obj];
329
- this.set((data) => {
330
- return data.filter((d) => !toRemove.includes(d));
331
- });
332
- return toRemove;
333
- }
334
373
  /**
335
374
  * Deletes from db data that are not in relation
336
375
  *
@@ -347,8 +386,10 @@ let ManyToManyRelationList = class ManyToManyRelationList extends Relation {
347
386
  if (this.Driver.Options.Database) {
348
387
  query.database(this.Driver.Options.Database);
349
388
  }
350
- // if we have data in relation, we need to exclude them from delete query
351
- const toDelete = [...data].filter((x) => x.PrimaryKeyValue).map((x) => x.PrimaryKeyValue);
389
+ // if we have data in relation, we need to exclude them from delete query.
390
+ // Explicit null/undefined checks a primary key of 0 or '' is a real key, and dropping
391
+ // it from the keep-list would delete that member's junction row.
392
+ const toDelete = [...data].map((x) => x.PrimaryKeyValue).filter((v) => v !== null && v !== undefined);
352
393
  if (toDelete.length !== 0) {
353
394
  query.whereNotIn(this.Relation.JunctionModelTargetModelFKey_Name, toDelete);
354
395
  }
@@ -359,8 +400,6 @@ let ManyToManyRelationList = class ManyToManyRelationList extends Relation {
359
400
  * Deletes from db entries that are not in relation and adds entries that are not in db
360
401
  * Sets foreign key to relational data
361
402
  *
362
- * Inserts or updates models that are dirty only.
363
- *
364
403
  * One transaction: the junction upserts and the orphan delete used to be independent
365
404
  * statements. Nested inside a caller's transaction this takes a savepoint.
366
405
  */
@@ -371,42 +410,69 @@ let ManyToManyRelationList = class ManyToManyRelationList extends Relation {
371
410
  });
372
411
  }
373
412
  /**
374
- * Updates or ads data to relation
375
- * It will not delete data from db that are not in relation. It will only update or insert new data.
376
- * Only dirty models are updated.
413
+ * Adds missing rows to the database without deleting anything: unsaved members are
414
+ * inserted, members without a junction row get one. Existing junction rows are left
415
+ * untouched.
377
416
  */
378
417
  async update() {
379
418
  await this.Driver.transaction(async () => {
380
419
  await this._update();
381
420
  });
382
421
  }
383
- /** The write itself, without a transaction of its own, so `sync()` can share one. */
422
+ /**
423
+ * Finds the junction model's relation pointing at `model`, by constructor identity — the
424
+ * junction's PROPERTY name is the author's choice ( `Order`, `Tag`, … ) and has nothing to
425
+ * do with the target class name.
426
+ */
427
+ junctionRelationFor(model) {
428
+ const relations = Array.from(this.junctionModelDescriptor?.Relations.values() ?? []);
429
+ const found = relations.find((r) => r.TargetModel === model);
430
+ if (!found) {
431
+ throw new OrmException(`junction model ${this.junctionModelDescriptor?.Name} of relation ${this.Relation.Name} declares no relation targeting ${model?.name}; add a @BelongsTo for it`);
432
+ }
433
+ return found;
434
+ }
435
+ /**
436
+ * The write itself, without a transaction of its own, so `sync()` can share one.
437
+ *
438
+ * Unsaved members are inserted first — a junction row written for a model with no primary
439
+ * key would carry a NULL foreign key. Members that already have a junction row are skipped:
440
+ * the junction's own primary key is auto-generated, so re-inserting the pair would DUPLICATE
441
+ * the link rather than upsert it ( which is exactly what repeated `sync()` calls used to do ).
442
+ */
384
443
  async _update() {
444
+ const sourceModelRelation = this.junctionRelationFor(this.Owner.constructor);
445
+ const existingQuery = this.Driver.select().from(this.junctionModelDescriptor.TableName).where(this.Relation.JunctionModelSourceModelFKey_Name, this.OwnerJoinValue);
446
+ if (this.Driver.Options.Database) {
447
+ existingQuery.database(this.Driver.Options.Database);
448
+ }
449
+ const existingRows = (await existingQuery.asRaw()) ?? [];
450
+ const linked = new Set(existingRows.map((r) => r[this.Relation.JunctionModelTargetModelFKey_Name]).filter((v) => v !== null && v !== undefined));
385
451
  for (const f of this) {
386
- const junctionEntry = new this.Relation.JunctionModel();
387
- const desc = junctionEntry.ModelDescriptor;
388
- const relationsArray = Array.from(desc.Relations.values());
389
- const sourceModelRelation = relationsArray.find((r) => r.TargetModel === this.Owner.constructor);
390
- const targetModelRelation = relationsArray.find((r) => r.TargetModel === f.constructor);
391
- if (!sourceModelRelation) {
392
- throw new Error(`Junction model relation for source model ${this.Owner.constructor.name} not found.`);
452
+ if (f.PrimaryKeyValue === null || f.PrimaryKeyValue === undefined) {
453
+ await f.insert(InsertBehaviour.InsertOrUpdate);
393
454
  }
394
- if (!targetModelRelation) {
395
- throw new Error(`Junction model relation for target model ${f.constructor.name} not found.`);
455
+ if (linked.has(f.PrimaryKeyValue)) {
456
+ continue;
396
457
  }
458
+ const targetModelRelation = this.junctionRelationFor(f.constructor);
459
+ const junctionEntry = new this.Relation.JunctionModel();
397
460
  junctionEntry[sourceModelRelation.Name].Value = this.Owner;
398
461
  junctionEntry[targetModelRelation.Name].Value = f;
399
462
  await junctionEntry.insert(InsertBehaviour.InsertOrUpdate);
400
463
  }
401
464
  }
402
465
  async populate(callback) {
466
+ // Resolved by constructor, not by `TargetModel.name` — the junction's property name is
467
+ // unrelated to the target class name, and class names do not survive minification.
468
+ const targetModelRelation = this.junctionRelationFor(this.Relation.TargetModel);
403
469
  const query = this.Relation.JunctionModel.where(this.Relation.JunctionModelSourceModelFKey_Name, this.OwnerJoinValue).populate(this.Relation.TargetModel, callback);
404
470
  const result = await query;
405
471
  if (result) {
406
472
  this.length = 0;
407
- this.push(...result.map((r) => {
408
- return r[this.Relation.TargetModel.name].Value;
409
- }));
473
+ // A junction row whose target row no longer exists resolves to a null Value — skip it
474
+ // rather than push null into the member list.
475
+ this.push(...result.map((r) => r[targetModelRelation.Name].Value).filter((v) => v !== null && v !== undefined));
410
476
  }
411
477
  this.Populated = true;
412
478
  this.Owner.snapshotRelation(this.Relation.Name);
@@ -425,24 +491,45 @@ let OneToManyRelationList = class OneToManyRelationList extends Relation {
425
491
  * @returns
426
492
  */
427
493
  async _dbDiff(data) {
428
- const query = this.Driver.del().from(this.TargetModelDescriptor.TableName).where(this.Relation.ForeignKey, this.OwnerJoinValue);
429
- if (this.Driver.Options.Database) {
430
- query.database(this.Driver.Options.Database);
431
- }
432
- // if we have data in relation, we need to exclude them from delete query.
433
494
  // A composite key is a tuple and always truthy, so filter on the key COLUMNS being set
434
495
  // rather than on the tuple itself.
435
496
  const keys = pkColumns(this.TargetModelDescriptor);
436
- const toDelete = data
497
+ const toKeep = data
437
498
  .map((x) => pkValueOf(x, this.TargetModelDescriptor))
438
499
  .filter((v) => (Array.isArray(v) ? v.every((p) => p !== null && p !== undefined) : v !== null && v !== undefined));
439
- if (toDelete.length !== 0 && keys.length !== 0) {
440
- whereNotAnyPk(query, this.TargetModelDescriptor, toDelete);
500
+ // A `@SoftDelete` target is never hard-deleted the same degradation
501
+ // `SubjectExecutor.effectivePolicy` applies to orphans on the save() path. The stamp goes
502
+ // through a model-aware builder so the DateTime passes the column's converter.
503
+ const softDeleteColumn = this.TargetModelDescriptor.SoftDelete?.DeletedAt;
504
+ if (softDeleteColumn) {
505
+ const { query } = createQuery(this.Relation.TargetModel, UpdateQueryBuilder);
506
+ const update = query.update({ [softDeleteColumn]: DateTime.now() });
507
+ update.where(this.Relation.ForeignKey, this.OwnerJoinValue);
508
+ // Rows stamped by an earlier sync keep their original deletion time.
509
+ update.whereNull(softDeleteColumn);
510
+ if (toKeep.length !== 0 && keys.length !== 0) {
511
+ whereNotAnyPk(update, this.TargetModelDescriptor, toKeep);
512
+ }
513
+ await update;
514
+ return;
515
+ }
516
+ const query = this.Driver.del().from(this.TargetModelDescriptor.TableName).where(this.Relation.ForeignKey, this.OwnerJoinValue);
517
+ if (this.Driver.Options.Database) {
518
+ query.database(this.Driver.Options.Database);
519
+ }
520
+ // if we have data in relation, we need to exclude them from the delete query
521
+ if (toKeep.length !== 0 && keys.length !== 0) {
522
+ whereNotAnyPk(query, this.TargetModelDescriptor, toKeep);
441
523
  }
442
524
  await query;
443
525
  }
444
526
  /**
445
527
  * Populates this relation ( loads all data related to owner of this relation)
528
+ *
529
+ * Pushes the rows into THIS list rather than routing through `Owner.attach()`: attach flags
530
+ * the owner dirty ( a read must not create unsaved changes ), feeds every sibling relation
531
+ * with the same target model, and drops discriminated subclass rows because their
532
+ * constructor is not the declared target. Only attach's back-reference wiring is kept.
446
533
  */
447
534
  async populate(callback) {
448
535
  const query = this.Relation.TargetModel.where(this.Relation.ForeignKey, this.OwnerJoinValue);
@@ -453,7 +540,12 @@ let OneToManyRelationList = class OneToManyRelationList extends Relation {
453
540
  if (result) {
454
541
  this.length = 0;
455
542
  result.forEach((r) => {
456
- this.Owner.attach(r);
543
+ // Set the child's back-reference to this owner, when the child declares one.
544
+ const backRef = [...(r.ModelDescriptor?.Relations.entries() ?? [])].find((e) => e[1].ForeignKey === this.Relation.ForeignKey);
545
+ if (backRef) {
546
+ r[backRef[0]].Value = this.Owner;
547
+ }
548
+ this.push(r);
457
549
  });
458
550
  }
459
551
  this.Populated = true;
@@ -503,67 +595,6 @@ let OneToManyRelationList = class OneToManyRelationList extends Relation {
503
595
  await f.insert(InsertBehaviour.InsertOrUpdate);
504
596
  }
505
597
  }
506
- /**
507
- * Calculates difference between this relation and dataset ( items from this relation that are not in dataset and items from dataset that are not in this relation)
508
- *
509
- * @param dataset
510
- * @param callback
511
- * @returns Difference between this relation and dataset
512
- */
513
- diff(dataset, callback) {
514
- return Dataset.diff(dataset, callback)([...this], pkColumns(this.TargetModelDescriptor));
515
- }
516
- /**
517
- * Sets data in relation ( clear data and replace with new dataset )
518
- *
519
- * @param obj
520
- */
521
- set(obj) {
522
- const toPush = _.isFunction(obj) ? obj([...this], pkColumns(this.TargetModelDescriptor)) : obj;
523
- this.empty();
524
- this.push(...toPush);
525
- }
526
- /**
527
- * Calculates intersection between data in this relation and provided dataset
528
- *
529
- * @param obj
530
- * @param callback compare function, if not set - primary key value is used
531
- * @returns Data that are in both sets
532
- */
533
- intersection(obj, callback) {
534
- return Dataset.intersection(obj, callback)([...this], pkColumns(this.TargetModelDescriptor));
535
- }
536
- /**
537
- * Combines data with this relation and saves to db
538
- * Shorthand for push
539
- * @param obj
540
- */
541
- union(obj) {
542
- this.push(...obj);
543
- }
544
- /**
545
- * Returns the elements of an array that meet the condition specified in a callback function.
546
- * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.
547
- */
548
- filter(predicate) {
549
- return [...this].filter(predicate);
550
- }
551
- remove(obj) {
552
- const toRemove = _.isFunction(obj) ? this.filter(obj) : Array.isArray(obj) ? obj : [obj];
553
- this.set((data) => {
554
- return data.filter((d) => !toRemove.includes(d));
555
- });
556
- return toRemove;
557
- }
558
- flatMap(callback) {
559
- const r = this.map(callback);
560
- return r.flatMap(x => x);
561
- }
562
- map(callback) {
563
- const r = [];
564
- this.forEach((x, i, a) => r.push(callback(x, i, a)));
565
- return r;
566
- }
567
598
  };
568
599
  OneToManyRelationList = __decorate([
569
600
  NewInstance()