@entity-access/entity-access 1.0.252 → 1.0.253

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 (96) hide show
  1. package/.vscode/launch.json +2 -1
  2. package/dist/common/symbols/symbols.d.ts +1 -0
  3. package/dist/common/symbols/symbols.d.ts.map +1 -1
  4. package/dist/common/symbols/symbols.js +1 -0
  5. package/dist/common/symbols/symbols.js.map +1 -1
  6. package/dist/decorators/ForeignKey.d.ts +8 -7
  7. package/dist/decorators/ForeignKey.d.ts.map +1 -1
  8. package/dist/decorators/ForeignKey.js +43 -8
  9. package/dist/decorators/ForeignKey.js.map +1 -1
  10. package/dist/decorators/IColumn.d.ts +6 -3
  11. package/dist/decorators/IColumn.d.ts.map +1 -1
  12. package/dist/decorators/Relate.d.ts.map +1 -1
  13. package/dist/decorators/Relate.js +8 -6
  14. package/dist/decorators/Relate.js.map +1 -1
  15. package/dist/entity-query/EntityType.d.ts +5 -1
  16. package/dist/entity-query/EntityType.d.ts.map +1 -1
  17. package/dist/entity-query/EntityType.js +57 -25
  18. package/dist/entity-query/EntityType.js.map +1 -1
  19. package/dist/migrations/postgres/PostgresAutomaticMigrations.js +1 -1
  20. package/dist/migrations/postgres/PostgresAutomaticMigrations.js.map +1 -1
  21. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js +1 -1
  22. package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js.map +1 -1
  23. package/dist/model/EntityModel.js +2 -2
  24. package/dist/model/EntityModel.js.map +1 -1
  25. package/dist/model/EntitySource.d.ts +6 -1
  26. package/dist/model/EntitySource.d.ts.map +1 -1
  27. package/dist/model/EntitySource.js.map +1 -1
  28. package/dist/model/SourceExpression.d.ts +1 -22
  29. package/dist/model/SourceExpression.d.ts.map +1 -1
  30. package/dist/model/SourceExpression.js +116 -98
  31. package/dist/model/SourceExpression.js.map +1 -1
  32. package/dist/model/changes/ChangeEntry.d.ts.map +1 -1
  33. package/dist/model/changes/ChangeEntry.js +62 -25
  34. package/dist/model/changes/ChangeEntry.js.map +1 -1
  35. package/dist/model/changes/ChangeSet.d.ts +2 -1
  36. package/dist/model/changes/ChangeSet.d.ts.map +1 -1
  37. package/dist/model/changes/ChangeSet.js +4 -3
  38. package/dist/model/changes/ChangeSet.js.map +1 -1
  39. package/dist/model/identity/IdentityMap.d.ts +23 -0
  40. package/dist/model/identity/IdentityMap.d.ts.map +1 -0
  41. package/dist/model/identity/IdentityMap.js +113 -0
  42. package/dist/model/identity/IdentityMap.js.map +1 -0
  43. package/dist/model/identity/RelationMapper.d.ts +2 -3
  44. package/dist/model/identity/RelationMapper.d.ts.map +1 -1
  45. package/dist/model/identity/RelationMapper.js +60 -27
  46. package/dist/model/identity/RelationMapper.js.map +1 -1
  47. package/dist/model/identity/SearchIndex.d.ts +17 -0
  48. package/dist/model/identity/SearchIndex.d.ts.map +1 -0
  49. package/dist/model/identity/SearchIndex.js +109 -0
  50. package/dist/model/identity/SearchIndex.js.map +1 -0
  51. package/dist/model/verification/VerificationSession.d.ts +1 -1
  52. package/dist/model/verification/VerificationSession.d.ts.map +1 -1
  53. package/dist/model/verification/VerificationSession.js +18 -16
  54. package/dist/model/verification/VerificationSession.js.map +1 -1
  55. package/dist/query/ast/ExpressionToSql.d.ts.map +1 -1
  56. package/dist/query/ast/ExpressionToSql.js +74 -52
  57. package/dist/query/ast/ExpressionToSql.js.map +1 -1
  58. package/dist/query/expander/QueryExpander.d.ts.map +1 -1
  59. package/dist/query/expander/QueryExpander.js +41 -10
  60. package/dist/query/expander/QueryExpander.js.map +1 -1
  61. package/dist/tests/db-tests/tests/multi-fk-tests.d.ts +3 -0
  62. package/dist/tests/db-tests/tests/multi-fk-tests.d.ts.map +1 -0
  63. package/dist/tests/db-tests/tests/multi-fk-tests.js +38 -0
  64. package/dist/tests/db-tests/tests/multi-fk-tests.js.map +1 -0
  65. package/dist/tests/expressions/left-joins/child-joins.js +7 -7
  66. package/dist/tests/model/ShoppingContext.d.ts +9 -0
  67. package/dist/tests/model/ShoppingContext.d.ts.map +1 -1
  68. package/dist/tests/model/ShoppingContext.js +34 -0
  69. package/dist/tests/model/ShoppingContext.js.map +1 -1
  70. package/dist/tests/security/tests/include-items.d.ts.map +1 -1
  71. package/dist/tests/security/tests/include-items.js +1 -0
  72. package/dist/tests/security/tests/include-items.js.map +1 -1
  73. package/dist/tsconfig.tsbuildinfo +1 -1
  74. package/package.json +1 -1
  75. package/src/common/symbols/symbols.ts +2 -1
  76. package/src/decorators/ForeignKey.ts +66 -28
  77. package/src/decorators/IColumn.ts +4 -3
  78. package/src/decorators/Relate.ts +8 -6
  79. package/src/entity-query/EntityType.ts +60 -26
  80. package/src/migrations/postgres/PostgresAutomaticMigrations.ts +1 -1
  81. package/src/migrations/sql-server/SqlServerAutomaticMigrations.ts +1 -1
  82. package/src/model/EntityModel.ts +2 -2
  83. package/src/model/EntitySource.ts +6 -1
  84. package/src/model/SourceExpression.ts +132 -132
  85. package/src/model/changes/ChangeEntry.ts +68 -25
  86. package/src/model/changes/ChangeSet.ts +4 -3
  87. package/src/model/identity/IdentityMap.ts +126 -0
  88. package/src/model/identity/RelationMapper.ts +71 -27
  89. package/src/model/identity/SearchIndex.ts +120 -0
  90. package/src/model/verification/VerificationSession.ts +19 -16
  91. package/src/query/ast/ExpressionToSql.ts +77 -61
  92. package/src/query/expander/QueryExpander.ts +52 -28
  93. package/src/tests/db-tests/tests/multi-fk-tests.ts +46 -0
  94. package/src/tests/expressions/left-joins/child-joins.ts +7 -7
  95. package/src/tests/model/ShoppingContext.ts +32 -0
  96. package/src/tests/security/tests/include-items.ts +1 -0
