1
- let knex = require ( 'knex' )
2
- let JSData = require ( 'js-data' )
3
- let underscore = require ( 'mout/string/underscore' )
4
- let unique = require ( 'mout/array/unique' )
5
- let toString = require ( 'mout/lang/toString' )
6
- let { DSUtils } = JSData
1
+ import knex from 'knex' ;
2
+ import Promise from 'bluebird' ;
3
+ import { contains , unique } from 'mout/array'
4
+ import { isEmpty , isObject , isString , toString } from 'mout/lang' ;
5
+ import { deepMixIn , forOwn , get , omit } from 'mout/object'
6
+ import { underscore } from 'mout/string' ;
7
+ import { DSUtils } from 'js-data' ;
8
+ const { removeCircular } = DSUtils ;
7
9
8
10
let reserved = [
9
11
'orderBy' ,
@@ -22,134 +24,132 @@ function loadWithRelations (items, resourceConfig, options) {
22
24
let tasks = [ ]
23
25
let instance = Array . isArray ( items ) ? null : items
24
26
25
- DSUtils . forEach ( resourceConfig . relationList , def => {
26
- let relationName = def . relation
27
- let relationDef = resourceConfig . getResource ( relationName )
27
+ if ( resourceConfig . relationList ) {
28
+ resourceConfig . relationList . forEach ( def => {
29
+ let relationName = def . relation
30
+ let relationDef = resourceConfig . getResource ( relationName )
28
31
29
- let containedName = null
30
- if ( DSUtils . contains ( options . with , relationName ) ) {
31
- containedName = relationName
32
- } else if ( DSUtils . contains ( options . with , def . localField ) ) {
33
- containedName = def . localField
34
- } else {
35
- return
36
- }
32
+ let containedName = null
33
+ if ( contains ( options . with , relationName ) ) {
34
+ containedName = relationName
35
+ } else if ( contains ( options . with , def . localField ) ) {
36
+ containedName = def . localField
37
+ } else {
38
+ return
39
+ }
37
40
38
- let __options = DSUtils . deepMixIn ( { } , options . orig ? options . orig ( ) : options )
41
+ let __options = deepMixIn ( { } , options . orig ? options . orig ( ) : options )
39
42
40
- // Filter to only properties under current relation
41
- __options . with = options . with . filter ( relation => {
42
- return relation !== containedName &&
43
- relation . indexOf ( containedName ) === 0 &&
44
- relation . length >= containedName . length &&
45
- relation [ containedName . length ] === '.'
46
- } ) . map ( relation => relation . substr ( containedName . length + 1 ) )
43
+ // Filter to only properties under current relation
44
+ __options . with = options . with . filter ( relation => {
45
+ return relation !== containedName &&
46
+ relation . indexOf ( containedName ) === 0 &&
47
+ relation . length >= containedName . length &&
48
+ relation [ containedName . length ] === '.'
49
+ } ) . map ( relation => relation . substr ( containedName . length + 1 ) )
47
50
48
- let task
51
+ let task
49
52
50
- if ( ( def . type === 'hasOne' || def . type === 'hasMany' ) && def . foreignKey ) {
51
- let foreignKeyFilter
52
- if ( instance ) {
53
- foreignKeyFilter = { '==' : instance [ resourceConfig . idAttribute ] }
54
- } else {
55
- foreignKeyFilter = { 'in' : items . map ( item => item [ resourceConfig . idAttribute ] ) }
56
- }
57
- task = this . findAll ( resourceConfig . getResource ( relationName ) , {
58
- where : {
59
- [ def . foreignKey ] : foreignKeyFilter
60
- }
61
- } , __options ) . then ( relatedItems => {
62
- if ( instance ) {
63
- if ( def . type === 'hasOne' && relatedItems . length ) {
64
- instance [ def . localField ] = relatedItems [ 0 ]
65
- } else {
66
- instance [ def . localField ] = relatedItems
53
+ if ( ( def . type === 'hasOne' || def . type === 'hasMany' ) && def . foreignKey ) {
54
+ task = this . findAll ( resourceConfig . getResource ( relationName ) , {
55
+ where : {
56
+ [ def . foreignKey ] : instance ?
57
+ { '==' : instance [ resourceConfig . idAttribute ] } :
58
+ { 'in' : items . map ( item => item [ resourceConfig . idAttribute ] ) }
67
59
}
68
- } else {
69
- DSUtils . forEach ( items , item => {
70
- let attached = relatedItems . filter ( ri => ri [ def . foreignKey ] === item [ resourceConfig . idAttribute ] )
71
- if ( def . type === 'hasOne' && attached . length ) {
72
- item [ def . localField ] = attached [ 0 ]
60
+ } , __options ) . then ( relatedItems => {
61
+ if ( instance ) {
62
+ if ( def . type === 'hasOne' && relatedItems . length ) {
63
+ instance [ def . localField ] = relatedItems [ 0 ]
73
64
} else {
74
- item [ def . localField ] = attached
65
+ instance [ def . localField ] = relatedItems
75
66
}
76
- } )
77
- }
67
+ } else {
68
+ items . forEach ( item => {
69
+ let attached = relatedItems . filter ( ri => ri [ def . foreignKey ] === item [ resourceConfig . idAttribute ] )
70
+ if ( def . type === 'hasOne' && attached . length ) {
71
+ item [ def . localField ] = attached [ 0 ]
72
+ } else {
73
+ item [ def . localField ] = attached
74
+ }
75
+ } )
76
+ }
78
77
79
- return relatedItems
80
- } )
81
- } else if ( def . type === 'hasMany' && def . localKeys ) {
82
- // TODO: Write test for with: hasMany property with localKeys
83
- let localKeys = [ ]
84
-
85
- if ( instance ) {
86
- let itemKeys = instance [ def . localKeys ] || [ ]
87
- itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys )
88
- localKeys = localKeys . concat ( itemKeys || [ ] )
89
- } else {
90
- DSUtils . forEach ( items , item => {
91
- let itemKeys = item [ def . localKeys ] || [ ]
92
- itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys )
93
- localKeys = localKeys . concat ( itemKeys || [ ] )
78
+ return relatedItems
94
79
} )
95
- }
80
+ } else if ( def . type === 'hasMany' && def . localKeys ) {
81
+ // TODO: Write test for with: hasMany property with localKeys
82
+ let localKeys = [ ]
96
83
97
- task = this . findAll ( resourceConfig . getResource ( relationName ) , {
98
- where : {
99
- [ relationDef . idAttribute ] : {
100
- 'in' : DSUtils . filter ( unique ( localKeys ) , x => x )
101
- }
102
- }
103
- } , __options ) . then ( relatedItems => {
104
84
if ( instance ) {
105
- instance [ def . localField ] = relatedItems
85
+ let itemKeys = instance [ def . localKeys ] || [ ]
86
+ itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys )
87
+ localKeys = localKeys . concat ( itemKeys || [ ] )
106
88
} else {
107
- DSUtils . forEach ( items , item => {
89
+ items . forEach ( item => {
108
90
let itemKeys = item [ def . localKeys ] || [ ]
109
- let attached = relatedItems . filter ( ri => itemKeys && DSUtils . contains ( itemKeys , ri [ relationDef . idAttribute ] ) )
110
- item [ def . localField ] = attached
91
+ itemKeys = Array . isArray ( itemKeys ) ? itemKeys : Object . keys ( itemKeys )
92
+ localKeys = localKeys . concat ( itemKeys || [ ] )
111
93
} )
112
94
}
113
95
114
- return relatedItems
115
- } )
116
- } else if ( def . type === 'belongsTo' || ( def . type === 'hasOne' && def . localKey ) ) {
117
- if ( instance ) {
118
- let id = DSUtils . get ( instance , def . localKey )
119
- if ( id ) {
120
- task = this . find ( resourceConfig . getResource ( relationName ) , DSUtils . get ( instance , def . localKey ) , __options ) . then ( relatedItem => {
121
- instance [ def . localField ] = relatedItem
122
- return relatedItem
123
- } )
124
- }
125
- } else {
126
- let ids = DSUtils . filter ( items . map ( item => DSUtils . get ( item , def . localKey ) ) , x => x )
127
- if ( ids . length ) {
128
- task = this . findAll ( resourceConfig . getResource ( relationName ) , {
129
- where : {
130
- [ relationDef . idAttribute ] : {
131
- 'in' : ids
132
- }
96
+ task = this . findAll ( resourceConfig . getResource ( relationName ) , {
97
+ where : {
98
+ [ relationDef . idAttribute ] : {
99
+ 'in' : filter ( unique ( localKeys ) , x => x )
133
100
}
134
- } , __options ) . then ( relatedItems => {
135
- DSUtils . forEach ( items , item => {
136
- DSUtils . forEach ( relatedItems , relatedItem => {
137
- if ( relatedItem [ relationDef . idAttribute ] === item [ def . localKey ] ) {
138
- item [ def . localField ] = relatedItem
101
+ }
102
+ } , __options ) . then ( relatedItems => {
103
+ if ( instance ) {
104
+ instance [ def . localField ] = relatedItems
105
+ } else {
106
+ items . forEach ( item => {
107
+ let itemKeys = item [ def . localKeys ] || [ ]
108
+ let attached = relatedItems . filter ( ri => itemKeys && contains ( itemKeys , ri [ relationDef . idAttribute ] ) )
109
+ item [ def . localField ] = attached
110
+ } )
111
+ }
112
+
113
+ return relatedItems
114
+ } )
115
+ } else if ( def . type === 'belongsTo' || ( def . type === 'hasOne' && def . localKey ) ) {
116
+ if ( instance ) {
117
+ let id = get ( instance , def . localKey )
118
+ if ( id ) {
119
+ task = this . find ( resourceConfig . getResource ( relationName ) , get ( instance , def . localKey ) , __options ) . then ( relatedItem => {
120
+ instance [ def . localField ] = relatedItem
121
+ return relatedItem
122
+ } )
123
+ }
124
+ } else {
125
+ let ids = items . map ( item => get ( item , def . localKey ) ) . filter ( x => x )
126
+ if ( ids . length ) {
127
+ task = this . findAll ( resourceConfig . getResource ( relationName ) , {
128
+ where : {
129
+ [ relationDef . idAttribute ] : {
130
+ 'in' : ids
139
131
}
132
+ }
133
+ } , __options ) . then ( relatedItems => {
134
+ items . forEach ( item => {
135
+ relatedItems . forEach ( relatedItem => {
136
+ if ( relatedItem [ relationDef . idAttribute ] === item [ def . localKey ] ) {
137
+ item [ def . localField ] = relatedItem
138
+ }
139
+ } )
140
140
} )
141
+ return relatedItems
141
142
} )
142
- return relatedItems
143
- } )
143
+ }
144
144
}
145
145
}
146
- }
147
146
148
- if ( task ) {
149
- tasks . push ( task )
150
- }
151
- } )
152
- return DSUtils . Promise . all ( tasks )
147
+ if ( task ) {
148
+ tasks . push ( task )
149
+ }
150
+ } )
151
+ }
152
+ return Promise . all ( tasks )
153
153
}
154
154
155
155
class DSSqlAdapter {
@@ -161,7 +161,7 @@ class DSSqlAdapter {
161
161
} else {
162
162
this . query = knex ( options )
163
163
}
164
- DSUtils . deepMixIn ( this . defaults , options )
164
+ deepMixIn ( this . defaults , options )
165
165
}
166
166
167
167
find ( resourceConfig , id , options ) {
@@ -195,7 +195,7 @@ class DSSqlAdapter {
195
195
}
196
196
197
197
create ( resourceConfig , attrs , options ) {
198
- attrs = DSUtils . removeCircular ( DSUtils . omit ( attrs , resourceConfig . relationFields || [ ] ) )
198
+ attrs = removeCircular ( omit ( attrs , resourceConfig . relationFields || [ ] ) )
199
199
let query = options && options . transaction || this . query
200
200
return query ( getTable ( resourceConfig ) )
201
201
. insert ( attrs , resourceConfig . idAttribute )
@@ -211,7 +211,7 @@ class DSSqlAdapter {
211
211
}
212
212
213
213
update ( resourceConfig , id , attrs , options ) {
214
- attrs = DSUtils . removeCircular ( DSUtils . omit ( attrs , resourceConfig . relationFields || [ ] ) )
214
+ attrs = removeCircular ( omit ( attrs , resourceConfig . relationFields || [ ] ) )
215
215
let query = options && options . transaction || this . query
216
216
return query ( getTable ( resourceConfig ) )
217
217
. where ( resourceConfig . idAttribute , toString ( id ) )
@@ -220,7 +220,7 @@ class DSSqlAdapter {
220
220
}
221
221
222
222
updateAll ( resourceConfig , attrs , params , options ) {
223
- attrs = DSUtils . removeCircular ( DSUtils . omit ( attrs , resourceConfig . relationFields || [ ] ) )
223
+ attrs = removeCircular ( omit ( attrs , resourceConfig . relationFields || [ ] ) )
224
224
return this . filterQuery ( resourceConfig , params , options ) . then ( items => {
225
225
return items . map ( item => item [ resourceConfig . idAttribute ] )
226
226
} ) . then ( ids => {
@@ -265,10 +265,10 @@ class DSSqlAdapter {
265
265
params . orderBy = params . orderBy || params . sort
266
266
params . skip = params . skip || params . offset
267
267
268
- DSUtils . forEach ( Object . keys ( params ) , k => {
268
+ Object . keys ( params ) . forEach ( k => {
269
269
let v = params [ k ]
270
- if ( ! DSUtils . contains ( reserved , k ) ) {
271
- if ( DSUtils . isObject ( v ) ) {
270
+ if ( ! contains ( reserved , k ) ) {
271
+ if ( isObject ( v ) ) {
272
272
params . where [ k ] = v
273
273
} else {
274
274
params . where [ k ] = {
@@ -279,9 +279,9 @@ class DSSqlAdapter {
279
279
}
280
280
} )
281
281
282
- if ( ! DSUtils . isEmpty ( params . where ) ) {
283
- DSUtils . forOwn ( params . where , ( criteria , field ) => {
284
- if ( ! DSUtils . isObject ( criteria ) ) {
282
+ if ( ! isEmpty ( params . where ) ) {
283
+ forOwn ( params . where , ( criteria , field ) => {
284
+ if ( ! isObject ( criteria ) ) {
285
285
params . where [ field ] = {
286
286
'==' : criteria
287
287
}
@@ -337,16 +337,16 @@ class DSSqlAdapter {
337
337
return `${ getTable ( localResourceConfig ) } .${ parts [ 0 ] } `
338
338
}
339
339
340
- if ( DSUtils . contains ( field , '.' ) ) {
341
- if ( DSUtils . contains ( field , ',' ) ) {
340
+ if ( contains ( field , '.' ) ) {
341
+ if ( contains ( field , ',' ) ) {
342
342
let splitFields = field . split ( ',' ) . map ( c => c . trim ( ) )
343
343
field = splitFields . map ( splitField => processRelationField ( splitField ) ) . join ( ',' )
344
344
} else {
345
345
field = processRelationField ( field , query , resourceConfig , joinedTables )
346
346
}
347
347
}
348
348
349
- DSUtils . forOwn ( criteria , ( v , op ) => {
349
+ forOwn ( criteria , ( v , op ) => {
350
350
if ( op === '==' || op === '===' ) {
351
351
if ( v === null ) {
352
352
query = query . whereNull ( field )
@@ -454,16 +454,16 @@ class DSSqlAdapter {
454
454
}
455
455
456
456
if ( params . orderBy ) {
457
- if ( DSUtils . isString ( params . orderBy ) ) {
457
+ if ( isString ( params . orderBy ) ) {
458
458
params . orderBy = [
459
459
[ params . orderBy , 'asc' ]
460
460
]
461
461
}
462
462
for ( var i = 0 ; i < params . orderBy . length ; i ++ ) {
463
- if ( DSUtils . isString ( params . orderBy [ i ] ) ) {
463
+ if ( isString ( params . orderBy [ i ] ) ) {
464
464
params . orderBy [ i ] = [ params . orderBy [ i ] , 'asc' ]
465
465
}
466
- query = DSUtils . upperCase ( params . orderBy [ i ] [ 1 ] ) === 'DESC' ? query . orderBy ( params . orderBy [ i ] [ 0 ] , 'desc' ) : query . orderBy ( params . orderBy [ i ] [ 0 ] , 'asc' )
466
+ query = params . orderBy [ i ] [ 1 ] . toUpperCase ( ) === 'DESC' ? query . orderBy ( params . orderBy [ i ] [ 0 ] , 'desc' ) : query . orderBy ( params . orderBy [ i ] [ 0 ] , 'asc' )
467
467
}
468
468
}
469
469
0 commit comments