Opened 5 years ago

Closed 4 years ago

Last modified 4 years ago

#18074 closed defect (patchwelcome)

Cannot override SimpleQueryEngine sort function

Reported by: Wouter Hager Owned by: Kris Zyp
Priority: undecided Milestone: 1.11
Component: Data Version: 1.10.0-beta1
Keywords: Cc:
Blocked By: Blocking:

Description

As far as I can tell, dojo/store/util/SimpleQueryEngine should be able to receive a sort function property. The format here is that the sort property holds the function itself (i.e. typeof options.sort == "function"), but in dojo/store, the sort property should be an array, so afaik there is no way to just provide a sort function to SimpleQueryEngine?.

Change History (21)

comment:1 Changed 5 years ago by Wouter Hager

The SimpleQueryEngine? docs say one should provide dojo/store/api/Store.QueryOptions?. This is probably incorrect.

comment:2 Changed 5 years ago by ben hockey

Owner: set to Wouter Hager
Status: newpending

is your point that this is just a documentation error? in practice i've used a sort function before and it works.

comment:3 Changed 5 years ago by bill

Component: GeneralData

comment:4 in reply to:  2 Changed 5 years ago by Wouter Hager

Status: pendingnew

Replying to neonstalwart:

is your point that this is just a documentation error? in practice i've used a sort function before and it works.

Hi Ben, No, this is a bug. When I provide a function, JsonRest? throws an error.

comment:5 Changed 5 years ago by Wouter Hager

The error in jsonrest is because sort should be an array (as per documentation).

comment:6 Changed 5 years ago by ben hockey

Status: newpending

I assumed you were using the Memory store because JsonReat? doesn't have a queryEngine. it doesn't seem to make sense to support sorting with a function in JsonRest? because you don't typically serialize functions across the wire.

what is it you're trying to do? I'd say it's not a bug that JsonRest? doesn't support a function for sorting.

comment:7 Changed 5 years ago by Wouter Hager

Status: pendingnew

SimpleQueryEngine? is required for dijit/tree/ObjectStoreModel + JsonRest? + Observable. I know...

comment:8 Changed 5 years ago by ben hockey

Owner: changed from Wouter Hager to bill
Status: newassigned

ok... this is where I bow out - bill and/or kris probably should take it from here.

comment:9 Changed 5 years ago by bill

Owner: changed from bill to Kris Zyp

Kris?

comment:10 Changed 5 years ago by ben hockey

Owner: changed from Kris Zyp to Wouter Hager
Status: assignedpending

wshager I took a look at the source for dijit/tree/ObjectStoreModel and I don't see any obvious reason that you need to use a function for sorting. can you explain (or even better provide an example) why you need to use a function for sorting in that scenario?

comment:11 Changed 5 years ago by Wouter Hager

Status: pendingnew

I assumed the id of before to be stored in its preceding sibling item. I just run the function in the client in store.getChildren() and need to overwrite sorting in SimpleQueryEngine? anyway, because it takes the form of sort(children), which is obviously unlike rql sort() or array.sort. So it turns out I actually can't even use the sort property this ticket refers to.

Here is my sorting function:

function sort(children) {
	var sorted = [];
	// iterate through results and move correct item to sorted
	var beforeId = null, len = children.length;
	// if item wasn't found, escape
	while(children.length && len>0) {
		var child = children.pop();
		if(child.before==beforeId) {
			// update safety
			len = children.length;
			beforeId = child.id;
			sorted.unshift(child);
		} else {
			children.unshift(child);
			len--;
		}
	}
	return sorted.concat(children);
}

No idea how to proceed from here. I guess we have a different solution, and I would like to hear yours.

comment:12 Changed 5 years ago by ben hockey

in SimpleQueryEngine?, sort as a function should work like array.sort. where are you finding sort being called with an array of children?

sorry for so many questions but I'm still really lost about why you need to use a function for sorting and then showing a function that takes an array of children is sounding strange. I can't say I've done much with trees and stores but the store side of this story isn't sounding like anything I've ever faced before. if there's any other pertinent information (ideally a complete example with code) that could give me insight it might at least help me see the problem (even if I can't solve it). as of now, the only problem I'm identifying is that you have a sort function that works on an array of children - I'm suspicious about why it isn't working like array.sort.

comment:13 Changed 5 years ago by Wouter Hager

If anyone is able to tell me how to use "before" with JsonRest? I would gladly implement that and provide a fully featured example. I'm not going to provide more code until it's clear to me how this API was meant to be implemented, since that obviously only leads to more confusion.

comment:14 Changed 5 years ago by ben hockey

Owner: changed from Wouter Hager to Kris Zyp
Status: newassigned

ok now that we're getting to the root cause I'm starting to see where the problem lies. the summary seems to be this: newItem and pasteItem in dijit/tree/ObjectStoreModel use parent, before, overwrite, and oldParent directives when calling store.put and dojo/store/JsonRest does not provide support for all these directives.

I'm going to assign this back to kris to hear what he has to say.

comment:15 Changed 5 years ago by Kris Zyp

FWIW, we have actually been very recently working on an implementation of the before directive: https://github.com/SitePen/dstore/tree/options-before At some point we could assess if that is worth backporting to Dojo's object stores.

In the past, I have implemented the before functionality by defining a property (like 'order') specifically to use for sorting, and then when a put takes place, I find the new adjacent objects, and update the order property of the object that is being updated, to the mean of the adjacent objects, and then continue with the update (so you end up doing something like dragNDroppedObject.order = (objectThatIsNowBefore.order + objectThatIsNowAfter.order) / 2). Then you don't need a custom sort function, you can just sort by the order property. Anyway, I don't know if that helps, I am sure it is not feasible in all situations.

comment:16 Changed 5 years ago by Wouter Hager

I don't see any implementation details in dstore, only a custom header (by the way, the X prefix is deprecated). The mean could be useful, I'll consider that.

comment:17 Changed 5 years ago by Wouter Hager

Is there nothing more sophisticated than using the mean for ordering items? More people must have faced this issue before.

comment:18 Changed 5 years ago by Wouter Hager

I guess not: http://stackoverflow.com/questions/3399253/how-to-store-ordered-items-which-often-change-position-in-db

It seems the initial value of the order/position property is quite arbitrary. Makes me wonder why there seems to be no alternative, but I could probably bang my head against the wall all day.

Outside of the scope of Dojo anyway, so please close and mute. Thanks.

comment:19 Changed 5 years ago by Wouter Hager

Well, you know what, I'll just express another "opinion" here.

If you provide an API, but no way to implement that (in NoSQL, because that's what we're all using anyway), you can't expect people would want to use your API. There's clearly put forth some concept of how NoSQL data should be modeled (with Persevere in the background), but Dojo seems to systematically lack the bridge between client and server. That this is not a priority I can understand, but this means that the concept will just keep floating.

When choices about the server-side implementation would just be made here, it could turn out that the concept is not feasible after all, and that another, less generic, approach would be more practical.

comment:20 Changed 4 years ago by dylan

Milestone: tbd1.11
Resolution: patchwelcome
Status: assignedclosed

Moving to consideration for dstore. Closing out here for dojo/store.

comment:21 Changed 4 years ago by Wouter Hager

Agreed. Personally I'm moving away from stores and towards document/collection resolving.

Note: See TracTickets for help on using tickets.