@@ -47,10 +47,10 @@ module.exports =
4747
4848 'use strict' ;
4949
50- var _createClass = ( function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ) ( ) ;
51-
5250 var _slicedToArray = ( function ( ) { function sliceIterator ( arr , i ) { var _arr = [ ] ; var _n = true ; var _d = false ; var _e = undefined ; try { for ( var _i = arr [ Symbol . iterator ] ( ) , _s ; ! ( _n = ( _s = _i . next ( ) ) . done ) ; _n = true ) { _arr . push ( _s . value ) ; if ( i && _arr . length === i ) break ; } } catch ( err ) { _d = true ; _e = err ; } finally { try { if ( ! _n && _i [ "return" ] ) _i [ "return" ] ( ) ; } finally { if ( _d ) throw _e ; } } return _arr ; } return function ( arr , i ) { if ( Array . isArray ( arr ) ) { return arr ; } else if ( Symbol . iterator in Object ( arr ) ) { return sliceIterator ( arr , i ) ; } else { throw new TypeError ( "Invalid attempt to destructure non-iterable instance" ) ; } } ; } ) ( ) ;
5351
52+ var _createClass = ( function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ) ( ) ;
53+
5454 function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
5555
5656 function _defineProperty ( obj , key , value ) { if ( key in obj ) { Object . defineProperty ( obj , key , { value : value , enumerable : true , configurable : true , writable : true } ) ; } else { obj [ key ] = value ; } return obj ; }
@@ -68,66 +68,6 @@ module.exports =
6868 return resourceConfig . table || underscore ( resourceConfig . name ) ;
6969 }
7070
71- /**
72- * Lookup and apply table joins to query if field contains a `.`
73- * @param {string } field - Field defined in where filter
74- * @param {object } query - knex query to modify
75- * @param {object } resourceConfig - Resource of primary query/table
76- * @param {string[] } existingJoins - Array of fully qualitifed field names for
77- * any existing table joins for query
78- * @returns {string } - field updated to perspective of applied joins
79- */
80- function applyTableJoins ( field , query , resourceConfig , existingJoins ) {
81- if ( DSUtils . contains ( field , '.' ) ) {
82- ( function ( ) {
83- var parts = field . split ( '.' ) ;
84- var localResourceConfig = resourceConfig ;
85-
86- var relationPath = [ ] ;
87-
88- var _loop = function _loop ( ) {
89- var relationName = parts . shift ( ) ;
90- var relationResourceConfig = resourceConfig . getResource ( relationName ) ;
91- relationPath . push ( relationName ) ;
92-
93- if ( ! existingJoins . some ( function ( t ) {
94- return t === relationPath . join ( '.' ) ;
95- } ) ) {
96- var _localResourceConfig$ = localResourceConfig . relationList . filter ( function ( r ) {
97- return r . relation === relationName ;
98- } ) ;
99-
100- var _localResourceConfig$2 = _slicedToArray ( _localResourceConfig$ , 1 ) ;
101-
102- var relation = _localResourceConfig$2 [ 0 ] ;
103-
104- if ( relation ) {
105- var table = getTable ( localResourceConfig ) ;
106- var localId = table + '.' + relation . localKey ;
107-
108- var relationTable = getTable ( relationResourceConfig ) ;
109- var foreignId = relationTable + '.' + relationResourceConfig . idAttribute ;
110-
111- query . join ( relationTable , localId , foreignId ) ;
112- existingJoins . push ( relationPath . join ( '.' ) ) ;
113- } else {
114- // hopefully a qualified local column
115- }
116- }
117- localResourceConfig = relationResourceConfig ;
118- } ;
119-
120- while ( parts . length >= 2 ) {
121- _loop ( ) ;
122- }
123-
124- field = getTable ( localResourceConfig ) + '.' + parts [ 0 ] ;
125- } ) ( ) ;
126- }
127-
128- return field ;
129- }
130-
13171 function loadWithRelations ( items , resourceConfig , options ) {
13272 var _this = this ;
13373
@@ -198,12 +138,12 @@ module.exports =
198138
199139 if ( instance ) {
200140 var itemKeys = instance [ def . localKeys ] || [ ] ;
201- itemKeys = Array . isArray ( itemKeys ) ? itemKeys : DSUtils . keys ( itemKeys ) ;
141+ itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys ) ;
202142 localKeys = localKeys . concat ( itemKeys || [ ] ) ;
203143 } else {
204144 DSUtils . forEach ( items , function ( item ) {
205145 var itemKeys = item [ def . localKeys ] || [ ] ;
206- itemKeys = Array . isArray ( itemKeys ) ? itemKeys : DSUtils . keys ( itemKeys ) ;
146+ itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys ) ;
207147 localKeys = localKeys . concat ( itemKeys || [ ] ) ;
208148 } ) ;
209149 }
@@ -296,7 +236,7 @@ module.exports =
296236 var query = options && options . transaction || this . query ;
297237 return query . select ( '*' ) . from ( getTable ( resourceConfig ) ) . where ( resourceConfig . idAttribute , toString ( id ) ) . then ( function ( rows ) {
298238 if ( ! rows . length ) {
299- return DSUtils . Promise . reject ( new Error ( 'Not Found!' ) ) ;
239+ return Promise . reject ( new Error ( 'Not Found!' ) ) ;
300240 } else {
301241 instance = rows [ 0 ] ;
302242 return loadWithRelations . call ( _this2 , instance , resourceConfig , options ) ;
@@ -386,7 +326,10 @@ module.exports =
386326 } , {
387327 key : 'filterQuery' ,
388328 value : function filterQuery ( resourceConfig , params , options ) {
329+ var _this7 = this ;
330+
389331 var table = getTable ( resourceConfig ) ;
332+ var joinedTables = [ ] ;
390333 var query = undefined ;
391334
392335 if ( params instanceof Object . getPrototypeOf ( this . query . client ) . QueryBuilder ) {
@@ -404,9 +347,7 @@ module.exports =
404347 params . orderBy = params . orderBy || params . sort ;
405348 params . skip = params . skip || params . offset ;
406349
407- var joinedTables = [ ] ;
408-
409- DSUtils . forEach ( DSUtils . keys ( params ) , function ( k ) {
350+ DSUtils . forEach ( Object . keys ( params ) , function ( k ) {
410351 var v = params [ k ] ;
411352 if ( ! DSUtils . contains ( reserved , k ) ) {
412353 if ( DSUtils . isObject ( v ) ) {
@@ -428,19 +369,82 @@ module.exports =
428369 } ;
429370 }
430371
431- DSUtils . forOwn ( criteria , function ( v , op ) {
432- // Apply table joins (if needed)
372+ var processRelationField = function processRelationField ( field ) {
373+ var parts = field . split ( '.' ) ;
374+ var localResourceConfig = resourceConfig ;
375+ var relationPath = [ ] ;
376+
377+ var _loop = function _loop ( ) {
378+ var relationName = parts . shift ( ) ;
379+
380+ var _localResourceConfig$ = localResourceConfig . relationList . filter ( function ( r ) {
381+ return r . relation === relationName || r . localField === relationName ;
382+ } ) ;
383+
384+ var _localResourceConfig$2 = _slicedToArray ( _localResourceConfig$ , 1 ) ;
385+
386+ var relation = _localResourceConfig$2 [ 0 ] ;
387+
388+ if ( relation ) {
389+ var relationResourceConfig = resourceConfig . getResource ( relation . relation ) ;
390+ relationPath . push ( relation . relation ) ;
391+
392+ if ( relation . type === 'belongsTo' || relation . type === 'hasOne' ) {
393+ // Apply table join for belongsTo/hasOne property (if not done already)
394+ if ( ! joinedTables . some ( function ( t ) {
395+ return t === relationPath . join ( '.' ) ;
396+ } ) ) {
397+ var _table = getTable ( localResourceConfig ) ;
398+ var localId = _table + '.' + relation . localKey ;
399+
400+ var relationTable = getTable ( relationResourceConfig ) ;
401+ var foreignId = relationTable + '.' + relationResourceConfig . idAttribute ;
402+
403+ query . join ( relationTable , localId , foreignId ) ;
404+ joinedTables . push ( relationPath . join ( '.' ) ) ;
405+ }
406+ } else if ( relation . type === 'hasMany' ) {
407+ var _existsParams ;
408+
409+ // Perform `WHERE EXISTS` subquery for hasMany property
410+ var _table2 = getTable ( localResourceConfig ) ;
411+ var localId = _table2 + '.' + localResourceConfig . idAttribute ;
412+
413+ var relationTable = getTable ( relationResourceConfig ) ;
414+ var foreignId = relationTable + '.' + relation . foreignKey ;
415+
416+ var existsParams = ( _existsParams = { } , _defineProperty ( _existsParams , foreignId , { '===' : knex . raw ( localId ) } ) , _defineProperty ( _existsParams , parts [ 0 ] , criteria ) , _existsParams ) ;
417+ query . whereExists ( _this7 . filterQuery ( relationResourceConfig , existsParams , options ) ) ;
418+ criteria = null ; // criteria handled by EXISTS subquery
419+ }
420+
421+ localResourceConfig = relationResourceConfig ;
422+ } else {
423+ // hopefully a qualified local column
424+ }
425+ } ;
426+
427+ while ( parts . length >= 2 ) {
428+ _loop ( ) ;
429+ }
430+
431+ return getTable ( localResourceConfig ) + '.' + parts [ 0 ] ;
432+ } ;
433+
434+ if ( DSUtils . contains ( field , '.' ) ) {
433435 if ( DSUtils . contains ( field , ',' ) ) {
434436 var splitFields = field . split ( ',' ) . map ( function ( c ) {
435437 return c . trim ( ) ;
436438 } ) ;
437439 field = splitFields . map ( function ( splitField ) {
438- return applyTableJoins ( splitField , query , resourceConfig , joinedTables ) ;
440+ return processRelationField ( splitField ) ;
439441 } ) . join ( ',' ) ;
440442 } else {
441- field = applyTableJoins ( field , query , resourceConfig , joinedTables ) ;
443+ field = processRelationField ( field , query , resourceConfig , joinedTables ) ;
442444 }
445+ }
443446
447+ DSUtils . forOwn ( criteria , function ( v , op ) {
444448 if ( op === '==' || op === '===' ) {
445449 if ( v === null ) {
446450 query = query . whereNull ( field ) ;
0 commit comments