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