Skip to content

Commit d6f6d1b

Browse files
committed
makes sorting with special types work
1 parent 6f25f16 commit d6f6d1b

File tree

4 files changed

+85
-47
lines changed

4 files changed

+85
-47
lines changed

src/helpers.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ var helpers = {
5858
return {prop: sortPropValue, desc: false};
5959
}
6060
},
61+
defaultCompare: defaultCompare,
6162
sorter: function (sortPropValue, sorters) {
6263
var data = helpers.sortData(sortPropValue);
6364
var compare;

src/serializers/basic-query.js

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -256,36 +256,18 @@ module.exports = function(schema) {
256256
}
257257
}
258258

259-
if(basicQuery.sort !== id) {
260-
res.sort = basicQuery.sort;
259+
if(basicQuery.sort.key !== id) {
260+
res.sort = basicQuery.sort.key;
261261
}
262262
return res;
263263

264264
}]
265265
];
266266

267267

268-
var sorters = {};
269-
canReflect.eachKey(keys, function(schemaProp, key){
270-
271-
sorters[key] = {
272-
// valueA is GT valueB
273-
$gt: function(valueA, valueB) {
274-
var $gt = hydrateAndValue({$gt: valueB}, key, schemaProp, function(){
275-
debugger;
276-
});
277-
return $gt.isMember(valueA);
278-
},
279-
$lt: function( valueA, valueB ){
280-
var $lt = hydrateAndValue({$lt: valueB}, key, schemaProp, function(){
281-
debugger;
282-
});
283-
return $lt.isMember(valueA);
284-
}
285-
};
286-
});
287-
288268

269+
// Makes a sort type that can make a compare function using the SetType
270+
var Sort = BasicQuery.makeSort(keys, hydrateAndValue);
289271
var serializer = new Serializer(serializeMap);
290272
serializer.add(comparisonsConverter.serializer);
291273

@@ -323,11 +305,11 @@ module.exports = function(schema) {
323305
query.page = new BasicQuery.RecordRange(data.page.start, data.page.end);
324306
}
325307
if(data.sort) {
326-
query.sort = data.sort;
308+
query.sort = new Sort(data.sort);
327309
} else {
328-
query.sort = id;
310+
query.sort = new Sort(id);
329311
}
330-
return new BasicQuery(query, sorters);
312+
return new BasicQuery(query);
331313
},
332314
serializer: serializer
333315
};

src/types/basic-query.js

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,61 @@ var andOrNot = require("./and-or-not");
66
var helpers = require("../helpers");
77
var defineLazyValue = require("can-define-lazy-value");
88

9+
// TYPES FOR FILTERING
910
var KeysAnd = andOrNot.KeysAnd,
1011
Or = andOrNot.ValuesOr,
1112
Not = andOrNot.ValuesNot;
1213

14+
// TYPES FOR PAGINATION
1315
var RecordRange = makeRealNumberRangeInclusive(0, Infinity);
1416

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({});
1660

1761

