@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.0
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 +279 -363
- package/lib/relations/RelationDeleteOperation.js +16 -22
- package/lib/relations/RelationFindOperation.js +100 -133
- package/lib/relations/RelationInsertOperation.js +19 -27
- package/lib/relations/RelationOwner.js +167 -204
- package/lib/relations/RelationProperty.js +177 -217
- package/lib/relations/RelationUpdateOperation.js +16 -23
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
- package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
- package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
- package/lib/relations/hasMany/HasManyRelation.js +30 -38
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
- package/lib/relations/hasOne/HasOneRelation.js +4 -7
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
- package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
- 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,341 +1,258 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { uniqBy } = require('../../utils/objectUtils');
|
|
4
3
|
const { Selection } = require('../operations/select/Selection');
|
|
5
4
|
const { createModifier } = require('../../utils/createModifier');
|
|
6
5
|
const { map: mapPromise } = require('../../utils/promiseUtils');
|
|
6
|
+
const { getReadConcurrency } = require('../../model/modelConcurrency');
|
|
7
7
|
const { ValidationErrorType } = require('../../model/ValidationError');
|
|
8
|
-
|
|
9
8
|
const { TableTree } = require('./TableTree');
|
|
10
9
|
const { JoinResultParser } = require('./JoinResultParser');
|
|
11
10
|
const { ID_LENGTH_LIMIT } = require('./utils');
|
|
12
|
-
|
|
13
11
|
/**
|
|
14
12
|
* Given a relation expression, builds a query using joins to fetch it.
|
|
15
13
|
*/
|
|
16
14
|
class RelationJoiner {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
this.options = defaultOptions();
|
|
27
|
-
this.tableTree = null;
|
|
28
|
-
this.internalSelections = null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
setExpression(expression) {
|
|
32
|
-
if (!this.expression) {
|
|
33
|
-
this.expression = expression;
|
|
15
|
+
constructor({ modelClass }) {
|
|
16
|
+
this.rootModelClass = modelClass;
|
|
17
|
+
// The relation expression to join.
|
|
18
|
+
this.expression = null;
|
|
19
|
+
// Explicit modifiers for the relation expression.
|
|
20
|
+
this.modifiers = null;
|
|
21
|
+
this.options = defaultOptions();
|
|
22
|
+
this.tableTree = null;
|
|
23
|
+
this.internalSelections = null;
|
|
34
24
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!this.modifiers) {
|
|
41
|
-
this.modifiers = modifiers;
|
|
25
|
+
setExpression(expression) {
|
|
26
|
+
if (!this.expression) {
|
|
27
|
+
this.expression = expression;
|
|
28
|
+
}
|
|
29
|
+
return this;
|
|
42
30
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.options = Object.assign(this.options, options);
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Fetches the column information needed for building the select clauses.
|
|
54
|
-
*
|
|
55
|
-
* This must be called before calling `build(builder, true)`. `build(builder, false)`
|
|
56
|
-
* can be called without this since it doesn't build selects.
|
|
57
|
-
*/
|
|
58
|
-
fetchColumnInfo(builder) {
|
|
59
|
-
const tableTree = this._getTableTree(builder);
|
|
60
|
-
const allModelClasses = new Set(tableTree.nodes.map((node) => node.modelClass));
|
|
61
|
-
|
|
62
|
-
return mapPromise(
|
|
63
|
-
Array.from(allModelClasses),
|
|
64
|
-
(modelClass) => modelClass.fetchTableMetadata({ parentBuilder: builder }),
|
|
65
|
-
{
|
|
66
|
-
concurrency: this.rootModelClass.getConcurrency(builder.unsafeKnex()),
|
|
67
|
-
},
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
build(builder, buildSelects = true) {
|
|
72
|
-
const rootTableNode = this._getTableTree(builder).rootNode;
|
|
73
|
-
const userSelectQueries = new Map([[rootTableNode, builder]]);
|
|
74
|
-
|
|
75
|
-
for (const tableNode of rootTableNode.childNodes) {
|
|
76
|
-
this._buildJoinsForNode({ builder, tableNode, userSelectQueries });
|
|
31
|
+
setModifiers(modifiers) {
|
|
32
|
+
if (!this.modifiers) {
|
|
33
|
+
this.modifiers = modifiers;
|
|
34
|
+
}
|
|
35
|
+
return this;
|
|
77
36
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
37
|
+
setOptions(options) {
|
|
38
|
+
this.options = Object.assign(this.options, options);
|
|
39
|
+
return this;
|
|
81
40
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (!this.tableTree) {
|
|
95
|
-
// Create the table tree lazily.
|
|
96
|
-
this.tableTree = TableTree.create({
|
|
97
|
-
rootModelClass: this.rootModelClass,
|
|
98
|
-
rootTableAlias: builder.tableRef(),
|
|
99
|
-
expression: this.expression,
|
|
100
|
-
options: this.options,
|
|
101
|
-
});
|
|
41
|
+
/**
|
|
42
|
+
* Fetches the column information needed for building the select clauses.
|
|
43
|
+
*
|
|
44
|
+
* This must be called before calling `build(builder, true)`. `build(builder, false)`
|
|
45
|
+
* can be called without this since it doesn't build selects.
|
|
46
|
+
*/
|
|
47
|
+
fetchColumnInfo(builder) {
|
|
48
|
+
const tableTree = this._getTableTree(builder);
|
|
49
|
+
const allModelClasses = new Set(tableTree.nodes.map((node) => node.modelClass));
|
|
50
|
+
return mapPromise(Array.from(allModelClasses), (modelClass) => modelClass.fetchTableMetadata({ parentBuilder: builder }), {
|
|
51
|
+
concurrency: getReadConcurrency(this.rootModelClass, builder.unsafeKnex()),
|
|
52
|
+
});
|
|
102
53
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
const userSelectQuery = subqueryToJoin.clone();
|
|
115
|
-
|
|
116
|
-
// relation.join applies the relation modifier that can
|
|
117
|
-
// also contain selects.
|
|
118
|
-
userSelectQuery.modify(tableNode.relation.modify);
|
|
119
|
-
|
|
120
|
-
// Save the query that contains the user specified selects
|
|
121
|
-
// for later use.
|
|
122
|
-
userSelectQueries.set(tableNode, userSelectQuery);
|
|
123
|
-
|
|
124
|
-
tableNode.relation.join(builder, {
|
|
125
|
-
joinOperation: this.options.joinOperation,
|
|
126
|
-
|
|
127
|
-
ownerTable: tableNode.parentNode.alias,
|
|
128
|
-
relatedTableAlias: tableNode.alias,
|
|
129
|
-
joinTableAlias: tableNode.getJoinTableAlias(builder),
|
|
130
|
-
|
|
131
|
-
relatedJoinSelectQuery: ensureIdAndRelationPropsAreSelected({
|
|
132
|
-
builder: subqueryToJoin,
|
|
133
|
-
tableNode,
|
|
134
|
-
}),
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
for (const childNode of tableNode.childNodes) {
|
|
138
|
-
this._buildJoinsForNode({ builder, tableNode: childNode, userSelectQueries });
|
|
54
|
+
build(builder, buildSelects = true) {
|
|
55
|
+
const rootTableNode = this._getTableTree(builder).rootNode;
|
|
56
|
+
const userSelectQueries = new Map([[rootTableNode, builder]]);
|
|
57
|
+
for (const tableNode of rootTableNode.childNodes) {
|
|
58
|
+
this._buildJoinsForNode({ builder, tableNode, userSelectQueries });
|
|
59
|
+
}
|
|
60
|
+
if (buildSelects) {
|
|
61
|
+
this._buildSelects({ builder, tableNode: rootTableNode, userSelectQueries });
|
|
62
|
+
}
|
|
139
63
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
64
|
+
parseResult(builder, flatRows) {
|
|
65
|
+
const parser = JoinResultParser.create({
|
|
66
|
+
tableTree: this._getTableTree(builder),
|
|
67
|
+
omitColumnAliases: this.internalSelections.map((it) => it.alias),
|
|
68
|
+
});
|
|
69
|
+
return parser.parse(flatRows);
|
|
70
|
+
}
|
|
71
|
+
_getTableTree(builder) {
|
|
72
|
+
if (!this.tableTree) {
|
|
73
|
+
// Create the table tree lazily.
|
|
74
|
+
this.tableTree = TableTree.create({
|
|
75
|
+
rootModelClass: this.rootModelClass,
|
|
76
|
+
rootTableAlias: builder.tableRef(),
|
|
77
|
+
expression: this.expression,
|
|
78
|
+
options: this.options,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return this.tableTree;
|
|
82
|
+
}
|
|
83
|
+
_buildJoinsForNode({ builder, tableNode, userSelectQueries }) {
|
|
84
|
+
const subqueryToJoin = createSubqueryToJoin({
|
|
85
|
+
builder,
|
|
86
|
+
tableNode,
|
|
87
|
+
modifiers: this.modifiers,
|
|
88
|
+
});
|
|
89
|
+
const userSelectQuery = subqueryToJoin.clone();
|
|
90
|
+
// relation.join applies the relation modifier that can
|
|
91
|
+
// also contain selects.
|
|
92
|
+
userSelectQuery.modify(tableNode.relation.modify);
|
|
93
|
+
// Save the query that contains the user specified selects
|
|
94
|
+
// for later use.
|
|
95
|
+
userSelectQueries.set(tableNode, userSelectQuery);
|
|
96
|
+
tableNode.relation.join(builder, {
|
|
97
|
+
joinOperation: this.options.joinOperation,
|
|
98
|
+
ownerTable: tableNode.parentNode.alias,
|
|
99
|
+
relatedTableAlias: tableNode.alias,
|
|
100
|
+
joinTableAlias: tableNode.getJoinTableAlias(builder),
|
|
101
|
+
relatedJoinSelectQuery: ensureIdAndRelationPropsAreSelected({
|
|
102
|
+
builder: subqueryToJoin,
|
|
103
|
+
tableNode,
|
|
104
|
+
}),
|
|
105
|
+
});
|
|
106
|
+
for (const childNode of tableNode.childNodes) {
|
|
107
|
+
this._buildJoinsForNode({ builder, tableNode: childNode, userSelectQueries });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
_buildSelects({ builder, tableNode, userSelectQueries }) {
|
|
111
|
+
const { selections, internalSelections } = getSelectionsForNode({
|
|
112
|
+
builder,
|
|
113
|
+
tableNode,
|
|
114
|
+
userSelectQueries,
|
|
115
|
+
});
|
|
116
|
+
for (const selection of selections) {
|
|
117
|
+
checkAliasLength(tableNode.modelClass, selection.name);
|
|
118
|
+
}
|
|
119
|
+
// Save the selections that were added internally (not by the user)
|
|
120
|
+
// so that we can later remove the corresponding properties when
|
|
121
|
+
// parsing the result.
|
|
122
|
+
this.internalSelections = internalSelections;
|
|
123
|
+
builder.select(selectionsToStrings(selections));
|
|
151
124
|
}
|
|
152
|
-
|
|
153
|
-
// Save the selections that were added internally (not by the user)
|
|
154
|
-
// so that we can later remove the corresponding properties when
|
|
155
|
-
// parsing the result.
|
|
156
|
-
this.internalSelections = internalSelections;
|
|
157
|
-
|
|
158
|
-
builder.select(selectionsToStrings(selections));
|
|
159
|
-
}
|
|
160
125
|
}
|
|
161
|
-
|
|
162
126
|
function defaultOptions() {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
127
|
+
return {
|
|
128
|
+
joinOperation: 'leftJoin',
|
|
129
|
+
minimize: false,
|
|
130
|
+
separator: ':',
|
|
131
|
+
aliases: {},
|
|
132
|
+
};
|
|
169
133
|
}
|
|
170
|
-
|
|
171
134
|
function createSubqueryToJoin({ builder, tableNode, modifiers }) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
modifiers,
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
try {
|
|
183
|
-
modifier(modifierQuery);
|
|
184
|
-
} catch (err) {
|
|
185
|
-
if (err instanceof modelClass.ModifierNotFoundError) {
|
|
186
|
-
throw modelClass.createValidationError({
|
|
187
|
-
type: ValidationErrorType.RelationExpression,
|
|
188
|
-
message: `could not find modifier "${modifierName}" for relation "${relation.name}"`,
|
|
135
|
+
const { relation, expression, modelClass } = tableNode;
|
|
136
|
+
const modifierQuery = modelClass.query().childQueryOf(builder);
|
|
137
|
+
for (const modifierName of expression.node.$modify) {
|
|
138
|
+
const modifier = createModifier({
|
|
139
|
+
modifier: modifierName,
|
|
140
|
+
modelClass,
|
|
141
|
+
modifiers,
|
|
189
142
|
});
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
143
|
+
try {
|
|
144
|
+
modifier(modifierQuery);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
if (err instanceof modelClass.ModifierNotFoundError) {
|
|
148
|
+
throw modelClass.createValidationError({
|
|
149
|
+
type: ValidationErrorType.RelationExpression,
|
|
150
|
+
message: `could not find modifier "${modifierName}" for relation "${relation.name}"`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
throw err;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
193
157
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return modifierQuery;
|
|
158
|
+
return modifierQuery;
|
|
197
159
|
}
|
|
198
|
-
|
|
199
160
|
function ensureIdAndRelationPropsAreSelected({ builder, tableNode }) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const selectStrings = uniqBy(cols)
|
|
212
|
-
.filter((col) => !builder.hasSelectionAs(col, col))
|
|
213
|
-
.map((col) => `${tableRef}.${col}`);
|
|
214
|
-
|
|
215
|
-
return builder.select(selectStrings);
|
|
161
|
+
const tableRef = builder.tableRef();
|
|
162
|
+
const cols = [
|
|
163
|
+
...builder.modelClass().getIdColumnArray(),
|
|
164
|
+
...tableNode.relation.relatedProp.cols,
|
|
165
|
+
...tableNode.childNodes.reduce((cols, childNode) => [...cols, ...childNode.relation.ownerProp.cols], []),
|
|
166
|
+
];
|
|
167
|
+
const selectStrings = uniqBy(cols)
|
|
168
|
+
.filter((col) => !builder.hasSelectionAs(col, col))
|
|
169
|
+
.map((col) => `${tableRef}.${col}`);
|
|
170
|
+
return builder.select(selectStrings);
|
|
216
171
|
}
|
|
217
|
-
|
|
218
172
|
function getSelectionsForNode({ builder, tableNode, userSelectQueries }) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
173
|
+
const userSelectQuery = userSelectQueries.get(tableNode);
|
|
174
|
+
const userSelections = userSelectQuery.findAllSelections();
|
|
175
|
+
const userSelectedAllColumns = isSelectAllSelectionSet(userSelections);
|
|
176
|
+
let selections = [];
|
|
177
|
+
let internalSelections = [];
|
|
178
|
+
if (tableNode.parentNode) {
|
|
179
|
+
selections = mapUserSelectionsFromSubqueryToMainQuery({ userSelections, tableNode });
|
|
180
|
+
if (userSelectedAllColumns && tableNode.relation.isObjectionManyToManyRelation) {
|
|
181
|
+
const extraSelections = getJoinTableExtraSelectionsForNode({ builder, tableNode });
|
|
182
|
+
selections = selections.concat(extraSelections);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (userSelectedAllColumns) {
|
|
186
|
+
const allColumnSelections = getAllColumnSelectionsForNode({ builder, tableNode });
|
|
187
|
+
selections = allColumnSelections.concat(selections);
|
|
232
188
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
189
|
+
else {
|
|
190
|
+
const idSelections = getIdSelectionsForNode({ tableNode });
|
|
191
|
+
for (const idSelection of idSelections) {
|
|
192
|
+
if (!userSelectQuery.hasSelectionAs(idSelection.column, idSelection.column)) {
|
|
193
|
+
selections.push(idSelection);
|
|
194
|
+
internalSelections.push(idSelection);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
for (const childNode of tableNode.childNodes) {
|
|
199
|
+
const childResult = getSelectionsForNode({ builder, tableNode: childNode, userSelectQueries });
|
|
200
|
+
selections = selections.concat(childResult.selections);
|
|
201
|
+
internalSelections = internalSelections.concat(childResult.internalSelections);
|
|
246
202
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
selections = selections.concat(childResult.selections);
|
|
253
|
-
internalSelections = internalSelections.concat(childResult.internalSelections);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
selections,
|
|
258
|
-
internalSelections,
|
|
259
|
-
};
|
|
203
|
+
return {
|
|
204
|
+
selections,
|
|
205
|
+
internalSelections,
|
|
206
|
+
};
|
|
260
207
|
}
|
|
261
|
-
|
|
262
208
|
function mapUserSelectionsFromSubqueryToMainQuery({ userSelections, tableNode }) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
selection.name,
|
|
267
|
-
tableNode.getColumnAliasForColumn(selection.name),
|
|
268
|
-
);
|
|
269
|
-
});
|
|
209
|
+
return userSelections.filter(isNotSelectAll).map((selection) => {
|
|
210
|
+
return new Selection(tableNode.alias, selection.name, tableNode.getColumnAliasForColumn(selection.name));
|
|
211
|
+
});
|
|
270
212
|
}
|
|
271
|
-
|
|
272
213
|
function getJoinTableExtraSelectionsForNode({ builder, tableNode }) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
extra.joinTableCol,
|
|
277
|
-
tableNode.getColumnAliasForColumn(extra.aliasCol),
|
|
278
|
-
);
|
|
279
|
-
});
|
|
214
|
+
return tableNode.relation.joinTableExtras.map((extra) => {
|
|
215
|
+
return new Selection(tableNode.getJoinTableAlias(builder), extra.joinTableCol, tableNode.getColumnAliasForColumn(extra.aliasCol));
|
|
216
|
+
});
|
|
280
217
|
}
|
|
281
|
-
|
|
282
218
|
function getAllColumnSelectionsForNode({ builder, tableNode }) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return tableMeta.columns.map((columnName) => {
|
|
293
|
-
return new Selection(
|
|
294
|
-
tableNode.alias,
|
|
295
|
-
columnName,
|
|
296
|
-
tableNode.getColumnAliasForColumn(columnName),
|
|
297
|
-
);
|
|
298
|
-
});
|
|
219
|
+
const table = builder.tableNameFor(tableNode.modelClass);
|
|
220
|
+
const tableMeta = tableNode.modelClass.tableMetadata({ table });
|
|
221
|
+
if (!tableMeta) {
|
|
222
|
+
throw new Error(`table metadata has not been fetched for table '${table}'. Are you trying to call toKnexQuery() for a withGraphJoined query? To make sure the table metadata is fetched see the objection.initialize function.`);
|
|
223
|
+
}
|
|
224
|
+
return tableMeta.columns.map((columnName) => {
|
|
225
|
+
return new Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
|
|
226
|
+
});
|
|
299
227
|
}
|
|
300
|
-
|
|
301
228
|
function getIdSelectionsForNode({ tableNode }) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
columnName,
|
|
306
|
-
tableNode.getColumnAliasForColumn(columnName),
|
|
307
|
-
);
|
|
308
|
-
});
|
|
229
|
+
return tableNode.modelClass.getIdColumnArray().map((columnName) => {
|
|
230
|
+
return new Selection(tableNode.alias, columnName, tableNode.getColumnAliasForColumn(columnName));
|
|
231
|
+
});
|
|
309
232
|
}
|
|
310
|
-
|
|
311
233
|
function selectionsToStrings(selections) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
234
|
+
return selections.map((selection) => {
|
|
235
|
+
const selectStr = `${selection.table}.${selection.column}`;
|
|
236
|
+
return `${selectStr} as ${selection.alias}`;
|
|
237
|
+
});
|
|
316
238
|
}
|
|
317
|
-
|
|
318
239
|
function isSelectAll(selection) {
|
|
319
|
-
|
|
240
|
+
return selection.column === '*';
|
|
320
241
|
}
|
|
321
|
-
|
|
322
242
|
function isNotSelectAll(selection) {
|
|
323
|
-
|
|
243
|
+
return selection.column !== '*';
|
|
324
244
|
}
|
|
325
|
-
|
|
326
245
|
function isSelectAllSelectionSet(selections) {
|
|
327
|
-
|
|
246
|
+
return selections.length === 0 || selections.some(isSelectAll);
|
|
328
247
|
}
|
|
329
|
-
|
|
330
248
|
function checkAliasLength(modelClass, alias) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
249
|
+
if (alias.length > ID_LENGTH_LIMIT) {
|
|
250
|
+
throw modelClass.createValidationError({
|
|
251
|
+
type: ValidationErrorType.RelationExpression,
|
|
252
|
+
message: `identifier ${alias} is over ${ID_LENGTH_LIMIT} characters long and would be truncated by the database engine.`,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
337
255
|
}
|
|
338
|
-
|
|
339
256
|
module.exports = {
|
|
340
|
-
|
|
257
|
+
RelationJoiner,
|
|
341
258
|
};
|