@@ -5,7 +5,7 @@ const Bluebird = require('bluebird');
5
5
const { raw } = require ( './RawBuilder' ) ;
6
6
const { createModifier } = require ( '../utils/createModifier' ) ;
7
7
const { Type : ValidationErrorType } = require ( '../model/ValidationError' ) ;
8
- const { isObject, isString, isFunction, last } = require ( '../utils/objectUtils' ) ;
8
+ const { isObject, isString, isFunction, last, groupBy } = require ( '../utils/objectUtils' ) ;
9
9
const { RelationExpression, DuplicateRelationError } = require ( './RelationExpression' ) ;
10
10
const { Selection } = require ( './operations/select/Selection' ) ;
11
11
@@ -55,6 +55,7 @@ class QueryBuilder extends QueryBuilderBase {
55
55
this . _eagerModifiersAtPath = [ ] ;
56
56
this . _allowedEagerExpression = null ;
57
57
this . _allowedUpsertExpression = null ;
58
+ this . _joinRelations = [ ] ;
58
59
59
60
this . _findOperationOptions = modelClass . defaultFindOptions ;
60
61
this . _eagerOperationOptions = modelClass . defaultEagerOptions ;
@@ -383,6 +384,10 @@ class QueryBuilder extends QueryBuilderBase {
383
384
return ! ! this . _eagerExpression ;
384
385
}
385
386
387
+ hasJoinRelation ( ) {
388
+ return this . _joinRelations . length > 0 ;
389
+ }
390
+
386
391
isSelectAll ( ) {
387
392
if ( this . _operations . length === 0 ) {
388
393
return true ;
@@ -457,6 +462,7 @@ class QueryBuilder extends QueryBuilderBase {
457
462
458
463
builder . _findOperationOptions = this . _findOperationOptions ;
459
464
builder . _eagerOperationOptions = this . _eagerOperationOptions ;
465
+ builder . _joinRelations = this . _joinRelations . slice ( ) ;
460
466
461
467
builder . _findOperationFactory = this . _findOperationFactory ;
462
468
builder . _insertOperationFactory = this . _insertOperationFactory ;
@@ -558,6 +564,12 @@ class QueryBuilder extends QueryBuilderBase {
558
564
// Take a clone so that we don't modify this instance during build.
559
565
const builder = this . clone ( ) ;
560
566
567
+ if ( builder . hasJoinRelation ( ) ) {
568
+ // If there are some *joinRelation calls, merge the expressions
569
+ // and add the needed operations.
570
+ addJoinRelationOperations ( builder ) ;
571
+ }
572
+
561
573
if ( builder . isFind ( ) ) {
562
574
// If no write operations have been called at this point this query is a
563
575
// find query and we need to call the custom find implementation.
@@ -980,60 +992,60 @@ class QueryBuilder extends QueryBuilderBase {
980
992
return this . addOperation ( new FirstOperation ( 'first' ) , arguments ) ;
981
993
}
982
994
983
- joinRelation ( ) {
984
- return this . addOperation (
985
- new JoinRelationOperation ( 'joinRelation' , { joinOperation : 'join' } ) ,
986
- arguments
987
- ) ;
995
+ joinRelation ( ...args ) {
996
+ return this . innerJoinRelation ( ...args ) ;
988
997
}
989
998
990
- innerJoinRelation ( ) {
991
- return this . addOperation (
992
- new JoinRelationOperation ( 'innerJoinRelation' , { joinOperation : 'innerJoin' } ) ,
993
- arguments
994
- ) ;
999
+ innerJoinRelation ( expression , options ) {
1000
+ this . _joinRelations . push ( {
1001
+ joinOperation : 'innerJoin' ,
1002
+ expression,
1003
+ options
1004
+ } ) ;
1005
+
1006
+ return this ;
995
1007
}
996
1008
997
- outerJoinRelation ( ) {
998
- return this . addOperation (
999
- new JoinRelationOperation ( 'outerJoinRelation' , { joinOperation : 'outerJoin' } ) ,
1000
- arguments
1001
- ) ;
1009
+ outerJoinRelation ( expression , options ) {
1010
+ this . _joinRelations . push ( {
1011
+ joinOperation : 'outerJoin' ,
1012
+ expression,
1013
+ options
1014
+ } ) ;
1015
+
1016
+ return this ;
1002
1017
}
1003
1018
1004
- leftJoinRelation ( ) {
1005
- return this . addOperation (
1006
- new JoinRelationOperation ( 'leftJoinRelation' , { joinOperation : 'leftJoin' } ) ,
1007
- arguments
1008
- ) ;
1019
+ fullOuterJoinRelation ( ...args ) {
1020
+ return this . outerJoin ( ...args ) ;
1009
1021
}
1010
1022
1011
- leftOuterJoinRelation ( ) {
1012
- return this . addOperation (
1013
- new JoinRelationOperation ( 'leftOuterJoinRelation' , { joinOperation : 'leftOuterJoin' } ) ,
1014
- arguments
1015
- ) ;
1023
+ leftJoinRelation ( expression , options ) {
1024
+ this . _joinRelations . push ( {
1025
+ joinOperation : 'leftJoin' ,
1026
+ expression,
1027
+ options
1028
+ } ) ;
1029
+
1030
+ return this ;
1016
1031
}
1017
1032
1018
- rightJoinRelation ( ) {
1019
- return this . addOperation (
1020
- new JoinRelationOperation ( 'rightJoinRelation' , { joinOperation : 'rightJoin' } ) ,
1021
- arguments
1022
- ) ;
1033
+ leftOuterJoinRelation ( ...args ) {
1034
+ return this . leftJoinRelation ( ...args ) ;
1023
1035
}
1024
1036
1025
- rightOuterJoinRelation ( ) {
1026
- return this . addOperation (
1027
- new JoinRelationOperation ( 'rightOuterJoinRelation' , { joinOperation : 'rightOuterJoin' } ) ,
1028
- arguments
1029
- ) ;
1037
+ rightJoinRelation ( expression , options ) {
1038
+ this . _joinRelations . push ( {
1039
+ joinOperation : 'rightJoin' ,
1040
+ expression,
1041
+ options
1042
+ } ) ;
1043
+
1044
+ return this ;
1030
1045
}
1031
1046
1032
- fullOuterJoinRelation ( ) {
1033
- return this . addOperation (
1034
- new JoinRelationOperation ( 'fullOuterJoinRelation' , { joinOperation : 'fullOuterJoin' } ) ,
1035
- arguments
1036
- ) ;
1047
+ rightOuterJoinRelation ( ...args ) {
1048
+ return this . rightJoinRelation ( ...args ) ;
1037
1049
}
1038
1050
1039
1051
deleteById ( ) {
@@ -1144,6 +1156,12 @@ function findQueryExecutorOperation(builder) {
1144
1156
function beforeExecute ( builder ) {
1145
1157
let promise = Promise . resolve ( ) ;
1146
1158
1159
+ if ( builder . hasJoinRelation ( ) ) {
1160
+ // If there are some *joinRelation calls, merge the expressions
1161
+ // and add the needed operations.
1162
+ addJoinRelationOperations ( builder ) ;
1163
+ }
1164
+
1147
1165
if ( builder . isFind ( ) ) {
1148
1166
// If no write operations have been called at this point this query is a
1149
1167
// find query and we need to call the custom find implementation.
@@ -1251,6 +1269,16 @@ function handleExecuteError(builder, err) {
1251
1269
return promise ;
1252
1270
}
1253
1271
1272
+ function addJoinRelationOperations ( builder ) {
1273
+ if ( ! builder . has ( JoinRelationOperation ) ) {
1274
+ const callsGroupedByJoinOperation = groupBy ( builder . _joinRelations , call => call . joinOperation ) ;
1275
+
1276
+ callsGroupedByJoinOperation . forEach ( calls => {
1277
+ builder . addOperation ( new JoinRelationOperation ( ) , calls ) ;
1278
+ } ) ;
1279
+ }
1280
+ }
1281
+
1254
1282
function addFindOperation ( builder ) {
1255
1283
if ( ! builder . has ( FindOperation ) ) {
1256
1284
const operation = builder . _findOperationFactory ( builder ) ;
0 commit comments