1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var Repository_1 = require("./Repository");
|
5 | var AbstractSqliteDriver_1 = require("../driver/sqlite-abstract/AbstractSqliteDriver");
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | var TreeRepository = (function (_super) {
|
12 | tslib_1.__extends(TreeRepository, _super);
|
13 | function TreeRepository() {
|
14 | return _super !== null && _super.apply(this, arguments) || this;
|
15 | }
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | |
22 |
|
23 |
|
24 | TreeRepository.prototype.findTrees = function () {
|
25 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
26 | var roots;
|
27 | var _this = this;
|
28 | return tslib_1.__generator(this, function (_a) {
|
29 | switch (_a.label) {
|
30 | case 0: return [4 , this.findRoots()];
|
31 | case 1:
|
32 | roots = _a.sent();
|
33 | return [4 , Promise.all(roots.map(function (root) { return _this.findDescendantsTree(root); }))];
|
34 | case 2:
|
35 | _a.sent();
|
36 | return [2 , roots];
|
37 | }
|
38 | });
|
39 | });
|
40 | };
|
41 | |
42 |
|
43 |
|
44 | TreeRepository.prototype.findRoots = function () {
|
45 | var _this = this;
|
46 | var escapeAlias = function (alias) { return _this.manager.connection.driver.escape(alias); };
|
47 | var escapeColumn = function (column) { return _this.manager.connection.driver.escape(column); };
|
48 | var parentPropertyName = this.manager.connection.namingStrategy.joinColumnName(this.metadata.treeParentRelation.propertyName, "id");
|
49 | return this.createQueryBuilder("treeEntity")
|
50 | .where(escapeAlias("treeEntity") + "." + escapeColumn(parentPropertyName) + " IS NULL")
|
51 | .getMany();
|
52 | };
|
53 | |
54 |
|
55 |
|
56 | TreeRepository.prototype.findDescendants = function (entity) {
|
57 | return this
|
58 | .createDescendantsQueryBuilder("treeEntity", "treeClosure", entity)
|
59 | .getMany();
|
60 | };
|
61 | |
62 |
|
63 |
|
64 | TreeRepository.prototype.findDescendantsTree = function (entity) {
|
65 | var _this = this;
|
66 |
|
67 | return this
|
68 | .createDescendantsQueryBuilder("treeEntity", "treeClosure", entity)
|
69 | .getRawAndEntities()
|
70 | .then(function (entitiesAndScalars) {
|
71 | var relationMaps = _this.createRelationMaps("treeEntity", entitiesAndScalars.raw);
|
72 | _this.buildChildrenEntityTree(entity, entitiesAndScalars.entities, relationMaps);
|
73 | return entity;
|
74 | });
|
75 | };
|
76 | |
77 |
|
78 |
|
79 | TreeRepository.prototype.countDescendants = function (entity) {
|
80 | return this
|
81 | .createDescendantsQueryBuilder("treeEntity", "treeClosure", entity)
|
82 | .getCount();
|
83 | };
|
84 | |
85 |
|
86 |
|
87 | TreeRepository.prototype.createDescendantsQueryBuilder = function (alias, closureTableAlias, entity) {
|
88 | var _this = this;
|
89 |
|
90 | var escape = function (alias) { return _this.manager.connection.driver.escape(alias); };
|
91 | if (this.metadata.treeType === "closure-table") {
|
92 | var joinCondition = this.metadata.closureJunctionTable.descendantColumns.map(function (column) {
|
93 | return escape(closureTableAlias) + "." + escape(column.propertyPath) + " = " + escape(alias) + "." + escape(column.referencedColumn.propertyPath);
|
94 | }).join(" AND ");
|
95 | var parameters_1 = {};
|
96 | var whereCondition = this.metadata.closureJunctionTable.ancestorColumns.map(function (column) {
|
97 | parameters_1[column.referencedColumn.propertyName] = column.referencedColumn.getEntityValue(entity);
|
98 | return escape(closureTableAlias) + "." + escape(column.propertyPath) + " = :" + column.referencedColumn.propertyName;
|
99 | }).join(" AND ");
|
100 | return this
|
101 | .createQueryBuilder(alias)
|
102 | .innerJoin(this.metadata.closureJunctionTable.tableName, closureTableAlias, joinCondition)
|
103 | .where(whereCondition)
|
104 | .setParameters(parameters_1);
|
105 | }
|
106 | else if (this.metadata.treeType === "nested-set") {
|
107 | var whereCondition = alias + "." + this.metadata.nestedSetLeftColumn.propertyPath + " BETWEEN " +
|
108 | "joined." + this.metadata.nestedSetLeftColumn.propertyPath + " AND joined." + this.metadata.nestedSetRightColumn.propertyPath;
|
109 | var parameters_2 = {};
|
110 | var joinCondition = this.metadata.treeParentRelation.joinColumns.map(function (joinColumn) {
|
111 | var parameterName = joinColumn.referencedColumn.propertyPath.replace(".", "_");
|
112 | parameters_2[parameterName] = joinColumn.referencedColumn.getEntityValue(entity);
|
113 | return "joined." + joinColumn.referencedColumn.propertyPath + " = :" + parameterName;
|
114 | }).join(" AND ");
|
115 | return this
|
116 | .createQueryBuilder(alias)
|
117 | .innerJoin(this.metadata.targetName, "joined", whereCondition)
|
118 | .where(joinCondition, parameters_2);
|
119 | }
|
120 | else if (this.metadata.treeType === "materialized-path") {
|
121 | return this
|
122 | .createQueryBuilder(alias)
|
123 | .where(function (qb) {
|
124 | var subQuery = qb.subQuery()
|
125 | .select(_this.metadata.targetName + "." + _this.metadata.materializedPathColumn.propertyPath, "path")
|
126 | .from(_this.metadata.target, _this.metadata.targetName)
|
127 | .whereInIds(_this.metadata.getEntityIdMap(entity));
|
128 | qb.setNativeParameters(subQuery.expressionMap.nativeParameters);
|
129 | if (_this.manager.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver) {
|
130 | return alias + "." + _this.metadata.materializedPathColumn.propertyPath + " LIKE " + subQuery.getQuery() + " || '%'";
|
131 | }
|
132 | else {
|
133 | return alias + "." + _this.metadata.materializedPathColumn.propertyPath + " LIKE CONCAT(" + subQuery.getQuery() + ", '%')";
|
134 | }
|
135 | });
|
136 | }
|
137 | throw new Error("Supported only in tree entities");
|
138 | };
|
139 | |
140 |
|
141 |
|
142 | TreeRepository.prototype.findAncestors = function (entity) {
|
143 | return this
|
144 | .createAncestorsQueryBuilder("treeEntity", "treeClosure", entity)
|
145 | .getMany();
|
146 | };
|
147 | |
148 |
|
149 |
|
150 | TreeRepository.prototype.findAncestorsTree = function (entity) {
|
151 | var _this = this;
|
152 |
|
153 | return this
|
154 | .createAncestorsQueryBuilder("treeEntity", "treeClosure", entity)
|
155 | .getRawAndEntities()
|
156 | .then(function (entitiesAndScalars) {
|
157 | var relationMaps = _this.createRelationMaps("treeEntity", entitiesAndScalars.raw);
|
158 | _this.buildParentEntityTree(entity, entitiesAndScalars.entities, relationMaps);
|
159 | return entity;
|
160 | });
|
161 | };
|
162 | |
163 |
|
164 |
|
165 | TreeRepository.prototype.countAncestors = function (entity) {
|
166 | return this
|
167 | .createAncestorsQueryBuilder("treeEntity", "treeClosure", entity)
|
168 | .getCount();
|
169 | };
|
170 | |
171 |
|
172 |
|
173 | TreeRepository.prototype.createAncestorsQueryBuilder = function (alias, closureTableAlias, entity) {
|
174 |
|
175 |
|
176 | var _this = this;
|
177 | if (this.metadata.treeType === "closure-table") {
|
178 | var joinCondition = this.metadata.closureJunctionTable.ancestorColumns.map(function (column) {
|
179 | return closureTableAlias + "." + column.propertyPath + " = " + alias + "." + column.referencedColumn.propertyPath;
|
180 | }).join(" AND ");
|
181 | var parameters_3 = {};
|
182 | var whereCondition = this.metadata.closureJunctionTable.descendantColumns.map(function (column) {
|
183 | parameters_3[column.referencedColumn.propertyName] = column.referencedColumn.getEntityValue(entity);
|
184 | return closureTableAlias + "." + column.propertyPath + " = :" + column.referencedColumn.propertyName;
|
185 | }).join(" AND ");
|
186 | return this
|
187 | .createQueryBuilder(alias)
|
188 | .innerJoin(this.metadata.closureJunctionTable.tableName, closureTableAlias, joinCondition)
|
189 | .where(whereCondition)
|
190 | .setParameters(parameters_3);
|
191 | }
|
192 | else if (this.metadata.treeType === "nested-set") {
|
193 | var joinCondition = "joined." + this.metadata.nestedSetLeftColumn.propertyPath + " BETWEEN " +
|
194 | alias + "." + this.metadata.nestedSetLeftColumn.propertyPath + " AND " + alias + "." + this.metadata.nestedSetRightColumn.propertyPath;
|
195 | var parameters_4 = {};
|
196 | var whereCondition = this.metadata.treeParentRelation.joinColumns.map(function (joinColumn) {
|
197 | var parameterName = joinColumn.referencedColumn.propertyPath.replace(".", "_");
|
198 | parameters_4[parameterName] = joinColumn.referencedColumn.getEntityValue(entity);
|
199 | return "joined." + joinColumn.referencedColumn.propertyPath + " = :" + parameterName;
|
200 | }).join(" AND ");
|
201 | return this
|
202 | .createQueryBuilder(alias)
|
203 | .innerJoin(this.metadata.targetName, "joined", joinCondition)
|
204 | .where(whereCondition, parameters_4);
|
205 | }
|
206 | else if (this.metadata.treeType === "materialized-path") {
|
207 |
|
208 | return this
|
209 | .createQueryBuilder(alias)
|
210 | .where(function (qb) {
|
211 | var subQuery = qb.subQuery()
|
212 | .select(_this.metadata.targetName + "." + _this.metadata.materializedPathColumn.propertyPath, "path")
|
213 | .from(_this.metadata.target, _this.metadata.targetName)
|
214 | .whereInIds(_this.metadata.getEntityIdMap(entity));
|
215 | qb.setNativeParameters(subQuery.expressionMap.nativeParameters);
|
216 | if (_this.manager.connection.driver instanceof AbstractSqliteDriver_1.AbstractSqliteDriver) {
|
217 | return subQuery.getQuery() + " LIKE " + alias + "." + _this.metadata.materializedPathColumn.propertyPath + " || '%'";
|
218 | }
|
219 | else {
|
220 | return subQuery.getQuery() + " LIKE CONCAT(" + alias + "." + _this.metadata.materializedPathColumn.propertyPath + ", '%')";
|
221 | }
|
222 | });
|
223 | }
|
224 | throw new Error("Supported only in tree entities");
|
225 | };
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | TreeRepository.prototype.createRelationMaps = function (alias, rawResults) {
|
236 | var _this = this;
|
237 | return rawResults.map(function (rawResult) {
|
238 | var joinColumn = _this.metadata.treeParentRelation.joinColumns[0];
|
239 |
|
240 | var joinColumnName = joinColumn.givenDatabaseName || joinColumn.databaseName;
|
241 | var id = rawResult[alias + "_" + _this.metadata.primaryColumns[0].databaseName];
|
242 | var parentId = rawResult[alias + "_" + joinColumnName];
|
243 | return {
|
244 | id: _this.manager.connection.driver.prepareHydratedValue(id, _this.metadata.primaryColumns[0]),
|
245 | parentId: _this.manager.connection.driver.prepareHydratedValue(parentId, joinColumn),
|
246 | };
|
247 | });
|
248 | };
|
249 | TreeRepository.prototype.buildChildrenEntityTree = function (entity, entities, relationMaps) {
|
250 | var _this = this;
|
251 | var childProperty = this.metadata.treeChildrenRelation.propertyName;
|
252 | var parentEntityId = this.metadata.primaryColumns[0].getEntityValue(entity);
|
253 | var childRelationMaps = relationMaps.filter(function (relationMap) { return relationMap.parentId === parentEntityId; });
|
254 | var childIds = childRelationMaps.map(function (relationMap) { return relationMap.id; });
|
255 | entity[childProperty] = entities.filter(function (entity) { return childIds.indexOf(entity.id) !== -1; });
|
256 | entity[childProperty].forEach(function (childEntity) {
|
257 | _this.buildChildrenEntityTree(childEntity, entities, relationMaps);
|
258 | });
|
259 | };
|
260 | TreeRepository.prototype.buildParentEntityTree = function (entity, entities, relationMaps) {
|
261 | var _this = this;
|
262 | var parentProperty = this.metadata.treeParentRelation.propertyName;
|
263 | var entityId = this.metadata.primaryColumns[0].getEntityValue(entity);
|
264 | var parentRelationMap = relationMaps.find(function (relationMap) { return relationMap.id === entityId; });
|
265 | var parentEntity = entities.find(function (entity) {
|
266 | if (!parentRelationMap)
|
267 | return false;
|
268 | return entity[_this.metadata.primaryColumns[0].propertyName] === parentRelationMap.parentId;
|
269 | });
|
270 | if (parentEntity) {
|
271 | entity[parentProperty] = parentEntity;
|
272 | this.buildParentEntityTree(entity[parentProperty], entities, relationMaps);
|
273 | }
|
274 | };
|
275 | return TreeRepository;
|
276 | }(Repository_1.Repository));
|
277 | exports.TreeRepository = TreeRepository;
|
278 |
|
279 |
|