1862
// Define the BasicQuery type
19-
function BasicQuery(query, sorters) {
20-
this._sorters = sorters;
63+
function BasicQuery(query) {
2164
assign(this, query);
2265
if (!this.filter) {
2366
this.filter = set.UNIVERSAL;
@@ -28,13 +71,17 @@ function BasicQuery(query, sorters) {
2871
if (!this.sort) {
2972
this.sort = "id";
3073
}
74+
if(typeof this.sort === "string") {
75+
this.sort = new DefaultSort(this.sort);
76+
}
3177
}
3278

3379
// BasicQuery's static properties
3480
BasicQuery.KeysAnd = KeysAnd;
3581
BasicQuery.Or = Or;
3682
BasicQuery.Not = Not;
3783
BasicQuery.RecordRange = RecordRange;
84+
BasicQuery.makeSort = makeSort;
3885

3986
// BasicQuery's prototype methods.
4087
// These are "additional" features beyond what `set` provides.
@@ -44,8 +91,7 @@ canReflect.assignMap(BasicQuery.prototype, {
4491
return this.page.end - this.page.start + 1;
4592
},
4693
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);
4995
},
5096
filterMembersAndGetCount: function(bData, parentQuery) {
5197
if (parentQuery) {
@@ -64,7 +110,7 @@ canReflect.assignMap(BasicQuery.prototype, {
64110
var count = aData.length;
65111

66112
// sort the data if needed
67-
if (count && (this.sort !== parentQuery.sort)) {
113+
if (count && (this.sort.key !== parentQuery.sort.key)) {
68114
aData = this.sortData(aData);
69115
}
70116

@@ -85,7 +131,7 @@ canReflect.assignMap(BasicQuery.prototype, {
85131
}
86132
}
87133
// 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)) {
89135
return {
90136
data: aData.slice(this.page.start - parentQuery.page.start, this.page.end - parentQuery.page.start + 1),
91137
count: count
@@ -107,18 +153,15 @@ canReflect.assignMap(BasicQuery.prototype, {
107153
var combined = helpers.uniqueConcat(aItems, bItems, getId);
108154
return union.sortData(combined);
109155
}
110-
111-
// basically if there's pagination, we might not be able to do this
112-
113-
114156
},
115157
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);
117160
if (!Object.prototype.hasOwnProperty.call(props, data.prop)) {
118161
return undefined;
119162
}
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);
122165
},
123166
isMember: function(props) {
124167
// Use the AND type for it's isMember method
@@ -130,7 +173,7 @@ canReflect.assignMap(BasicQuery.prototype, {
130173
});
131174

132175
// Helpers used for the `set` comparators
133-
var CLAUSE_TYPES = ["filter", "page", "sort"];
176+
var CLAUSE_TYPES = ["filter", "page","sort"];
134177

135178
function getDifferentClauseTypes(queryA, queryB) {
136179
var differentTypes = [];
@@ -178,7 +221,7 @@ canReflect.eachKey({
178221
return this.pageIsEqual && this.aPageIsUniversal;
179222
},
180223
"sortIsEqual": function() {
181-
return this.queryA.sort === this.queryB.sort;
224+
return this.queryA.sort.key === this.queryB.sort.key;
182225
},
183226
"aFilterIsSubset": function() {
184227
return set.isSubset(this.queryA.filter, this.queryB.filter);
@@ -224,7 +267,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
224267
// We ignore the sort.
225268
return new BasicQuery({
226269
filter: filterUnion,
227-
sort: meta.sortIsEqual ? queryA.sort : undefined
270+
sort: meta.sortIsEqual ? queryA.sort.key : undefined
228271
});
229272
}
230273

@@ -233,7 +276,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
233276
if (meta.sortIsEqual) {
234277
return new BasicQuery({
235278
filter: queryA.filter,
236-
sort: queryA.sort,
279+
sort: queryA.sort.key,
237280
page: set.union(queryA.page, queryB.page)
238281
});
239282
} else {
@@ -270,7 +313,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
270313
if (set.isDefinedAndHasMembers(filterResult)) {
271314
return new BasicQuery({
272315
filter: filterResult,
273-
sort: meta.sortIsEqual ? queryA.sort : undefined
316+
sort: meta.sortIsEqual ? queryA.sort.key : undefined
274317
});
275318

276319
} else {
@@ -289,7 +332,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
289332
if (meta.sortIsEqual) {
290333
return new BasicQuery({
291334
filter: queryA.filter,
292-
sort: queryA.sort,
335+
sort: queryA.sort.key,
293336
page: set.intersection(queryA.page, queryB.page)
294337
});
295338
} else {
@@ -326,7 +369,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
326369
if (meta.pagesAreUniversal) {
327370
return new BasicQuery({
328371
filter: set.difference(queryA.filter, queryB.filter),
329-
sort: queryA.sort
372+
sort: queryA.sort.key
330373
});
331374
}
332375

@@ -367,7 +410,7 @@ set.defineComparison(BasicQuery, BasicQuery, {
367410
var query = {
368411
filter: queryA.filter,
369412
page: queryA.page,
370-
sort: queryA.sort
413+
sort: queryA.sort.key
371414
};
372415
query[clause] = result;
373416
return new BasicQuery(query);

test/special-comparison-logic-test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,16 @@ QUnit.test("value type", function(){
244244
var ids = result.map(function(item){ return item.id});
245245
QUnit.deepEqual(ids,[1,2,3,4], "sorted correctly");
246246

247+
var index = queryLogic.index({
248+
sort: "date"
249+
},
250+
[
251+
{id: 1, date: new Date(2018,4,20).toString()}, // M
252+
{id: 2, date: new Date(2018,4,21).toString()}, // Tu
253+
{id: 3, date: new Date(2018,4,22).toString()}, // We
254+
{id: 4, date: new Date(2018,4,23).toString()} // Thurs
255+
],
256+
{id: 4, date: new Date(2018,4,24).toString()}); //F
257+
258+
QUnit.equal(index, 4, "added at the end")
247259
});

0 commit comments

Comments
 (0)