@@ -3,6 +3,7 @@ import { IClassOf } from "./IClassOf.js";
3
3
  import { IForeignKeyConstraint } from "./IForeignKeyConstraint.js";
4
4
  import { ISqlType } from "./ISqlType.js";
5
5
 
6
+ export type FKType = { fkColumn: IColumn, relatedKeyColumn: IColumn };
6
7
 
7
8
  export interface IColumn {
8
9
  name?: string;
@@ -87,13 +88,13 @@ export interface IEntityRelation {
87
88
  singleInverseRelation?
88
89
 
89
90
 
90
- foreignKey: string;
91
+ // foreignKey: string;
91
92
 
92
93
  relatedTypeClass: IClassOf<any>;
93
94
 
94
95
  relatedTypeClassFactory?: () => IClassOf<any>;
95
96
 
96
- fkColumn?: IColumn;
97
+ fkMap: FKType[];
97
98
 
98
99
 
99
100
  relatedName: string;
@@ -105,7 +106,7 @@ export interface IEntityRelation {
105
106
 
106
107
  relatedRelation?: IEntityRelation;
107
108
 
108
- dotNotCreateIndex?: boolean;
109
+ doNotCreateIndex?: boolean;
109
110
 
110
111
  foreignKeyConstraint?: IForeignKeyConstraint;
111
112
 
@@ -51,7 +51,7 @@ export function RelateTo(c, p?): any {
51
51
 
52
52
  const { property, inverseKey: invKey, inverseProperty, dotNotCreateIndex, foreignKeyConstraint } = p;
53
53
 
54
- return (target: any, foreignKey: string): any => {
54
+ return (target: any, fkName: string): any => {
55
55
 
56
56
  const cn = target.constructor ?? target;
57
57
  const entityType = SchemaRegistry.model(cn);
@@ -61,13 +61,14 @@ export function RelateTo(c, p?): any {
61
61
  entityType.addRelation({
62
62
  type: entityType,
63
63
  name,
64
- foreignKey,
64
+ fkName,
65
+ fkMap: null,
65
66
  relatedTypeClass: c,
66
67
  relatedTypeClassFactory: p.type,
67
68
  relatedName: NameParser.parseMember(inverseProperty),
68
69
  relatedKey: invKey ? NameParser.parseMember(invKey) : void 0,
69
70
  foreignKeyConstraint,
70
- dotNotCreateIndex
71
+ doNotCreateIndex: dotNotCreateIndex
71
72
  });
72
73
 
73
74
  };
@@ -87,7 +88,7 @@ export function RelateToOne(c, p?): any {
87
88
 
88
89
  const { property, inverseKey: invKey, inverseProperty, dotNotCreateIndex } = p;
89
90
 
90
- return (target: any, foreignKey: string): any => {
91
+ return (target: any, fkName: string): any => {
91
92
 
92
93
  const cn = target.constructor ?? target;
93
94
  const entityType = SchemaRegistry.model(cn);
@@ -97,12 +98,13 @@ export function RelateToOne(c, p?): any {
97
98
  entityType.addRelation({
98
99
  type: entityType,
99
100
  name,
100
- foreignKey,
101
+ fkName,
102
+ fkMap:null,
101
103
  relatedTypeClass: c,
102
104
  relatedTypeClassFactory: p.type,
103
105
  relatedName: NameParser.parseMember(inverseProperty),
104
106
  relatedKey: invKey ? NameParser.parseMember(invKey) : void 0,
105
- dotNotCreateIndex,
107
+ doNotCreateIndex: dotNotCreateIndex,
106
108
  singleInverseRelation: true
107
109
  });
108
110
 
@@ -82,8 +82,27 @@ export default class EntityType {
82
82
 
83
83
  const existing = this.fieldMap.get(c.name);
84
84
  if (existing) {
85
- c.fkRelation = existing.fkRelation;
86
- c.fkRelation.fkColumn = c;
85
+ const fkRelation = c.fkRelation = existing.fkRelation;
86
+ if(fkRelation) {
87
+ fkRelation.fkMap = [{ fkColumn: c, relatedKeyColumn: null }];
88
+ // if(!fkRelation.fkMap?.length) {
89
+ // fkRelation.fkMap = [{ fkColumn: c, relatedKeyColumn: null}];
90
+ // } else {
91
+ // if(fkRelation.fkMap.length === 1) {
92
+ // fkRelation.fkMap[0].fkColumn = c;
93
+ // }
94
+ // }
95
+ }
96
+ // if (fkRelation?.fkMap) {
97
+ // if (!c.fkRelation.fkMap.length) {
98
+ // c.fkRelation.fkMap = [{ fkColumn: c, relatedKeyColumn: null }];
99
+ // } else {
100
+ // c.fkRelation.fkMap[0].fkColumn = c;
101
+ // }
102
+ // } else {
103
+ // c
104
+ // }
105
+ // c.fkRelation.fkColumn = c;
87
106
  }
88
107
 
89
108
  this.fieldMap.set(c.name, c);
@@ -109,26 +128,29 @@ export default class EntityType {
109
128
  }
110
129
 
111
130
 
112
- addRelation(relation: IEntityRelation, getInverseModel?: (t) => EntityType) {
131
+ addRelation(relation: IEntityRelation & { fkName?: string }, getInverseModel?: (t) => EntityType) {
113
132
  // we will also set fk to the corresponding column
114
133
  this.relations.push(relation);
115
134
  this.relationMap.set(relation.name, relation);
116
135
 
117
- // find fk...
118
- let fkColumn = this.fieldMap.get(relation.foreignKey);
119
- if(!fkColumn) {
120
- fkColumn = {
121
- name: relation.foreignKey,
122
- // columnName: relation.foreignKey,
123
- fkRelation: relation,
124
- dataType: "BigInt"
125
- };
126
- this.fieldMap.set(relation.foreignKey, fkColumn);
127
- }
128
- fkColumn.fkRelation = relation;
129
- relation.fkColumn = fkColumn;
130
- if (fkColumn.dataType === "Double") {
131
- fkColumn.dataType = "BigInt";
136
+ if (!relation.fkMap) {
137
+ // find fk...
138
+ let fkColumn = this.fieldMap.get(relation.fkName);
139
+ if(!fkColumn) {
140
+ fkColumn = {
141
+ name: relation.fkName,
142
+ // columnName: relation.foreignKey,
143
+ fkRelation: relation,
144
+ dataType: "BigInt"
145
+ };
146
+ this.fieldMap.set(relation.fkName, fkColumn);
147
+ relation.fkMap = [ { fkColumn, relatedKeyColumn: null} ];
148
+ }
149
+ fkColumn.fkRelation = relation;
150
+ // relation.fkColumn = fkColumn;
151
+ if (fkColumn.dataType === "Double") {
152
+ fkColumn.dataType = "BigInt";
153
+ }
132
154
  }
133
155
 
134
156
  if (!getInverseModel) {
@@ -137,14 +159,23 @@ export default class EntityType {
137
159
 
138
160
  // let us set inverse relations...
139
161
  const relatedType = getInverseModel(relation.relatedTypeClass);
162
+
163
+ relation.fkMap[0].relatedKeyColumn ??= relatedType.keys[0];
164
+ relation.fkMap = [ ... relation.fkMap.map((x) => ({ ... x}))];
165
+ for (const iterator of relation.fkMap) {
166
+ iterator.fkColumn = this.getField(iterator.fkColumn.name);
167
+ // iterator.fkColumn.fkRelation = relation;
168
+ iterator.relatedKeyColumn = relatedType.getField(iterator.relatedKeyColumn.name);
169
+ iterator.relatedKeyColumn.entityType = relatedType;
170
+ }
171
+
140
172
  relation.relatedEntity = relatedType;
141
173
  const inverseRelation: IEntityRelation = {
142
174
  name: relation.relatedName,
143
- foreignKey: "",
144
175
  relatedName: relation.name,
145
176
  relatedTypeClass: this.typeClass,
146
- dotNotCreateIndex: true,
147
- fkColumn,
177
+ doNotCreateIndex: true,
178
+ fkMap: null,
148
179
  isInverseRelation: true,
149
180
  isCollection: relation.singleInverseRelation ? false : true,
150
181
  relatedRelation: relation,
@@ -158,11 +189,14 @@ export default class EntityType {
158
189
 
159
190
  let { foreignKeyConstraint } = relation;
160
191
  if(foreignKeyConstraint) {
161
- foreignKeyConstraint = { ... foreignKeyConstraint};
162
- relation.foreignKeyConstraint = foreignKeyConstraint;
163
- foreignKeyConstraint.name ||= `FK_${this.name}_${fkColumn.name}_${this.typeClass.name}_${relatedType.keys[0].name}`;
164
- foreignKeyConstraint.column = fkColumn;
165
- foreignKeyConstraint.refColumns = relatedType.keys;
192
+ if (relation.fkMap.length === 1) {
193
+ const { fkColumn } = relation.fkMap[0];
194
+ foreignKeyConstraint = { ... foreignKeyConstraint};
195
+ relation.foreignKeyConstraint = foreignKeyConstraint;
196
+ foreignKeyConstraint.name ||= `FK_${this.name}_${fkColumn.name}_${this.typeClass.name}_${relatedType.keys[0].name}`;
197
+ foreignKeyConstraint.column = fkColumn;
198
+ foreignKeyConstraint.refColumns = relatedType.keys;
199
+ }
166
200
  }
167
201
  return relation;
168
202
  }
@@ -26,7 +26,7 @@ export default class PostgresAutomaticMigrations extends PostgresMigrations {
26
26
  await this.createIndexes(context, type, nonKeyColumns.filter((x) =>
27
27
  x.fkRelation
28
28
  && (!x.key || type.keys.indexOf(x) !== 0)
29
- && !x.fkRelation?.dotNotCreateIndex));
29
+ && !x.fkRelation?.doNotCreateIndex));
30
30
 
31
31
  }
32
32
 
@@ -26,7 +26,7 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
26
26
  await this.createIndexes(context, type, nonKeyColumns.filter((x) =>
27
27
  x.fkRelation
28
28
  && (!x.key || type.keys.indexOf(x) !== 0)
29
- && !x.fkRelation?.dotNotCreateIndex));
29
+ && !x.fkRelation?.doNotCreateIndex));
30
30
 
31
31
  }
32
32
 
@@ -23,8 +23,8 @@ const getOrCreateModel = (map: Map<any, EntityType>, type: IClassOf<any>, naming
23
23
  ? column.columnName
24
24
  : (namingConvention
25
25
  ? namingConvention(column.columnName) : column.columnName);
26
- t.addColumn(column);
27
26
  column.entityType = t;
27
+ t.addColumn(column);
28
28
  }
29
29
  t.indexes.push(... original.indexes.map((i) => ({ ... i, columns: [ ... i.columns.map((c) => ( { ... c}))] })));
30
30
  // sort keys...
@@ -38,7 +38,7 @@ const getOrCreateModel = (map: Map<any, EntityType>, type: IClassOf<any>, naming
38
38
  if (iterator.isInverseRelation) {
39
39
  continue;
40
40
  }
41
- const relation: IEntityRelation = { ... iterator, fkColumn: void 0, relatedEntity: void 0,type: t };
41
+ const relation: IEntityRelation = { ... iterator, relatedEntity: void 0,type: t };
42
42
  t.addRelation(relation, (tc) => getOrCreateModel(map, tc, namingConvention));
43
43
  }
44
44
  return t;
@@ -28,8 +28,13 @@ export type ISaveDirect<T> = {
28
28
  keys: Partial<T>,
29
29
  changes: Partial<T>,
30
30
  // select?: Partial<T>,
31
- mode: "selectOrInsert" | "insert",
31
+ mode: "selectOrInsert",
32
32
  updateAfterSelect?: never
33
+ } | {
34
+ keys?: never,
35
+ mode: "insert",
36
+ changes: Partial<T>,
37
+ updateAfterSelect?: never,
33
38
  } | {
34
39
  keys?: Partial<T>,
35
40
  changes: Partial<T>,
@@ -1,132 +1,132 @@
1
- import { modelSymbol } from "../common/symbols/symbols.js";
2
- import EntityType from "../entity-query/EntityType.js";
3
- import { Expression, JoinExpression, ParameterExpression, SelectStatement } from "../query/ast/Expressions.js";
4
- import { ITextQueryFragment, QueryParameter } from "../query/ast/IStringTransformer.js";
5
- import EntityContext from "./EntityContext.js";
6
-
7
- const sourceSymbol = Symbol("source");
8
-
9
- export class SourceExpression {
10
-
11
- public static create(p: Partial<SourceExpression>) {
12
- return new SourceExpression(p);
13
- }
14
-
15
- alias: ParameterExpression;
16
- parameter?: ParameterExpression;
17
- context: EntityContext;
18
- model?: EntityType;
19
- include?: EntityType[];
20
- select: SelectStatement;
21
- parent?: SourceExpression;
22
-
23
- private map: Map<string,SourceExpression>;
24
- private paramMap: Map<string, SourceExpression>;
25
-
26
- private constructor(p: Partial<SourceExpression>) {
27
- Object.setPrototypeOf(p, SourceExpression.prototype);
28
- const r = p as SourceExpression;
29
- if (r.parent) {
30
- r.map = r.parent.map;
31
- r.paramMap = r.parent.paramMap;
32
- } else {
33
- r.paramMap = new Map();
34
- r.map = new Map();
35
- }
36
- return r;
37
- }
38
-
39
- copy() {
40
- const r = { ... this } as SourceExpression;
41
- Object.setPrototypeOf(r, Object.getPrototypeOf(this));
42
- r.map = new Map(this.map.entries());
43
- r.paramMap = new Map(this.paramMap.entries());
44
- r.select = Expression.clone(this.select);
45
- return r;
46
- }
47
-
48
- addJoin(property: string) {
49
- const { select } = this;
50
- select.joins ??= [];
51
-
52
- const relation = this.model.getProperty(property);
53
- const model = this.context.model.register(relation.relation.relatedTypeClass)[modelSymbol];
54
-
55
- for (const iterator of select.joins) {
56
- if (model === iterator.model) {
57
- return iterator[sourceSymbol] as SourceExpression;
58
- }
59
- }
60
- const column = relation.relation.fkColumn;
61
- const parameter = ParameterExpression.create({ name: this.parameter + "." + property, model });
62
- const source = this.addSource(model, parameter);
63
- const join = JoinExpression.create({
64
- as: source.alias,
65
- joinType: column.nullable ? "LEFT" : "INNER",
66
- model,
67
- source: Expression.identifier(model.name),
68
- where: Expression.logicalAnd(
69
- Expression.member(
70
- this.alias,
71
- column.columnName),
72
- Expression.member(
73
- source.alias,
74
- model.keys[0].columnName)
75
- )
76
- });
77
- select.joins.push(join);
78
- join[sourceSymbol] = source;
79
- return source;
80
- }
81
-
82
- addSource(model: EntityType, parameter: ParameterExpression) {
83
-
84
- const { context } = this;
85
- const source = SourceExpression.create({
86
- model,
87
- parameter,
88
- context,
89
- parent: this
90
- });
91
-
92
- source.map = this.map;
93
- source.paramMap = this.paramMap;
94
-
95
- let id = 0;
96
- let alias: string;
97
- do {
98
- alias = model.name[0] + id++;
99
- const exists = this.map.get(alias);
100
- if (exists === null || exists === void 0) {
101
- break;
102
- }
103
- }while (true);
104
- source.alias = ParameterExpression.create({ name: alias, model });
105
- this.map.set(alias, source);
106
- this.paramMap.set(parameter.name, source);
107
- return source;
108
- }
109
-
110
- flatten(chain: string[]): ITextQueryFragment {
111
- const [start, ... others ] = chain;
112
- if (start === this.parameter.name) {
113
- return this.prepareNames(others);
114
- }
115
- const mapped = this.paramMap.get(start);
116
- if (mapped) {
117
- return mapped.prepareNames(others);
118
- }
119
- throw new Error("Not found");
120
- }
121
-
122
- prepareNames([property , ... others]: string[]): ITextQueryFragment {
123
- const p = this.model.getProperty(property);
124
- if (others.length === 0) {
125
- return `${ QueryParameter.create(() => this.alias.name)}.${p.field.columnName}`;
126
- }
127
-
128
- // this must be a navigation...
129
- const source = this.addJoin(property);
130
- return source.prepareNames(others);
131
- }
132
- }
1
+ // import { modelSymbol } from "../common/symbols/symbols.js";
2
+ // import EntityType from "../entity-query/EntityType.js";
3
+ // import { Expression, JoinExpression, ParameterExpression, SelectStatement } from "../query/ast/Expressions.js";
4
+ // import { ITextQueryFragment, QueryParameter } from "../query/ast/IStringTransformer.js";
5
+ // import EntityContext from "./EntityContext.js";
6
+
7
+ // const sourceSymbol = Symbol("source");
8
+
9
+ // export class SourceExpression {
10
+
11
+ // public static create(p: Partial<SourceExpression>) {
12
+ // return new SourceExpression(p);
13
+ // }
14
+
15
+ // alias: ParameterExpression;
16
+ // parameter?: ParameterExpression;
17
+ // context: EntityContext;
18
+ // model?: EntityType;
19
+ // include?: EntityType[];
20
+ // select: SelectStatement;
21
+ // parent?: SourceExpression;
22
+
23
+ // private map: Map<string,SourceExpression>;
24
+ // private paramMap: Map<string, SourceExpression>;
25
+
26
+ // private constructor(p: Partial<SourceExpression>) {
27
+ // Object.setPrototypeOf(p, SourceExpression.prototype);
28
+ // const r = p as SourceExpression;
29
+ // if (r.parent) {
30
+ // r.map = r.parent.map;
31
+ // r.paramMap = r.parent.paramMap;
32
+ // } else {
33
+ // r.paramMap = new Map();
34
+ // r.map = new Map();
35
+ // }
36
+ // return r;
37
+ // }
38
+
39
+ // copy() {
40
+ // const r = { ... this } as SourceExpression;
41
+ // Object.setPrototypeOf(r, Object.getPrototypeOf(this));
42
+ // r.map = new Map(this.map.entries());
43
+ // r.paramMap = new Map(this.paramMap.entries());
44
+ // r.select = Expression.clone(this.select);
45
+ // return r;
46
+ // }
47
+
48
+ // addJoin(property: string) {
49
+ // const { select } = this;
50
+ // select.joins ??= [];
51
+
52
+ // const relation = this.model.getProperty(property);
53
+ // const model = this.context.model.register(relation.relation.relatedTypeClass)[modelSymbol];
54
+
55
+ // for (const iterator of select.joins) {
56
+ // if (model === iterator.model) {
57
+ // return iterator[sourceSymbol] as SourceExpression;
58
+ // }
59
+ // }
60
+ // const column = relation.relation.fkColumn;
61
+ // const parameter = ParameterExpression.create({ name: this.parameter + "." + property, model });
62
+ // const source = this.addSource(model, parameter);
63
+ // const join = JoinExpression.create({
64
+ // as: source.alias,
65
+ // joinType: column.nullable ? "LEFT" : "INNER",
66
+ // model,
67
+ // source: Expression.identifier(model.name),
68
+ // where: Expression.logicalAnd(
69
+ // Expression.member(
70
+ // this.alias,
71
+ // column.columnName),
72
+ // Expression.member(
73
+ // source.alias,
74
+ // model.keys[0].columnName)
75
+ // )
76
+ // });
77
+ // select.joins.push(join);
78
+ // join[sourceSymbol] = source;
79
+ // return source;
80
+ // }
81
+
82
+ // addSource(model: EntityType, parameter: ParameterExpression) {
83
+
84
+ // const { context } = this;
85
+ // const source = SourceExpression.create({
86
+ // model,
87
+ // parameter,
88
+ // context,
89
+ // parent: this
90
+ // });
91
+
92
+ // source.map = this.map;
93
+ // source.paramMap = this.paramMap;
94
+
95
+ // let id = 0;
96
+ // let alias: string;
97
+ // do {
98
+ // alias = model.name[0] + id++;
99
+ // const exists = this.map.get(alias);
100
+ // if (exists === null || exists === void 0) {
101
+ // break;
102
+ // }
103
+ // }while (true);
104
+ // source.alias = ParameterExpression.create({ name: alias, model });
105
+ // this.map.set(alias, source);
106
+ // this.paramMap.set(parameter.name, source);
107
+ // return source;
108
+ // }
109
+
110
+ // flatten(chain: string[]): ITextQueryFragment {
111
+ // const [start, ... others ] = chain;
112
+ // if (start === this.parameter.name) {
113
+ // return this.prepareNames(others);
114
+ // }
115
+ // const mapped = this.paramMap.get(start);
116
+ // if (mapped) {
117
+ // return mapped.prepareNames(others);
118
+ // }
119
+ // throw new Error("Not found");
120
+ // }
121
+
122
+ // prepareNames([property , ... others]: string[]): ITextQueryFragment {
123
+ // const p = this.model.getProperty(property);
124
+ // if (others.length === 0) {
125
+ // return `${ QueryParameter.create(() => this.alias.name)}.${p.field.columnName}`;
126
+ // }
127
+
128
+ // // this must be a navigation...
129
+ // const source = this.addJoin(property);
130
+ // return source.prepareNames(others);
131
+ // }
132
+ // }