@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.1
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.
- package/README.md +103 -67
- package/lib/index.mjs +6 -0
- package/lib/initialize.js +6 -9
- package/lib/model/AjvValidator.js +235 -282
- package/lib/model/Model.js +653 -823
- package/lib/model/ModifierNotFoundError.js +5 -7
- package/lib/model/NotFoundError.js +14 -18
- package/lib/model/RelationDoesNotExistError.js +6 -9
- package/lib/model/ValidationError.js +33 -41
- package/lib/model/Validator.js +15 -21
- package/lib/model/getModel.js +1 -3
- package/lib/model/graph/ModelGraph.js +44 -64
- package/lib/model/graph/ModelGraphBuilder.js +164 -217
- package/lib/model/graph/ModelGraphEdge.js +31 -43
- package/lib/model/graph/ModelGraphNode.js +192 -231
- package/lib/model/inheritModel.js +9 -18
- package/lib/model/modelBindKnex.js +48 -62
- package/lib/model/modelClone.js +79 -98
- package/lib/model/modelColPropMap.js +16 -26
- package/lib/model/modelConcurrency.js +24 -0
- package/lib/model/modelId.js +44 -49
- package/lib/model/modelJsonAttributes.js +56 -76
- package/lib/model/modelParseRelations.js +68 -67
- package/lib/model/modelQueryProps.js +76 -107
- package/lib/model/modelSet.js +92 -112
- package/lib/model/modelTableMetadata.js +60 -72
- package/lib/model/modelToJson.js +120 -150
- package/lib/model/modelUtils.js +30 -37
- package/lib/model/modelValidate.js +34 -42
- package/lib/model/modelValues.js +78 -91
- package/lib/model/modelVisitor.js +22 -29
- package/lib/objection.js +42 -67
- package/lib/queryBuilder/FunctionBuilder.js +231 -279
- package/lib/queryBuilder/InternalOptions.js +19 -24
- package/lib/queryBuilder/JoinBuilder.js +116 -149
- package/lib/queryBuilder/QueryBuilder.js +1009 -1271
- package/lib/queryBuilder/QueryBuilderBase.js +647 -865
- package/lib/queryBuilder/QueryBuilderContext.js +14 -21
- package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
- package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
- package/lib/queryBuilder/RawBuilder.js +58 -73
- package/lib/queryBuilder/ReferenceBuilder.js +232 -270
- package/lib/queryBuilder/RelationExpression.js +322 -380
- package/lib/queryBuilder/StaticHookArguments.js +94 -106
- package/lib/queryBuilder/ValueBuilder.js +100 -112
- package/lib/queryBuilder/expressions.js +86 -116
- package/lib/queryBuilder/functions/mysql.js +642 -697
- package/lib/queryBuilder/graph/GraphAction.js +44 -59
- package/lib/queryBuilder/graph/GraphData.js +7 -9
- package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
- package/lib/queryBuilder/graph/GraphOperation.js +16 -22
- package/lib/queryBuilder/graph/GraphOptions.js +143 -185
- package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
- package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
- package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
- package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
- package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
- package/lib/queryBuilder/join/JoinResultParser.js +88 -101
- package/lib/queryBuilder/join/RelationJoiner.js +205 -288
- package/lib/queryBuilder/join/TableNode.js +117 -144
- package/lib/queryBuilder/join/TableTree.js +60 -76
- package/lib/queryBuilder/join/utils.js +10 -16
- package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
- package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
- package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
- package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
- package/lib/queryBuilder/operations/FindOperation.js +114 -131
- package/lib/queryBuilder/operations/FirstOperation.js +14 -19
- package/lib/queryBuilder/operations/FromOperation.js +69 -88
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
- package/lib/queryBuilder/operations/InsertOperation.js +132 -165
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
- package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
- package/lib/queryBuilder/operations/KnexOperation.js +4 -7
- package/lib/queryBuilder/operations/MergeOperation.js +32 -45
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
- package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
- package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
- package/lib/queryBuilder/operations/RangeOperation.js +30 -40
- package/lib/queryBuilder/operations/RelateOperation.js +14 -21
- package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
- package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
- package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
- package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
- package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
- package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
- package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
- package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
- package/lib/queryBuilder/operations/select/Selection.js +94 -105
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
- package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
- package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
- package/lib/queryBuilder/transformations/index.js +3 -9
- package/lib/queryBuilder/whereScopes.js +158 -186
- package/lib/relations/Relation.js +293 -375
- package/lib/relations/RelationDeleteOperation.js +24 -28
- package/lib/relations/RelationFindOperation.js +108 -138
- package/lib/relations/RelationInsertOperation.js +24 -32
- package/lib/relations/RelationOwner.js +175 -209
- package/lib/relations/RelationProperty.js +186 -223
- package/lib/relations/RelationUpdateOperation.js +23 -29
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
- package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
- package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
- package/lib/relations/hasMany/HasManyRelation.js +38 -46
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
- package/lib/relations/hasOne/HasOneRelation.js +9 -12
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
- package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
- package/lib/transaction.js +53 -83
- package/lib/utils/assert.js +15 -21
- package/lib/utils/buildUtils.js +17 -19
- package/lib/utils/classUtils.js +7 -11
- package/lib/utils/cloneDeep.js +365 -0
- package/lib/utils/createModifier.js +36 -41
- package/lib/utils/deprecate.js +8 -12
- package/lib/utils/identifierMapping.js +153 -192
- package/lib/utils/internalPropUtils.js +4 -8
- package/lib/utils/knexUtils.js +61 -56
- package/lib/utils/mixin.js +16 -23
- package/lib/utils/mysqlJsonPath.js +55 -40
- package/lib/utils/normalizeIds.js +110 -127
- package/lib/utils/objectUtils.js +236 -338
- package/lib/utils/parseFieldExpression.js +66 -44
- package/lib/utils/postgresJsonPath.js +48 -62
- package/lib/utils/promiseUtils/after.js +10 -13
- package/lib/utils/promiseUtils/afterReturn.js +10 -13
- package/lib/utils/promiseUtils/index.js +15 -17
- package/lib/utils/promiseUtils/isPromise.js +6 -9
- package/lib/utils/promiseUtils/map.js +75 -89
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
- package/lib/utils/promiseUtils/try.js +15 -18
- package/lib/utils/resolveModel.js +91 -94
- package/lib/utils/tmpColumnUtils.js +4 -13
- package/package.json +50 -23
- package/typings/objection/index.d.mts +362 -0
- package/typings/objection/index.d.ts +36 -9
- package/lib/.eslintrc.json +0 -8
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
- package/lib/utils/clone.js +0 -2329
|
@@ -1,431 +1,373 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const parser = require('./parsers/relationExpressionParser');
|
|
4
3
|
const { isObject, isNumber, isString, union } = require('../utils/objectUtils');
|
|
5
4
|
const { RelationDoesNotExistError } = require('../model/RelationDoesNotExistError');
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
class RelationExpressionParseError extends Error {
|
|
6
|
+
}
|
|
8
7
|
class DuplicateRelationError extends RelationExpressionParseError {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
constructor(relationName) {
|
|
9
|
+
super();
|
|
10
|
+
this.relationName = relationName;
|
|
11
|
+
}
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
class RelationExpression {
|
|
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
|
-
|
|
14
|
+
constructor(node = newNode(), recursionDepth = 0) {
|
|
15
|
+
this.node = node;
|
|
16
|
+
this.recursionDepth = recursionDepth;
|
|
17
|
+
}
|
|
18
|
+
// Create a relation expression from a string, a pojo or another
|
|
19
|
+
// RelationExpression instance.
|
|
20
|
+
static create(expr) {
|
|
21
|
+
if (isObject(expr)) {
|
|
22
|
+
if (expr.isObjectionRelationExpression) {
|
|
23
|
+
return expr;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return new RelationExpression(normalizeNode(expr));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (isString(expr)) {
|
|
30
|
+
if (expr.trim().length === 0) {
|
|
31
|
+
return new RelationExpression();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
try {
|
|
35
|
+
return new RelationExpression(parse(expr));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err.duplicateRelationName) {
|
|
39
|
+
throw new DuplicateRelationError(err.duplicateRelationName);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
throw new RelationExpressionParseError(err.message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return new RelationExpression();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Create a relation expression from a model graph.
|
|
52
|
+
static fromModelGraph(graph) {
|
|
53
|
+
if (!graph) {
|
|
54
|
+
return new RelationExpression();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return new RelationExpression(modelGraphToNode(graph, newNode()));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
get maxRecursionDepth() {
|
|
61
|
+
if (isNumber(this.node.$recursive)) {
|
|
62
|
+
return this.node.$recursive;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
return this.node.$recursive ? Number.MAX_SAFE_INTEGER : 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
get numChildren() {
|
|
69
|
+
return this.node.$childNames.length;
|
|
70
|
+
}
|
|
71
|
+
get isEmpty() {
|
|
72
|
+
return this.numChildren === 0;
|
|
73
|
+
}
|
|
74
|
+
// Merges this relation expression with another. `expr` can be a string,
|
|
75
|
+
// a pojo, or a RelationExpression instance.
|
|
76
|
+
merge(expr) {
|
|
77
|
+
expr = RelationExpression.create(expr);
|
|
78
|
+
if (this.isEmpty) {
|
|
79
|
+
// Nothing to merge.
|
|
80
|
+
return expr;
|
|
81
|
+
}
|
|
82
|
+
return new RelationExpression(mergeNodes(this.node, expr.node));
|
|
83
|
+
}
|
|
84
|
+
// Returns true if `expr` is contained by this expression. For example
|
|
85
|
+
// `a.b` is contained by `a.[b, c]`.
|
|
86
|
+
isSubExpression(expr) {
|
|
87
|
+
expr = RelationExpression.create(expr);
|
|
88
|
+
if (this.node.$allRecursive) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
if (expr.node.$allRecursive) {
|
|
92
|
+
return this.node.$allRecursive;
|
|
42
93
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return new RelationExpression();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Create a relation expression from a model graph.
|
|
50
|
-
static fromModelGraph(graph) {
|
|
51
|
-
if (!graph) {
|
|
52
|
-
return new RelationExpression();
|
|
53
|
-
} else {
|
|
54
|
-
return new RelationExpression(modelGraphToNode(graph, newNode()));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get maxRecursionDepth() {
|
|
59
|
-
if (isNumber(this.node.$recursive)) {
|
|
60
|
-
return this.node.$recursive;
|
|
61
|
-
} else {
|
|
62
|
-
return this.node.$recursive ? Number.MAX_SAFE_INTEGER : 0;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get numChildren() {
|
|
67
|
-
return this.node.$childNames.length;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get isEmpty() {
|
|
71
|
-
return this.numChildren === 0;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Merges this relation expression with another. `expr` can be a string,
|
|
75
|
-
// a pojo, or a RelationExpression instance.
|
|
76
|
-
merge(expr) {
|
|
77
|
-
expr = RelationExpression.create(expr);
|
|
78
|
-
|
|
79
|
-
if (this.isEmpty) {
|
|
80
|
-
// Nothing to merge.
|
|
81
|
-
return expr;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return new RelationExpression(mergeNodes(this.node, expr.node));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Returns true if `expr` is contained by this expression. For example
|
|
88
|
-
// `a.b` is contained by `a.[b, c]`.
|
|
89
|
-
isSubExpression(expr) {
|
|
90
|
-
expr = RelationExpression.create(expr);
|
|
91
|
-
|
|
92
|
-
if (this.node.$allRecursive) {
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (expr.node.$allRecursive) {
|
|
97
|
-
return this.node.$allRecursive;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (this.node.$relation !== expr.node.$relation) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const maxRecursionDepth = expr.maxRecursionDepth;
|
|
105
|
-
|
|
106
|
-
if (maxRecursionDepth > 0) {
|
|
107
|
-
return this.node.$allRecursive || this.maxRecursionDepth >= maxRecursionDepth;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
for (const childName of expr.node.$childNames) {
|
|
111
|
-
const ownSubExpression = this.childExpression(childName);
|
|
112
|
-
const subExpression = expr.childExpression(childName);
|
|
113
|
-
|
|
114
|
-
if (!ownSubExpression || !ownSubExpression.isSubExpression(subExpression)) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Returns a RelationExpression for a child node or null if there
|
|
123
|
-
// is no child with the given name `childName`.
|
|
124
|
-
childExpression(childName) {
|
|
125
|
-
if (
|
|
126
|
-
this.node.$allRecursive ||
|
|
127
|
-
(childName === this.node.$name && this.recursionDepth < this.maxRecursionDepth - 1)
|
|
128
|
-
) {
|
|
129
|
-
return new RelationExpression(this.node, this.recursionDepth + 1);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const child = this.node[childName];
|
|
133
|
-
|
|
134
|
-
if (child) {
|
|
135
|
-
return new RelationExpression(child);
|
|
136
|
-
} else {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Loops throught all first level children.
|
|
142
|
-
forEachChildExpression(modelClass, cb) {
|
|
143
|
-
const maxRecursionDepth = this.maxRecursionDepth;
|
|
144
|
-
|
|
145
|
-
if (this.node.$allRecursive) {
|
|
146
|
-
for (const relationName of modelClass.getRelationNames()) {
|
|
147
|
-
const node = newNode(relationName, true);
|
|
148
|
-
const relation = modelClass.getRelationUnsafe(relationName);
|
|
149
|
-
const childExpr = new RelationExpression(node);
|
|
150
|
-
|
|
151
|
-
cb(childExpr, relation);
|
|
152
|
-
}
|
|
153
|
-
} else if (this.recursionDepth < maxRecursionDepth - 1) {
|
|
154
|
-
const relation = modelClass.getRelationUnsafe(this.node.$relation) || null;
|
|
155
|
-
const childExpr = new RelationExpression(this.node, this.recursionDepth + 1);
|
|
156
|
-
|
|
157
|
-
cb(childExpr, relation);
|
|
158
|
-
} else if (maxRecursionDepth === 0) {
|
|
159
|
-
for (const childName of this.node.$childNames) {
|
|
160
|
-
const node = this.node[childName];
|
|
161
|
-
const relation = modelClass.getRelationUnsafe(node.$relation);
|
|
162
|
-
|
|
163
|
-
if (!relation) {
|
|
164
|
-
throw new RelationDoesNotExistError(node.$relation);
|
|
94
|
+
if (this.node.$relation !== expr.node.$relation) {
|
|
95
|
+
return false;
|
|
165
96
|
}
|
|
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
|
-
|
|
97
|
+
const maxRecursionDepth = expr.maxRecursionDepth;
|
|
98
|
+
if (maxRecursionDepth > 0) {
|
|
99
|
+
return this.node.$allRecursive || this.maxRecursionDepth >= maxRecursionDepth;
|
|
100
|
+
}
|
|
101
|
+
for (const childName of expr.node.$childNames) {
|
|
102
|
+
const ownSubExpression = this.childExpression(childName);
|
|
103
|
+
const subExpression = expr.childExpression(childName);
|
|
104
|
+
if (!ownSubExpression || !ownSubExpression.isSubExpression(subExpression)) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
// Returns a RelationExpression for a child node or null if there
|
|
111
|
+
// is no child with the given name `childName`.
|
|
112
|
+
childExpression(childName) {
|
|
113
|
+
if (this.node.$allRecursive ||
|
|
114
|
+
(childName === this.node.$name && this.recursionDepth < this.maxRecursionDepth - 1)) {
|
|
115
|
+
return new RelationExpression(this.node, this.recursionDepth + 1);
|
|
116
|
+
}
|
|
117
|
+
const child = this.node[childName];
|
|
118
|
+
if (child) {
|
|
119
|
+
return new RelationExpression(child);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Loops throught all first level children.
|
|
126
|
+
forEachChildExpression(modelClass, cb) {
|
|
127
|
+
const maxRecursionDepth = this.maxRecursionDepth;
|
|
128
|
+
if (this.node.$allRecursive) {
|
|
129
|
+
for (const relationName of modelClass.getRelationNames()) {
|
|
130
|
+
const node = newNode(relationName, true);
|
|
131
|
+
const relation = modelClass.getRelationUnsafe(relationName);
|
|
132
|
+
const childExpr = new RelationExpression(node);
|
|
133
|
+
cb(childExpr, relation);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (this.recursionDepth < maxRecursionDepth - 1) {
|
|
137
|
+
const relation = modelClass.getRelationUnsafe(this.node.$relation) || null;
|
|
138
|
+
const childExpr = new RelationExpression(this.node, this.recursionDepth + 1);
|
|
139
|
+
cb(childExpr, relation);
|
|
140
|
+
}
|
|
141
|
+
else if (maxRecursionDepth === 0) {
|
|
142
|
+
for (const childName of this.node.$childNames) {
|
|
143
|
+
const node = this.node[childName];
|
|
144
|
+
const relation = modelClass.getRelationUnsafe(node.$relation);
|
|
145
|
+
if (!relation) {
|
|
146
|
+
throw new RelationDoesNotExistError(node.$relation);
|
|
147
|
+
}
|
|
148
|
+
const childExpr = new RelationExpression(node);
|
|
149
|
+
cb(childExpr, relation);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
expressionsAtPath(path) {
|
|
154
|
+
return findExpressionsAtPath(this, RelationExpression.create(path), []);
|
|
155
|
+
}
|
|
156
|
+
clone() {
|
|
157
|
+
return new RelationExpression(cloneNode(this.node), this.recursionDepth);
|
|
158
|
+
}
|
|
159
|
+
toString() {
|
|
160
|
+
return toString(this.node);
|
|
161
|
+
}
|
|
162
|
+
toPojo() {
|
|
163
|
+
return cloneNode(this.node);
|
|
164
|
+
}
|
|
165
|
+
toJSON() {
|
|
166
|
+
return this.toPojo();
|
|
167
|
+
}
|
|
193
168
|
}
|
|
194
|
-
|
|
195
169
|
const parseCache = new Map();
|
|
196
170
|
function parse(str) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
171
|
+
const cachedNode = parseCache.get(str);
|
|
172
|
+
if (cachedNode) {
|
|
173
|
+
return cloneNode(cachedNode);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const node = parser.parse(str);
|
|
177
|
+
parseCache.set(str, cloneNode(node));
|
|
178
|
+
return node;
|
|
179
|
+
}
|
|
206
180
|
}
|
|
207
|
-
|
|
208
181
|
// All enumerable properties of a node that don't start with `$`
|
|
209
182
|
// are child nodes.
|
|
210
183
|
function getChildNames(node) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return childNames;
|
|
184
|
+
if (!node) {
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
const childNames = [];
|
|
188
|
+
for (const key of Object.keys(node)) {
|
|
189
|
+
if (key[0] !== '$') {
|
|
190
|
+
childNames.push(key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return childNames;
|
|
224
194
|
}
|
|
225
|
-
|
|
226
195
|
function toString(node) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
196
|
+
const childNames = node.$childNames;
|
|
197
|
+
let childExpr = childNames.map((childName) => node[childName]).map(toString);
|
|
198
|
+
let str = node.$relation;
|
|
199
|
+
if (node.$recursive) {
|
|
200
|
+
if (isNumber(node.$recursive)) {
|
|
201
|
+
str += '.^' + node.$recursive;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
str += '.^';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (node.$allRecursive) {
|
|
208
|
+
str += '.*';
|
|
209
|
+
}
|
|
210
|
+
if (childExpr.length > 1) {
|
|
211
|
+
childExpr = `[${childExpr.join(', ')}]`;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
childExpr = childExpr[0];
|
|
215
|
+
}
|
|
216
|
+
if (node.$modify.length) {
|
|
217
|
+
str += `(${node.$modify.join(', ')})`;
|
|
218
|
+
}
|
|
219
|
+
if (node.$name !== node.$relation) {
|
|
220
|
+
str += ` as ${node.$name}`;
|
|
221
|
+
}
|
|
222
|
+
if (childExpr) {
|
|
223
|
+
if (str) {
|
|
224
|
+
return `${str}.${childExpr}`;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return childExpr;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return str;
|
|
232
|
+
}
|
|
265
233
|
}
|
|
266
|
-
|
|
267
234
|
function cloneNode(node) {
|
|
268
|
-
|
|
235
|
+
return normalizeNode(node);
|
|
269
236
|
}
|
|
270
|
-
|
|
271
237
|
function modelGraphToNode(models, node) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
return node;
|
|
238
|
+
if (!models) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (Array.isArray(models)) {
|
|
242
|
+
for (let i = 0, l = models.length; i < l; ++i) {
|
|
243
|
+
modelToNode(models[i], node);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
modelToNode(models, node);
|
|
248
|
+
}
|
|
249
|
+
return node;
|
|
285
250
|
}
|
|
286
|
-
|
|
287
251
|
function modelToNode(model, node) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
modelGraphToNode(model[relName], childNode);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
252
|
+
const modelClass = model.constructor;
|
|
253
|
+
const relationNames = modelClass.getRelationNames();
|
|
254
|
+
for (let r = 0, lr = relationNames.length; r < lr; ++r) {
|
|
255
|
+
const relName = relationNames[r];
|
|
256
|
+
if (model[relName] !== undefined) {
|
|
257
|
+
let childNode = node[relName];
|
|
258
|
+
if (!childNode) {
|
|
259
|
+
childNode = newNode(relName);
|
|
260
|
+
node[relName] = childNode;
|
|
261
|
+
node.$childNames.push(relName);
|
|
262
|
+
}
|
|
263
|
+
modelGraphToNode(model[relName], childNode);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
306
266
|
}
|
|
307
|
-
|
|
308
267
|
function newNode(name = null, allRecusive = false) {
|
|
309
|
-
|
|
268
|
+
return normalizeNode(null, name, allRecusive);
|
|
310
269
|
}
|
|
311
|
-
|
|
312
270
|
function normalizeNode(node = null, name = null, allRecusive = false) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return normalized;
|
|
271
|
+
const normalized = {
|
|
272
|
+
$name: normalizeName(node, name),
|
|
273
|
+
$relation: normalizeRelation(node, name),
|
|
274
|
+
$modify: normalizeModify(node),
|
|
275
|
+
$recursive: normalizeRecursive(node),
|
|
276
|
+
$allRecursive: normalizeAllRecursive(node, allRecusive),
|
|
277
|
+
$childNames: normalizeChildNames(node),
|
|
278
|
+
};
|
|
279
|
+
for (const childName of normalized.$childNames) {
|
|
280
|
+
const childNode = node[childName];
|
|
281
|
+
if (isObject(childNode) || childNode === true) {
|
|
282
|
+
normalized[childName] = normalizeNode(childNode, childName);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return normalized;
|
|
331
286
|
}
|
|
332
|
-
|
|
333
287
|
function normalizeName(node, name) {
|
|
334
|
-
|
|
288
|
+
return (node && node.$name) || name || null;
|
|
335
289
|
}
|
|
336
|
-
|
|
337
290
|
function normalizeRelation(node, name) {
|
|
338
|
-
|
|
291
|
+
return (node && node.$relation) || name || null;
|
|
339
292
|
}
|
|
340
|
-
|
|
341
293
|
function normalizeModify(node) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return Array.isArray(node.$modify) ? node.$modify.slice() : [node.$modify];
|
|
294
|
+
if (!node || !node.$modify) {
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
return Array.isArray(node.$modify) ? node.$modify.slice() : [node.$modify];
|
|
347
298
|
}
|
|
348
|
-
|
|
349
299
|
function normalizeRecursive(node) {
|
|
350
|
-
|
|
300
|
+
return (node && node.$recursive) || false;
|
|
351
301
|
}
|
|
352
|
-
|
|
353
302
|
function normalizeAllRecursive(node, allRecusive) {
|
|
354
|
-
|
|
303
|
+
return (node && node.$allRecursive) || allRecusive || false;
|
|
355
304
|
}
|
|
356
|
-
|
|
357
305
|
function normalizeChildNames(node) {
|
|
358
|
-
|
|
306
|
+
return (node && node.$childNames && node.$childNames.slice()) || getChildNames(node);
|
|
359
307
|
}
|
|
360
|
-
|
|
361
308
|
function findExpressionsAtPath(target, path, results) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
return results;
|
|
309
|
+
if (path.node.$childNames.length == 0) {
|
|
310
|
+
// Path leaf reached, add target node to result set.
|
|
311
|
+
results.push(target);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
for (const childName of path.node.$childNames) {
|
|
315
|
+
const pathChild = path.childExpression(childName);
|
|
316
|
+
const targetChild = target.childExpression(childName);
|
|
317
|
+
if (targetChild) {
|
|
318
|
+
findExpressionsAtPath(targetChild, pathChild, results);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return results;
|
|
377
323
|
}
|
|
378
|
-
|
|
379
324
|
function mergeNodes(node1, node2) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
return node;
|
|
325
|
+
const node = {
|
|
326
|
+
$name: node1.$name,
|
|
327
|
+
$relation: node1.$relation,
|
|
328
|
+
$modify: union(node1.$modify, node2.$modify),
|
|
329
|
+
$recursive: mergeRecursion(node1.$recursive, node2.$recursive),
|
|
330
|
+
$allRecursive: node1.$allRecursive || node2.$allRecursive,
|
|
331
|
+
$childNames: null,
|
|
332
|
+
};
|
|
333
|
+
if (!node.$recursive && !node.$allRecursive) {
|
|
334
|
+
node.$childNames = union(node1.$childNames, node2.$childNames);
|
|
335
|
+
for (const childName of node.$childNames) {
|
|
336
|
+
const child1 = node1[childName];
|
|
337
|
+
const child2 = node2[childName];
|
|
338
|
+
if (child1 && child2) {
|
|
339
|
+
node[childName] = mergeNodes(child1, child2);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
node[childName] = child1 || child2;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
node.$childNames = [];
|
|
348
|
+
}
|
|
349
|
+
return node;
|
|
407
350
|
}
|
|
408
|
-
|
|
409
351
|
function mergeRecursion(rec1, rec2) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
352
|
+
if (rec1 === true || rec2 === true) {
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
else if (isNumber(rec1) && isNumber(rec2)) {
|
|
356
|
+
return Math.max(rec1, rec2);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
return rec1 || rec2;
|
|
360
|
+
}
|
|
417
361
|
}
|
|
418
|
-
|
|
419
362
|
Object.defineProperties(RelationExpression.prototype, {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
363
|
+
isObjectionRelationExpression: {
|
|
364
|
+
enumerable: false,
|
|
365
|
+
writable: false,
|
|
366
|
+
value: true,
|
|
367
|
+
},
|
|
425
368
|
});
|
|
426
|
-
|
|
427
369
|
module.exports = {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
370
|
+
RelationExpression,
|
|
371
|
+
RelationExpressionParseError,
|
|
372
|
+
DuplicateRelationError,
|
|
431
373
|
};
|