@@ -6,18 +6,61 @@ var andOrNot = require("./and-or-not");
6
6
var helpers = require ( "../helpers" ) ;
7
7
var defineLazyValue = require ( "can-define-lazy-value" ) ;
8
8
9
+ // TYPES FOR FILTERING
9
10
var KeysAnd = andOrNot . KeysAnd ,
10
11
Or = andOrNot . ValuesOr ,
11
12
Not = andOrNot . ValuesNot ;
12
13
14
+ // TYPES FOR PAGINATION
13
15
var RecordRange = makeRealNumberRangeInclusive ( 0 , Infinity ) ;
14
16
15
- // Wire up the sub-types to be able to compare to each other
17
+ // WILL MAKE A TYPE FOR SORTING
18
+ function makeSort ( schemaKeys , hydrateAndValue ) {
19
+ // Makes gt and lt functions that `helpers.sorter` can use
20
+ // to make a `compare` function for `Array.sort(compare)`.`
21
+ var sorters = { } ;
22
+ canReflect . eachKey ( schemaKeys , function ( schemaProp , key ) {
23
+
24
+ sorters [ key ] = {
25
+ // valueA is GT valueB
26
+ $gt : function ( valueA , valueB ) {
27
+ var $gt = hydrateAndValue ( { $gt : valueB } , key , schemaProp ) ;
28
+ return $gt . isMember ( valueA ) ;
29
+ } ,
30
+ $lt : function ( valueA , valueB ) {
31
+ var $lt = hydrateAndValue ( { $lt : valueB } , key , schemaProp ) ;
32
+ return $lt . isMember ( valueA ) ;
33
+ }
34
+ } ;
35
+ } ) ;
36
+
37
+ function Sort ( key ) {
38
+ this . key = key ;
39
+ this . compare = helpers . sorter ( key , sorters ) ;
40
+ }
41
+
42
+ function identityIntersection ( v1 , v2 ) {
43
+ return v1 . key === v2 . key ? v1 : set . EMPTY ;
44
+ }
45
+ function identityDifference ( v1 , v2 ) {
46
+ return v1 . key === v2 . key ? set . EMPTY : v1 ;
47
+ }
48
+ function identityUnion ( v1 , v2 ) {
49
+ return v1 . key === v2 . key ? v1 : set . UNDEFINABLE ;
50
+ }
51
+ set . defineComparison ( Sort , Sort , {
52
+ intersection : identityIntersection ,
53
+ difference : identityDifference ,
54
+ union : identityUnion
55
+ } ) ;
56
+ return Sort ;
57
+ }
58
+
59
+ var DefaultSort = makeSort ( { } ) ;
16
60
17
61
18
62
// Define the BasicQuery type
19
- function BasicQuery ( query , sorters ) {
20
- this . _sorters = sorters ;
63
+ function BasicQuery ( query ) {
21
64
assign ( this , query ) ;
22
65
if ( ! this . filter ) {
23
66
this . filter = set . UNIVERSAL ;
@@ -28,13 +71,17 @@ function BasicQuery(query, sorters) {
28
71
if ( ! this . sort ) {
29
72
this . sort = "id" ;
30
73
}
74
+ if ( typeof this . sort === "string" ) {
75
+ this . sort = new DefaultSort ( this . sort ) ;
76
+ }
31
77
}
32
78
33
79
// BasicQuery's static properties
34
80
BasicQuery . KeysAnd = KeysAnd ;
35
81
BasicQuery . Or = Or ;
36
82
BasicQuery . Not = Not ;
37
83
BasicQuery . RecordRange = RecordRange ;
84
+ BasicQuery . makeSort = makeSort ;
38
85
39
86
// BasicQuery's prototype methods.
40
87
// These are "additional" features beyond what `set` provides.
@@ -44,8 +91,7 @@ canReflect.assignMap(BasicQuery.prototype, {
44
91
return this . page . end - this . page . start + 1 ;
45
92
} ,
46
93
sortData : function ( data ) {
47
- var sort = helpers . sorter ( this . sort , this . _sorters ) ;
48
- return data . slice ( 0 ) . sort ( sort ) ;
94
+ return data . slice ( 0 ) . sort ( this . sort . compare ) ;
49
95
} ,
50
96
filterMembersAndGetCount : function ( bData , parentQuery ) {
51
97
if ( parentQuery ) {
@@ -64,7 +110,7 @@ canReflect.assignMap(BasicQuery.prototype, {
64
110
var count = aData . length ;
65
111
66
112
// sort the data if needed
67
- if ( count && ( this . sort !== parentQuery . sort ) ) {
113
+ if ( count && ( this . sort . key !== parentQuery . sort . key ) ) {
68
114
aData = this . sortData ( aData ) ;
69
115
}
70
116
@@ -85,7 +131,7 @@ canReflect.assignMap(BasicQuery.prototype, {
85
131
}
86
132
}
87
133
// everything but range is equal
88
- else if ( this . sort === parentQuery . sort && set . isEqual ( parentQuery . filter , this . filter ) ) {
134
+ else if ( this . sort . key === parentQuery . sort . key && set . isEqual ( parentQuery . filter , this . filter ) ) {
89
135
return {
90
136
data : aData . slice ( this . page . start - parentQuery . page . start , this . page . end - parentQuery . page . start + 1 ) ,
91
137
count : count
@@ -107,18 +153,15 @@ canReflect.assignMap(BasicQuery.prototype, {
107
153
var combined = helpers . uniqueConcat ( aItems , bItems , getId ) ;
108
154
return union . sortData ( combined ) ;
109
155
}
110
-
111
- // basically if there's pagination, we might not be able to do this
112
-
113
-
114
156
} ,
115
157
index : function ( props , items ) {
116
- var data = helpers . sortData ( this . sort ) ;
158
+ // make sure we have the property
159
+ var data = helpers . sortData ( this . sort . key ) ;
117
160
if ( ! Object . prototype . hasOwnProperty . call ( props , data . prop ) ) {
118
161
return undefined ;
119
162
}
120
- var sort = helpers . sorter ( this . sort ) ;
121
- return helpers . getIndex ( sort , items , props ) ;
163
+ // use the passed sort's compare function
164
+ return helpers . getIndex ( this . sort . compare , items , props ) ;
122
165
} ,
123
166
isMember : function ( props ) {
124
167
// Use the AND type for it's isMember method
@@ -130,7 +173,7 @@ canReflect.assignMap(BasicQuery.prototype, {
130
173
} ) ;
131
174
132
175
// Helpers used for the `set` comparators
133
- var CLAUSE_TYPES = [ "filter" , "page" , "sort" ] ;
176
+ var CLAUSE_TYPES = [ "filter" , "page" , "sort" ] ;
134
177
135
178
function getDifferentClauseTypes ( queryA , queryB ) {
136
179
var differentTypes = [ ] ;
@@ -178,7 +221,7 @@ canReflect.eachKey({
178
221
return this . pageIsEqual && this . aPageIsUniversal ;
179
222
} ,
180
223
"sortIsEqual" : function ( ) {
181
- return this . queryA . sort === this . queryB . sort ;
224
+ return this . queryA . sort . key === this . queryB . sort . key ;
182
225
} ,
183
226
"aFilterIsSubset" : function ( ) {
184
227
return set . isSubset ( this . queryA . filter , this . queryB . filter ) ;
@@ -224,7 +267,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
224
267
// We ignore the sort.
225
268
return new BasicQuery ( {
226
269
filter : filterUnion ,
227
- sort : meta . sortIsEqual ? queryA . sort : undefined
270
+ sort : meta . sortIsEqual ? queryA . sort . key : undefined
228
271
} ) ;
229
272
}
230
273
@@ -233,7 +276,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
233
276
if ( meta . sortIsEqual ) {
234
277
return new BasicQuery ( {
235
278
filter : queryA . filter ,
236
- sort : queryA . sort ,
279
+ sort : queryA . sort . key ,
237
280
page : set . union ( queryA . page , queryB . page )
238
281
} ) ;
239
282
} else {
@@ -270,7 +313,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
270
313
if ( set . isDefinedAndHasMembers ( filterResult ) ) {
271
314
return new BasicQuery ( {
272
315
filter : filterResult ,
273
- sort : meta . sortIsEqual ? queryA . sort : undefined
316
+ sort : meta . sortIsEqual ? queryA . sort . key : undefined
274
317
} ) ;
275
318
276
319
} else {
@@ -289,7 +332,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
289
332
if ( meta . sortIsEqual ) {
290
333
return new BasicQuery ( {
291
334
filter : queryA . filter ,
292
- sort : queryA . sort ,
335
+ sort : queryA . sort . key ,
293
336
page : set . intersection ( queryA . page , queryB . page )
294
337
} ) ;
295
338
} else {
@@ -326,7 +369,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
326
369
if ( meta . pagesAreUniversal ) {
327
370
return new BasicQuery ( {
328
371
filter : set . difference ( queryA . filter , queryB . filter ) ,
329
- sort : queryA . sort
372
+ sort : queryA . sort . key
330
373
} ) ;
331
374
}
332
375
@@ -367,7 +410,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
367
410
var query = {
368
411
filter : queryA . filter ,
369
412
page : queryA . page ,
370
- sort : queryA . sort
413
+ sort : queryA . sort . key
371
414
} ;
372
415
query [ clause ] = result ;
373
416
return new BasicQuery ( query ) ;
0 commit comments