UNPKG

10.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var FindRelationsNotFoundError_1 = require("../error/FindRelationsNotFoundError");
4var StringUtils_1 = require("../util/StringUtils");
5/**
6 * Utilities to work with FindOptions.
7 */
8var FindOptionsUtils = /** @class */ (function () {
9 function FindOptionsUtils() {
10 }
11 // -------------------------------------------------------------------------
12 // Public Static Methods
13 // -------------------------------------------------------------------------
14 /**
15 * Checks if given object is really instance of FindOneOptions interface.
16 */
17 FindOptionsUtils.isFindOneOptions = function (obj) {
18 var possibleOptions = obj;
19 return possibleOptions &&
20 (possibleOptions.select instanceof Array ||
21 possibleOptions.where instanceof Object ||
22 typeof possibleOptions.where === "string" ||
23 possibleOptions.relations instanceof Array ||
24 possibleOptions.join instanceof Object ||
25 possibleOptions.order instanceof Object ||
26 possibleOptions.cache instanceof Object ||
27 typeof possibleOptions.cache === "boolean" ||
28 typeof possibleOptions.cache === "number" ||
29 possibleOptions.lock instanceof Object ||
30 possibleOptions.loadRelationIds instanceof Object ||
31 typeof possibleOptions.loadRelationIds === "boolean" ||
32 typeof possibleOptions.loadEagerRelations === "boolean");
33 };
34 /**
35 * Checks if given object is really instance of FindManyOptions interface.
36 */
37 FindOptionsUtils.isFindManyOptions = function (obj) {
38 var possibleOptions = obj;
39 return possibleOptions && (this.isFindOneOptions(possibleOptions) ||
40 typeof possibleOptions.skip === "number" ||
41 typeof possibleOptions.take === "number" ||
42 typeof possibleOptions.skip === "string" ||
43 typeof possibleOptions.take === "string");
44 };
45 /**
46 * Checks if given object is really instance of FindOptions interface.
47 */
48 FindOptionsUtils.extractFindManyOptionsAlias = function (object) {
49 if (this.isFindManyOptions(object) && object.join)
50 return object.join.alias;
51 return undefined;
52 };
53 /**
54 * Applies give find many options to the given query builder.
55 */
56 FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder = function (qb, options) {
57 if (this.isFindManyOptions(options))
58 return this.applyOptionsToQueryBuilder(qb, options);
59 if (options)
60 return qb.where(options);
61 return qb;
62 };
63 /**
64 * Applies give find options to the given query builder.
65 */
66 FindOptionsUtils.applyOptionsToQueryBuilder = function (qb, options) {
67 // if options are not set then simply return query builder. This is made for simplicity of usage.
68 if (!options || (!this.isFindOneOptions(options) && !this.isFindManyOptions(options)))
69 return qb;
70 if (!qb.expressionMap.mainAlias || !qb.expressionMap.mainAlias.hasMetadata)
71 return qb;
72 var metadata = qb.expressionMap.mainAlias.metadata;
73 // apply all options from FindOptions
74 if (options.select) {
75 qb.select([]);
76 options.select.forEach(function (select) {
77 if (!metadata.findColumnWithPropertyPath(String(select)))
78 throw new Error(select + " column was not found in the " + metadata.name + " entity.");
79 qb.addSelect(qb.alias + "." + select);
80 });
81 }
82 if (options.where)
83 qb.where(options.where);
84 if (options.skip)
85 qb.skip(options.skip);
86 if (options.take)
87 qb.take(options.take);
88 if (options.order)
89 Object.keys(options.order).forEach(function (key) {
90 var order = options.order[key];
91 if (!metadata.findColumnWithPropertyPath(key))
92 throw new Error(key + " column was not found in the " + metadata.name + " entity.");
93 switch (order) {
94 case 1:
95 qb.addOrderBy(qb.alias + "." + key, "ASC");
96 break;
97 case -1:
98 qb.addOrderBy(qb.alias + "." + key, "DESC");
99 break;
100 case "ASC":
101 qb.addOrderBy(qb.alias + "." + key, "ASC");
102 break;
103 case "DESC":
104 qb.addOrderBy(qb.alias + "." + key, "DESC");
105 break;
106 }
107 });
108 if (options.relations) {
109 var allRelations = options.relations.map(function (relation) { return relation; });
110 this.applyRelationsRecursively(qb, allRelations, qb.expressionMap.mainAlias.name, qb.expressionMap.mainAlias.metadata, "");
111 // recursive removes found relations from allRelations array
112 // if there are relations left in this array it means those relations were not found in the entity structure
113 // so, we give an exception about not found relations
114 if (allRelations.length > 0)
115 throw new FindRelationsNotFoundError_1.FindRelationsNotFoundError(allRelations);
116 }
117 if (options.join) {
118 if (options.join.leftJoin)
119 Object.keys(options.join.leftJoin).forEach(function (key) {
120 qb.leftJoin(options.join.leftJoin[key], key);
121 });
122 if (options.join.innerJoin)
123 Object.keys(options.join.innerJoin).forEach(function (key) {
124 qb.innerJoin(options.join.innerJoin[key], key);
125 });
126 if (options.join.leftJoinAndSelect)
127 Object.keys(options.join.leftJoinAndSelect).forEach(function (key) {
128 qb.leftJoinAndSelect(options.join.leftJoinAndSelect[key], key);
129 });
130 if (options.join.innerJoinAndSelect)
131 Object.keys(options.join.innerJoinAndSelect).forEach(function (key) {
132 qb.innerJoinAndSelect(options.join.innerJoinAndSelect[key], key);
133 });
134 }
135 if (options.cache) {
136 if (options.cache instanceof Object) {
137 var cache = options.cache;
138 qb.cache(cache.id, cache.milliseconds);
139 }
140 else {
141 qb.cache(options.cache);
142 }
143 }
144 if (options.lock) {
145 if (options.lock.mode === "optimistic") {
146 qb.setLock(options.lock.mode, options.lock.version);
147 }
148 else if (options.lock.mode === "pessimistic_read" || options.lock.mode === "pessimistic_write" || options.lock.mode === "dirty_read") {
149 qb.setLock(options.lock.mode);
150 }
151 }
152 if (options.loadRelationIds === true) {
153 qb.loadAllRelationIds();
154 }
155 else if (options.loadRelationIds instanceof Object) {
156 qb.loadAllRelationIds(options.loadRelationIds);
157 }
158 return qb;
159 };
160 // -------------------------------------------------------------------------
161 // Protected Static Methods
162 // -------------------------------------------------------------------------
163 /**
164 * Adds joins for all relations and sub-relations of the given relations provided in the find options.
165 */
166 FindOptionsUtils.applyRelationsRecursively = function (qb, allRelations, alias, metadata, prefix) {
167 var _this = this;
168 // find all relations that match given prefix
169 var matchedBaseRelations = [];
170 if (prefix) {
171 var regexp_1 = new RegExp("^" + prefix.replace(".", "\\.") + "\\.");
172 matchedBaseRelations = allRelations
173 .filter(function (relation) { return relation.match(regexp_1); })
174 .map(function (relation) { return relation.replace(regexp_1, ""); })
175 .filter(function (relation) { return metadata.findRelationWithPropertyPath(relation); });
176 }
177 else {
178 matchedBaseRelations = allRelations.filter(function (relation) { return metadata.findRelationWithPropertyPath(relation); });
179 }
180 // go through all matched relations and add join for them
181 matchedBaseRelations.forEach(function (relation) {
182 // generate a relation alias
183 var relationAlias = alias + "__" + relation;
184 // shorten it if needed by the driver
185 if (qb.connection.driver.maxAliasLength && relationAlias.length > qb.connection.driver.maxAliasLength) {
186 relationAlias = StringUtils_1.shorten(relationAlias);
187 }
188 // add a join for the found relation
189 var selection = alias + "." + relation;
190 qb.leftJoinAndSelect(selection, relationAlias);
191 // join the eager relations of the found relation
192 var relMetadata = metadata.relations.find(function (metadata) { return metadata.propertyName === relation; });
193 if (relMetadata) {
194 _this.joinEagerRelations(qb, relationAlias, relMetadata.inverseEntityMetadata);
195 }
196 // remove added relations from the allRelations array, this is needed to find all not found relations at the end
197 allRelations.splice(allRelations.indexOf(prefix ? prefix + "." + relation : relation), 1);
198 // try to find sub-relations
199 var join = qb.expressionMap.joinAttributes.find(function (join) { return join.entityOrProperty === selection; });
200 _this.applyRelationsRecursively(qb, allRelations, join.alias.name, join.metadata, prefix ? prefix + "." + relation : relation);
201 });
202 };
203 FindOptionsUtils.joinEagerRelations = function (qb, alias, metadata) {
204 var _this = this;
205 metadata.eagerRelations.forEach(function (relation) {
206 var relationAlias = qb.connection.namingStrategy.eagerJoinRelationAlias(alias, relation.propertyPath);
207 qb.leftJoinAndSelect(alias + "." + relation.propertyPath, relationAlias);
208 _this.joinEagerRelations(qb, relationAlias, relation.inverseEntityMetadata);
209 });
210 };
211 return FindOptionsUtils;
212}());
213exports.FindOptionsUtils = FindOptionsUtils;
214
215//# sourceMappingURL=FindOptionsUtils.js.map