Welcome, guest ( Login )

WikiHome » dojo.data » Dojo Data Meetings » 2006-09-19

2006-09-19

Version 13, changed by brian 09/19/2006.   Show version history

Agenda

  • try to resolve some of the open issues
    • Read api
      • one more method to add?
        • var array = store.getAttributes(kermit);
      • naming
        • byIdentity() getIdentity() vs. byKey() getKeyOf() vs. something else
        • fetch() search() query()
      • forEach() args -- any specific proposals
        • onCompletion?
        • first/last, first/numItems, start/end?
        • forEach(someCallbackFunction)
        • forEach(someControllerObject, "someCallbackMethod")
    • Write api
      • save() -- onComplete callback? -- return a Deferred or a boolean?
      • problem with adding a single value?
    • other issues to work on?
  • sign off on some APIs (or is it too early for this?)
    • Read and Result
    • Write

Resolutions

  • in dojo.data.Read:
    • var array = store.getAttributes(kermit);
    • var item = store.getByIdentity(identityString);
    • var identityString = store.getIdentity(item);
    • find(), not fetch(), search(), or query()
    • var result = store.find(queryParam, optionsKeywordParams);
      • queryParam and optionsKeywordParams are both optional
      • queryParam can be anything: string, Date, keywordObject, etc.
      • optionsKeywordParams is always a keywordObject, like {async: true}
    • var result = store.find("all books");
    • var result = store.find({author:"Austin"}, {async: true});
    • get() and getValues() throw exceptions if the item argument is not actually an item
  • in dojo.data.Result
    • we allow args on forEach() -- we agree that we don't specify what any specific looping args are, but we agree that forEach() can be called multiple times
    • forEach() always takes exactly one argument, which is either:
      • a simple callback function: result.forEach(function (item){/print item name/});
      • a keyword object:
        • result.forEach({callback: someCallbackFunction});
        • result.forEach({object: someHandlerObject, callback: someCallbackMethod});
    • var boolean = result.inProgress();
    • getLength() returns -1 if the length is not known when the method is called

Transcript

[1:10 PM] brian_skinner: so, no sign of Alex -- but all the rest of the regular crowd is here, so i think we have a quorum
[1:10 PM] dmachi: alex is out of the country
[1:10 PM] ttrenka: belgium, right?
[1:10 PM] brian_skinner: okay, then no alex this week
[1:10 PM] jaxsphere: no feedback on the new api's?
[1:10 PM] dmachi: ttrenka: sounds right
[1:11 PM] brian_skinner: i posted a proposed agenda -- http://dojo.jot.com/2006-09-19
[1:11 PM] jaxsphere: ah
[1:11 PM] brian_skinner: does that look okay -- do we have other stuff to cover today?
[1:11 PM] aszs: i've been implementing them
[1:11 PM] brian_skinner: :-)
[1:11 PM] jaxsphere: cool
[1:11 PM] aszs: raises some questions
[1:11 PM] aszs: minor ones
[1:12 PM] brian_skinner: our first reality check ;-)
[1:12 PM] aszs: yes
[1:12 PM] aszs: so far so good
[1:13 PM] aszs: the issues are minor so we can get to them later
[1:13 PM] brian_skinner: okay
[1:13 PM] jaxsphere: Read api
[1:13 PM] jaxsphere:     * one more method to add?
[1:13 PM] jaxsphere:           o var array = store.getAttributes(kermit);
[1:13 PM] aszs: yes
[1:14 PM] aszs: unless we keep asJson()
[1:14 PM] brian_skinner: yup, aszs exchanged mail about that during the week
[1:14 PM] brian_skinner: a simple UI needs some way to find out what attributes a data item has
[1:14 PM] brian_skinner: in the absence of schema/metamodel info
[1:15 PM] jaxsphere: the names of the attributes, or the values?
[1:15 PM] brian_skinner: the names
[1:15 PM] brian_skinner: (or objects that represent the attributes)
[1:15 PM] brian_skinner: not the values
[1:15 PM] jaxsphere: shouldnt that be part of the meta api?
[1:16 PM] aszs: its the one part of the meta api
[1:16 PM] aszs: that will be need generally i think
[1:16 PM] brian_skinner: i was hoping that some simple datastores wouldn't need to include the meta api at all, if the datastore doesn't have a structured schema
[1:16 PM] aszs: yes
[1:16 PM] jaxsphere: every store must implement this too for Read api
[1:17 PM] brian_skinner: yes, that's what we're proposing
[1:17 PM] jaxsphere: makes sense.  Can then use attr names to get further meta info usng meta api
[1:17 PM] brian_skinner: yup
[1:17 PM] brian_skinner: for a structured datastore, the implementation should be trivial
[1:18 PM] brian_skinner: maybe one line of code
[1:18 PM] ttrenka: sorry guys, I'm sort of lurking today, trying to get docs done and dealing with a company that thinks no one understands how SSH works
[1:18 PM] brian_skinner: just find the class of the item and ask it for its list of attributes
[1:19 PM] brian_skinner: ttrenka: yup, understood -- jump in if there's anything that's caught your eye
[1:19 PM] ttrenka: will do
[1:19 PM] jaxsphere: +1 for store.getAttributes(item)
[1:19 PM] ttrenka: brian_skinner: also ping me in a bit about your banner request
[1:19 PM] brian_skinner: ttrenka: will do
[1:20 PM] aszs: +1
[1:20 PM] brian_skinner: i'm +1 for getAttributes() too
[1:20 PM] ttrenka: 0
[1:20 PM] ttrenka: (I'm neutral :)
[1:20 PM] brian_skinner: sounds like we're mostly in favor -- i'll add it to the dojo.data.Read wiki page
[1:21 PM] brian_skinner: moving on to the next issue...
[1:21 PM] brian_skinner: a couple little naming questions to figure out
[1:21 PM] jaxsphere: naming
[1:21 PM] jaxsphere:     * byIdentity() getIdentity() vs. byKey() getKeyOf() vs. something else
[1:21 PM] aszs: of those: byKey()
[1:21 PM] brian_skinner: in last week's meeting, nobody liked byId()
[1:21 PM] brian_skinner: jaxsphere proposed byIdentity()
[1:22 PM] brian_skinner: byIdentifier() might also make sense
[1:22 PM] jaxsphere: i like by Identity :) more general than byKey (could be a uri), and byId was confusing with dom id
[1:22 PM] brian_skinner: i don't like byId, but I'm game for pretty much anything else
[1:23 PM] jaxsphere: key makes me think of a list of values that are for attributes of the item
[1:23 PM] ttrenka: I'm ok with Identity
[1:23 PM] ttrenka: that's clearer, I think; byId implies a common field name
[1:23 PM] aszs: byName()?
[1:24 PM] brian_skinner: byToken()
[1:24 PM] jaxsphere: name also sounds like getting attribute
[1:24 PM] jaxsphere: how about just identity(item)
[1:24 PM] brian_skinner: i'd like to avoid "Name", since that makes me think of a display name
[1:24 PM] aszs: i like byIdentity() better
[1:24 PM] brian_skinner: jaxsphere: identity(item) instead of byIdentity(item) or getIdentity(item)?
[1:25 PM] jaxsphere: yes
[1:25 PM] brian_skinner: i like by or get better too
[1:25 PM] aszs: i like "by" better because you're not getting the identity
[1:25 PM] brian_skinner: oops, by *and* get
[1:25 PM] jaxsphere: getIdentity(item), if qualified is probably clearer
[1:25 PM] aszs: your getting the item using the identitiy
[1:26 PM] jaxsphere: aszs, ah, so this is more like findByIdentity(item)
[1:26 PM] aszs: yes
[1:26 PM] brian_skinner: string = getIdentity(item)
[1:26 PM] brian_skinner: item = byIdentity(string)
[1:26 PM] aszs: the latter, right?
[1:26 PM] brian_skinner: we need both
[1:27 PM] aszs: oops
[1:27 PM] ttrenka: aszs, I'd totally disagree with that: I'd expect getIdentity(item) to return me the identity of the item
[1:27 PM] jaxsphere: maybe naming consistent with lookup... wg. search(...), searchByIdentity(), searchByKey
[1:27 PM] jaxsphere: r/wg./eg.
[1:27 PM] aszs: ttrenka: we're in violent agreeement
[1:28 PM] aszs: jaxsphere: i agree
[1:28 PM] jaxsphere: ok :) so getIdentity(item) just returns some opaque string identifier for the item
[1:28 PM] brian_skinner: jaxsphere: naming consistent with lookup sounds fine to me
[1:28 PM] ttrenka: aszs: well...if we follow the DOM model, it'd be getByIdentity
[1:28 PM] jaxsphere: and searchByIdentity(identifier) looks up an item by an identifier
[1:28 PM] aszs: ttrenka: yes, i agree
[1:28 PM] ttrenka: that seems to leave no ambiguity whatsoever
[1:29 PM] jaxsphere: identifiers only have meaning within the context of a store instance/impl
[1:29 PM] ttrenka: all I care about is making sure that whatever it's called, it's clear as a beel
[1:29 PM] ttrenka: s/beel/bell
[1:29 PM] brian_skinner: clear == good
[1:29 PM] jaxsphere: eg. cant take identifier from one store and use with another store
[1:29 PM] brian_skinner: jaxsphere: yup, agreed
[1:29 PM] aszs: yes
[1:30 PM] brian_skinner: so was there a resolution there?
[1:30 PM] aszs: findByIdentity, getByIdentity, getByKey, i like them all
[1:30 PM] aszs: don't like searchBy* though
[1:30 PM] ttrenka: I'd vote getBy*
[1:30 PM] aszs: +1
[1:30 PM] ttrenka: ...and I'm neutral on Identity vs. Key
[1:30 PM] ttrenka: I like them both
[1:31 PM] aszs: like key better but don't care too much
[1:31 PM] -->| JeffreyH (n=chatzill@adsl-75-5-124-98.dsl.pltn13.sbcglobal.net) has joined #dojo-meeting
[1:31 PM] ttrenka: aszs: exactly my sentiment
[1:31 PM] brian_skinner: hey JeffreyH
[1:31 PM] ttrenka: hey
[1:31 PM] JeffreyH: hi, I'd been thinking you all were talking at 2PM, oops...
[1:32 PM] brian_skinner: JeffreyH: we're working through these agenda items -- http://dojo.jot.com/2006-09-19
[1:32 PM] ttrenka: heh...its 3pm for me :)
[1:32 PM] brian_skinner: okay, item = getByIdentity(string) or item = getByKey(string) both sound good to me
[1:32 PM] jaxsphere: getByIdentity(identity), getIdentity(item) works
[1:33 PM] brian_skinner: let's go with that
[1:33 PM] brian_skinner: getByIdentity(identity), getIdentity(item) works
[1:33 PM] brian_skinner: that seems to have the most support, least objection
[1:33 PM] jaxsphere: next...
[1:33 PM] jaxsphere: fetch() search() query()
[1:33 PM] jaxsphere: search +1
[1:34 PM] ttrenka: neutral again.  I'd actually prefer find, but I'm not picky
[1:34 PM] aszs: i like fetch or query better
[1:34 PM] jaxsphere: lol
[1:34 PM] aszs: i like find too
[1:34 PM] jaxsphere: find ok
[1:34 PM] aszs: +1 find
[1:34 PM] jaxsphere: but that's not one of the options :)
[1:34 PM] ttrenka: +1 find
[1:34 PM] ttrenka: it's a wiki.  we'll make it an option :)
[1:34 PM] jaxsphere: find +1
[1:34 PM] jaxsphere: brian?
[1:34 PM] brian_skinner: sorry
[1:35 PM] brian_skinner: i'm back
[1:35 PM] brian_skinner: find sounds fine to me
[1:35 PM] brian_skinner: so
[1:35 PM] brian_skinner: var result = store.find({query: "all books"});
[1:35 PM] brian_skinner: like that?
[1:35 PM] ttrenka: sure
[1:35 PM] aszs: yes
[1:36 PM] jaxsphere: why not just store.find({params},options)
[1:36 PM] jaxsphere: why the need for query: as a prop?
[1:36 PM] aszs: that's just an example, right?
[1:36 PM] brian_skinner: so, you mean...
[1:36 PM] aszs: query isn't required
[1:36 PM] aszs: i assume
[1:37 PM] brian_skinner: var result = store.find("all books", {async: true});  ??
[1:37 PM] ttrenka: seems like that's just an implementation detail, right?
[1:37 PM] jaxsphere: store.find({name:"Mitch%"},{maxResults:100})
[1:37 PM] ttrenka: hmmm
[1:37 PM] aszs: i like brian's suggestion
[1:37 PM] ttrenka: more like store.find({ name:"Mitch%", maxResults:100 });
[1:37 PM] jaxsphere: y
[1:38 PM] brian_skinner: aszs: you mean the first thing? -- var result = store.find({query: "all books", async: true});
[1:38 PM] aszs: yes
[1:38 PM] ttrenka: one q
[1:38 PM] ttrenka: with something like this:
[1:38 PM] ttrenka: query:"all books"
[1:38 PM] aszs: ttrenka: so that ban attributes named  "maxResults"?
[1:38 PM] aszs: the attributes to test for should be distinct from options
[1:38 PM] jaxsphere: n, that's an option passed to the store implementation
[1:38 PM] ttrenka: I'm assuming that we'll have to have some sort of parser to deal with predicates?
[1:38 PM] brian_skinner: ttrenka: if think store.find({ name:"Mitch%", maxResults:100 }) is confusing -- is maxResults part of the query?
[1:39 PM] ttrenka: no disagreement
[1:39 PM] aszs: maybe all the args can be implementation details
[1:39 PM] jaxsphere: y, its part of the search criteria sent to the backend
[1:39 PM] brian_skinner: ttrenka: re: predicates, that's up to individual data provider implementations
[1:39 PM] ttrenka: perhaps 2 keyword args:  the first would be actual filters, the second be a set of parameters
[1:39 PM] aszs: javascript doesn't require the number of args to be specified
[1:40 PM] aszs: tthenka: yes, but first arg could just be a string, not a dict
[1:40 PM] ttrenka: right
[1:40 PM] jaxsphere: i like idea of just single anonymous obj with various properties used for search params, but do we need to be prescriptive about using "query" as a required prop?
[1:40 PM] aszs: i like that
[1:41 PM] ttrenka: aszs: yeah, JS doesn't require the number of args but it's usually better to have a consistent sig
[1:41 PM] brian_skinner: i think the format of the query should be an implementation detail that different data providers do differently -- but I'd like to see some sort of standard for the async:true part
[1:41 PM] ttrenka: jaxsphere: I think the idea is that the first object would simply specify properties that match attributes of the records in the store
[1:41 PM] aszs: but not necessarily
[1:42 PM] aszs: right?
[1:42 PM] aszs: or do we want that requirement?
[1:42 PM] jaxsphere: i dont think they have to match attributes
[1:42 PM] brian_skinner: aszs: what requirement?
[1:42 PM] aszs: sort of a mini query API?
[1:42 PM] brian_skinner: jaxsphere: +1
[1:42 PM] ttrenka: aszs: I think so
[1:42 PM] brian_skinner: we don't want to get into any spec about what the query itself looks like
[1:42 PM] aszs: that find() handle a dictionary of attributes and match their values
[1:42 PM] ttrenka: right
[1:42 PM] jaxsphere: they can contain other hints to the store for how to deal with partial query results, etc.
[1:42 PM] ttrenka: aszs: that could be just one way of doing it
[1:43 PM] brian_skinner: aszs: i don't think we want that as a requirement
[1:43 PM] ttrenka: ...and then let the second dictionary specify things like maxResults, pageStart, etc.
[1:43 PM] aszs: yes, i don't think so either
[1:43 PM] ttrenka: +1 to not a requirement
[1:44 PM] jaxsphere: it would be nice if we could come up with some "standard" prop names for things like startIndex, numitems, but i dont think we should be prescriptive yet on this
[1:44 PM] ttrenka: I was thinking more along the lines of::
[1:44 PM] aszs: +1 on two args: first specifies the query, 2nd specifies options
[1:44 PM] ttrenka: store.find({ querySearchStuff}, { queryConfigStuff })
[1:44 PM] ttrenka: right
[1:44 PM] brian_skinner: as a real world example, if you're talking to del.ic.ious, the query string will need to look like this: {query: "hillary/medicaid"}
[1:44 PM] jaxsphere: yes
[1:44 PM] ttrenka: +1 on two args
[1:44 PM] jaxsphere: +1 on two args
[1:44 PM] ttrenka: the second being optional
[1:44 PM] jaxsphere: second options args are optional
[1:44 PM] aszs: yes
[1:44 PM] jaxsphere: hehe :)
[1:44 PM] brian_skinner: sounds good
[1:45 PM] brian_skinner: i think we just got consensus
[1:45 PM] brian_skinner: store.find({ querySearchStuff}, { queryConfigStuff })
[1:45 PM] ttrenka: =)
[1:45 PM] aszs: but first arg doesn't need to be {query} could just be "query", right?
[1:46 PM] aszs: find("select * from mytable")
[1:46 PM] brian_skinner: aszs: +1 -- the first arg can be a string or a {} or a Date or whatever the data provider implementation wants it to be
[1:46 PM] jaxsphere: first arg String or {}
[1:46 PM] aszs: yes
[1:46 PM] jaxsphere: +1
[1:47 PM] jaxsphere: that helps with text searches as well
[1:47 PM] jaxsphere: forEach()?
[1:48 PM] brian_skinner: forEach()...
[1:48 PM] jaxsphere: forEach() args -- any specific proposals
[1:48 PM] jaxsphere:     * onCompletion?
[1:48 PM] jaxsphere:     * first/last, first/numItems, start/end?
[1:48 PM] jaxsphere:     * forEach(someCallbackFunction)
[1:48 PM] jaxsphere:     * forEach(someControllerObject, "someCallbackMethod")
[1:48 PM] aszs: the last two
[1:48 PM] ttrenka: i think that no matter what happens, there needs to be a callback method first
[1:48 PM] brian_skinner: i propose we punt on first/last, first/numItems, start/end -- at least for now
[1:48 PM] ttrenka: unless it's part of the controller object
[1:49 PM] aszs: brian: +1
[1:49 PM] ttrenka: brian: I say we don't implement it but keep the idea open in a parameter object
[1:49 PM] ttrenka: ...let me rephrase
[1:49 PM] ttrenka: I still think we should use the same approach as dojo.io.bind
[1:50 PM] ttrenka: which will give us the flexibility to add things like start and end later
[1:50 PM] jaxsphere: so how does this work for large data set results, when i only want a window into hundreds of thousands of records that reside on the server?
[1:50 PM] ttrenka: without revising the api
[1:50 PM] jaxsphere: we need a simple way to do paging
[1:51 PM] brian_skinner: jaxsphere: yup, we do need that -- i was maybe naive in suggesting that we punt for now
[1:51 PM] jaxsphere: and iterating across the entire collection sequentially is also not feasible
[1:51 PM] aszs: jaxsphere: is see that specified in find(options)
[1:52 PM] ttrenka: i think I'm with aszs on this
[1:52 PM] brian_skinner: ttrenka: so you're suggesting that forEach() always takes a single argument, which is a keyword object?
[1:52 PM] ttrenka: brian_skinner: yeah, i think so
[1:52 PM] -->| peller (n=peller@209-6-218-233.c3-0.nwt-ubr2.sbo-nwt.ma.cable.rcn.com) has joined #dojo-meeting
[1:52 PM] brian_skinner: ttrenka: if we do that, what do the forEach(someCallbackFunction) and forEach(someObject, "someCallbackMethod") end up looking like?
[1:52 PM] ttrenka: to me, dojo.io.bind defines "Dojo-ish)"
[1:52 PM] brian_skinner: hi peller
[1:53 PM] ttrenka: hi adam
[1:53 PM] peller: hey.  sorry I'm late/missed the meeting
[1:53 PM] ttrenka: brian: it doesn't.  What would end up happening is that someCallbackMethod is one of the named args
[1:53 PM] brian_skinner: peller: here's the agenda we're working on, and the resolutions we've reached so far: http://dojo.jot.com/2006-09-19
[1:53 PM] ttrenka: brian: in the same way as load is for dojo.io.bind
[1:54 PM] jaxsphere: can we try a scenario?
[1:55 PM] ttrenka: shoot, but I've been tasked by adam :)
[1:55 PM] jaxsphere: :)
[1:55 PM] * peller is thankful that adam is ambiguous here
[1:55 PM] jaxsphere: so we first do a find with params and options...
[1:55 PM] brian_skinner: ttrenka: so, something like this?  results.forEach({callback: someCallbackFunction}); results.forEach({obj: callbackObj, method:"someCallbackMethod"});
[1:55 PM] ttrenka: right
[1:56 PM] brian_skinner: jaxsphere: sorry, didn't mean to interrupt
[1:56 PM] jaxsphere: var results = store.find({all people with last names starting with "a"}
[1:57 PM] brian_skinner: );
[1:57 PM] jaxsphere: results.forEach({callback:function (item){/*print item name*/}});
[1:59 PM] aszs: or find('all people...", {limit=100})
[1:59 PM] jaxsphere: could, but in this case purposely with no limit
[1:59 PM] jaxsphere: but still want this to perform as i display the list
[2:00 PM] aszs: all results are loaded in memory but only some shown at a time
[2:00 PM] jaxsphere: isnt that up to the store impl?
[2:00 PM] jaxsphere: what i want to avoid is loading all items in memory
[2:01 PM] jaxsphere: initially
[2:01 PM] jaxsphere: and specify a range with each access to the results
[2:01 PM] brian_skinner: seems like a store is free to not load all the items until they're actually looped over
[2:01 PM] aszs: we talked about this last week
[2:01 PM] brian_skinner: :-)
[2:01 PM] aszs: the problem with start and stop on forEach
[2:01 PM] aszs: is that it introduces state
[2:02 PM] aszs: sorry doesn't introduce state
[2:02 PM] jaxsphere: y, but lets assume i have a client server impl of a store
[2:02 PM] jaxsphere: and assume that my store impl can maintain a session
[2:03 PM] aszs: ok
[2:03 PM] jaxsphere: the client needs to coordinate with the server to work efficiently
[2:03 PM] aszs: why not do that with find()?
[2:04 PM] ttrenka: sorry, popping back
[2:04 PM] ttrenka: I'd vote for find dealing with server comm
[2:04 PM] jaxsphere: so are you saying in find, specify the pagin options, then in all subsequent forEach, the options specified by the orig find will always be used?
[2:04 PM] ttrenka: and forEach to be a pure client side thing
[2:05 PM] jaxsphere: how do i page backwards?
[2:05 PM] aszs: issue a new find()
[2:05 PM] jaxsphere: i have a scrolling table, and am in the middle of 1000 records.  I've already performed a search and specified my params to get a result set
[2:06 PM] aszs: redo the search with new parameters
[2:06 PM] jaxsphere: as user scrolls down, window pulls in next 50 items in oob xhr
[2:06 PM] jaxsphere: and prev 50 items destroyed/gc'd to reduce mem
[2:07 PM] aszs: ok
[2:07 PM] jaxsphere: so perform same search with same query params, and different options
[2:07 PM] jaxsphere: this doesnt seem intutive
[2:07 PM] aszs: that's one approach
[2:07 PM] aszs: ok here's the crux of it:
[2:08 PM] aszs: can you call forEach more than once on the result?
[2:08 PM] jaxsphere: right
[2:08 PM] ttrenka: +1 on calling forEach more than once
[2:08 PM] jaxsphere: does for each iterate across the entire extent of the results
[2:08 PM] aszs: if you can the store needs to cache the results itself or reissue the query
[2:09 PM] jaxsphere: if not, how do you reposition it
[2:09 PM] ttrenka: jaxsphere: I think that's part of what were were discussing in terms of what to pass to forEach
[2:09 PM] aszs: so i don't see how your gonna save on memory
[2:10 PM] jaxsphere: neither of these options allow for me to reposition:  * forEach(someCallbackFunction)
[2:10 PM] jaxsphere: * forEach(someControllerObject, "someCallbackMethod")
[2:10 PM] jaxsphere: i like this for iteration, but still need paging
[2:11 PM] jaxsphere: results.setStartOffet(1000); results.setNumItems(50); do forEach?
[2:11 PM] aszs: better to have args on forEach no?
[2:12 PM] jaxsphere: and use getLength to tell if past end?
[2:12 PM] jaxsphere: aszs: i would prefer that
[2:12 PM] aszs: jaxsphere: how do use getLength() for that?
[2:13 PM] jaxsphere: is getLength is the "count" of the num items in the full result set, or just the num of items in the window?
[2:13 PM] jaxsphere: i assumed its the number of items in the full result set
[2:13 PM] jaxsphere:    Returns an integer -- the number of items in the result list.
[2:14 PM] jaxsphere: on the current api
[2:14 PM] aszs: jaxsphere: sorry, i was being dence
[2:14 PM] brian_skinner: i also assumed it was the number in the full result set
[2:15 PM] jaxsphere: So we use this for the example of how to page on a large result set...
[2:15 PM] jaxsphere: 		   results.forEach(callbackFunction, {first: 201, last: 300}); // partial loop
[2:15 PM] jaxsphere: 		   results.forEach(callbackFunction, {first: 200, numItems: 50}); // partial loop from 200 to 250
[2:16 PM] aszs: this requires to store to save the whole result set in memory, right?
[2:16 PM] aszs: you're ok with that?
[2:16 PM] jaxsphere: but won't be prescriptive about the names of the paging args used by a particular store implementaiton
[2:17 PM] brian_skinner: aszs: a simple implementation could store and save the whole result set in memory, but the API doesn't force the data provider to be implemented that way
[2:17 PM] jaxsphere: this requires to store to save the whole result set in memory, right? <-- I guess this is the question...does it requre keeping entire set in memory
[2:18 PM] brian_skinner: there's no reason that the results.forEach(callbackFunction, {first: 201, last: 300}) couldn't trigger a client/server query to get the next 100 results
[2:18 PM] aszs: a store with connection object and server side api for iterating through the cursor
[2:18 PM] jaxsphere: i think we're assuming that the store will do a for each over a dojo collection like an array
[2:19 PM] aszs: but if a store doesn't support that (and most won't!)
[2:19 PM] jaxsphere: but the collection impl can be smart and keep a cache of just items needed based on forEach access with args
[2:20 PM] aszs: then the requirement that forEach is called more than once means it will have to remember them...
[2:20 PM] aszs: hmm, i guess i'm wrong:
[2:20 PM] aszs: it instead could just re-do the whole query...
[2:22 PM] jaxsphere: doesnt need to redu the whole query.  the query results  from the initial find() can be kept server side, and the client store can just request a page of those results (based on forEach params)... this is common today with search engines
[2:22 PM] aszs: so where should the implementation burden lie: for the store or the widget?
[2:22 PM] jaxsphere: I think we just need to clarify the api docs for forEach
[2:23 PM] aszs: but the initial find() doesn't specify the range
[2:24 PM] aszs: unless it by default just gets the first page of results...
[2:24 PM] jaxsphere: y
[2:24 PM] ttrenka: sorry I haven't been paying more attention
[2:25 PM] ttrenka: seems like we're overthinking this though
[2:25 PM] ttrenka: server/paging specs would basically be up to the implementation, right>?
[2:25 PM] aszs: i'm trying to make it easy to implement stores
[2:25 PM] jaxsphere: i think the forEach api that's there is ok, but we should clarify that it can be called more than once
[2:25 PM] ttrenka: aszs: of course :)
[2:26 PM] brian_skinner: ttrenka: i think dealing with large results sets may be a common problem
[2:26 PM] jaxsphere: yes, using the optional args {} after callbackFunction
[2:26 PM] ttrenka: jaxsphere: you can call the iterators in collections more than once too
[2:26 PM] aszs: allowing forEach more than once makes it harder
[2:26 PM] jaxsphere: aszs, the case for store that dont do paging is still simple
[2:26 PM] brian_skinner: aszs: why does allowing forEach more than once make it harder?
[2:27 PM] ttrenka: brian_skinner:  understood but we don't need to bake that into the api signature; we just need to be sure that we've kept the signatures open enough to take that into account later on
[2:28 PM] aszs: brian: because store needs to either store all the results, reissue the query, or support some sort of session management wiht the server
[2:28 PM] brian_skinner: aszs: right, but aren't those first two options both easy to implement?
[2:28 PM] aszs: if the foreach is just like an iterator that exhauts itself, the store just gets the results and sends it along
[2:28 PM] jaxsphere: Possible examples with current api... we're just saying that we *do* need the optional args so that we can impl more complex things like paging, but we just don't want to be prescriptive of what the arg names are right now...they will vary by store impl
[2:28 PM] jaxsphere: 		    results.forEach(someCallbackObject, "someCallbackMethod");
[2:28 PM] jaxsphere: 		    results.forEach(callbackFunction, {onCompletion: finishedFunction});
[2:28 PM] jaxsphere: 		    results.forEach(callbackFunction, {first: 201, last: 300}); // partial loop
[2:28 PM] jaxsphere: 		    results.forEach(callbackFunction, {first: 200, numItems: 50}); // partial loop from 200 to 250
[2:29 PM] aszs: brian_skinner: easy and inefficient -- make the api user do that make that clear, or have user use find() to support it in options
[2:30 PM] jaxsphere: and that do paging forEach must be callable more than once on same result set with different args, funcs... I assumed that was the case from the api docs, but prob want to note this in the api doc
[2:32 PM] ttrenka: jaxsphere: yeah, I'd agree with that
[2:32 PM] ttrenka: I don't see anything wrong with being able to call forEach more than once, personally
[2:32 PM] |<-- peller has left freenode ()
[2:34 PM] brian_skinner: i don't have a strong opinion about all this myself -- i'd like to reach some resolution and move on, but i don't get the sense that we've reach a consensus, is that right?
[2:35 PM] brian_skinner: leave it as an open issue for next week ;-)
[2:36 PM] jaxsphere: in the current api, we allow args on for each.  can we agree that we don't specify what the args are, but that for each can be called multiple times?
[2:36 PM] aszs: ok
[2:36 PM] ttrenka: i think we won't agree on something until there's a better idea of what implementations are going to take
[2:36 PM] brian_skinner: i'm okay with that
[2:36 PM] ttrenka: +1 on that
[2:36 PM] -->| peller (n=peller@209-6-218-233.c3-0.nwt-ubr2.sbo-nwt.ma.cable.rcn.com) has joined #dojo-meeting
[2:37 PM] jaxsphere: we may need to revisit after implementing this in a couple providers, but i think it leaves the door open enough to do advanced cases
[2:37 PM] brian_skinner: so, can we go back quickly to ttrenka's suggestion about using a keyword args object, like dojo.io.bind does?
[2:38 PM] brian_skinner: results.forEach({callback:function (item){/*print item name*/}});
[2:38 PM] brian_skinner: vs.
[2:38 PM] ttrenka: wait
[2:38 PM] ttrenka: how about this:
[2:38 PM] brian_skinner: results.forEach(function (item){/*print item name*/});
[2:38 PM] ttrenka: forEach takes one arg
[2:38 PM] ttrenka: if that arg is a function, it's a callback
[2:38 PM] ttrenka: if it's an object, it's the advanced keyword object
[2:38 PM] ttrenka: sound fair?
[2:38 PM] brian_skinner: +1
[2:39 PM] ttrenka: that way we keep the simple case but keep the more advanced flexibility
[2:39 PM] aszs: +1
[2:39 PM] ttrenka: +1
[2:39 PM] brian_skinner: in the keyword object, what are the two standard keywords for the object/method callback case
[2:39 PM] brian_skinner: ?
[2:39 PM] jaxsphere: so no (object,handler) case?
[2:40 PM] jaxsphere: where handler is a function on object scope
[2:40 PM] ttrenka: jaxsphere: right
[2:40 PM] brian_skinner: results.forEach({object: handlerObject, method:"handlerMethod"});
[2:40 PM] ttrenka: +1
[2:41 PM] jaxsphere: +1
[2:41 PM] -->| rcoup (n=rcoup@p549C2F41.dip0.t-ipconnect.de) has joined #dojo-meeting
[2:41 PM] aszs: does io.bind() handle load: "method"?
[2:41 PM] brian_skinner: so "object" and "method" as the two keywords?
[2:41 PM] ttrenka: aszs: yep
[2:41 PM] ttrenka: that's how it works.
[2:41 PM] aszs: what's the param name for the object?
[2:41 PM] ttrenka: do we need to decide that right now?
[2:42 PM] aszs: ttrenka: i mean in io.bind?
[2:42 PM] ttrenka: no, I mean decide on what keywords will be used in the keyword object
[2:42 PM] jaxsphere: this is like kwConnect too
[2:42 PM] ttrenka: right
[2:42 PM] ttrenka: oh
[2:42 PM] brian_skinner: ttrenka: i don't think we need to decide on all possible keywords, but these two seem important
[2:42 PM] ttrenka: aszs: it's load: function(type, data, http){ ... }
[2:43 PM] ttrenka: not a string
[2:43 PM] aszs: yes
[2:43 PM] brian_skinner: dojo.event.kwConnect() uses "targetObj" and "targetFunc" -- i'm not crazy about those name
[2:43 PM] aszs: i was wondering if it supported brian's case
[2:43 PM] aszs: it == "bind"
[2:44 PM] aszs: i'm looking at the source and i doesn't look like it does
[2:44 PM] brian_skinner: aszs: i'm looking at the docs and it doesn't look like it does
[2:45 PM] brian_skinner: but i'd like forEach() to support it anyway, even if dojo.io.bind doesn't provide a precident
[2:45 PM] brian_skinner: it'll be a annoying to implement controller objects without it
[2:46 PM] jaxsphere: skinner: i agree
[2:47 PM] aszs: maybe ask the list, maybe there's a global style
[2:47 PM] brian_skinner: aszs: okay, i can do that
[2:47 PM] aszs: the deferred object does support both
[2:49 PM] brian_skinner: aszs: what keywords does deferred use?
[2:49 PM] aszs: no keywords
[2:49 PM] aszs: variable length args
[2:50 PM] brian_skinner: i see -- no help then
[2:50 PM] aszs: no
[2:51 PM] jaxsphere: are we going to end now?
[2:51 PM] aszs: ok
[2:51 PM] ttrenka: ok
[2:51 PM] jaxsphere: seems like things slowed down :)
[2:51 PM] ttrenka: sorry I wasn't paying more attention
[2:52 PM] ttrenka: been trying to get documentation done and ended up screwing up with a bunch of syntax errors
[2:52 PM] brian_skinner: sorry, i was just off updating the meeting notes
[2:52 PM] brian_skinner: i'm game to quit for the week
[2:52 PM] jaxsphere: aszs, for the minor issues you talked about at beginning of irc, can u post ot contrib list?
[2:52 PM] aszs: yes.
[2:52 PM] brian_skinner: also game to go on to the save() API, if anyone has energy
[2:52 PM] aszs: but here too:
[2:53 PM] aszs: * get/getValues(): if item isn't present return undefined
[2:53 PM] aszs: get() return null if attribute is present but has no values?
[2:53 PM] aszs: Result.getlength = null; //null until completion ?
[2:53 PM] ttrenka: works for me
[2:53 PM] jaxsphere: ah
[2:53 PM] jaxsphere: y
[2:53 PM] aszs: signature of errBack, (& use for timeout?)?
[2:54 PM] jaxsphere: Result.getlength = null; //null until completion ?<== This will always return the number of results met by the original find()
[2:54 PM] jaxsphere: should never be null
[2:55 PM] aszs: what if the store doesn't know?
[2:55 PM] aszs: if results are streaming?
[2:55 PM] jaxsphere: eww
[2:55 PM] brian_skinner: right, find() returns a result object immediately
[2:55 PM] brian_skinner: so the response may not have come back yet
[2:55 PM] brian_skinner: :-(
[2:56 PM] aszs: options: null, -1, throw exception
[2:56 PM] aszs: or 0
[2:56 PM] brian_skinner: not 0, that would be ambigous
[2:56 PM] ttrenka: +1 on -1
[2:56 PM] jaxsphere: results.hasResults() bool
[2:57 PM] ttrenka: results.inProgress()
[2:57 PM] jaxsphere: y, better
[2:57 PM] brian_skinner: the current wiki page says: Returns -1 if the length is not known when the method is called.
[2:57 PM] ttrenka: sounds good to me
[2:57 PM] aszs: -1 +1
[2:57 PM] brian_skinner: null seems fine too
[2:57 PM] brian_skinner: -1 fits better with how the basic javascript functions work
[2:58 PM] ttrenka: either way works for me, but -1 feels more JS ish
[2:58 PM] brian_skinner: e.g. string search functions
[2:58 PM] jaxsphere: +1 on -1 length unknown
[2:58 PM] jaxsphere: +1 to add results.inProgress()
[2:58 PM] aszs: or we could copy deferred state field
[2:59 PM] brian_skinner: inProgress() returns a boolean? true if the results have not finished loading?
[2:59 PM] jaxsphere: is inProgress()===true precondition for forEach?
[2:59 PM] ttrenka: one other thing:  if results is working like deferred, I'd also like there to be a pass through abort method
[2:59 PM] jaxsphere: or will forEach block
[2:59 PM] ttrenka: brian_skinner: yeah, sorry, that'd be bool
[2:59 PM] aszs: foreach doesn't block
[2:59 PM] ttrenka: +1 on not blocking
[2:59 PM] brian_skinner: ttrenka: we have a cancel() method now -- is that the same thing?
[2:59 PM] aszs: but inProgress() could be false
[3:00 PM] jaxsphere: sorry, i meant inProgress()===false
[3:00 PM] ttrenka: brian_skinner: as long as cancel will fire abort on the xmlhttp object being used to get records, then yes.
[3:00 PM] ttrenka: :)
[3:00 PM] ttrenka: that's turned into a major issue for me with other streaming things
[3:00 PM] ttrenka: i'd like to avoid that here if possible
[3:01 PM] brian_skinner: forEach() doesn't block, but it doesn't need inProgress() to be false -- it could just wait until the results are available to start calling the callback
[3:01 PM] brian_skinner: ttrenka: i see -- i guess cancel() and abort() are different
[3:01 PM] jaxsphere: makes sense...starts iterating over items receieved so far
[3:02 PM] brian_skinner: bummer, this is getting complicated
[3:02 PM] aszs: another reason for foreach to only called once ;)
[3:02 PM] ttrenka: well, I guess the abort thing would be implementation specific
[3:03 PM] brian_skinner: so in practice, could inProgress() just be implemented as: return (this.getLength() == -1);  ?
[3:03 PM] ttrenka: yeah
[3:04 PM] |<-- peller has left freenode ()
[3:04 PM] brian_skinner: okay, was there a decision to add inProgress?
[3:05 PM] jaxsphere: so if you have partial results and are iterating items via for each, and call getLength()...
[3:05 PM] ttrenka: i think it was a plus one...
[3:06 PM] -->| DojoLog (n=stats@reigndropsfall.net) has joined #dojo-meeting
[3:06 PM] aszs: jaxsphere: good point
[3:06 PM] jaxsphere: get length gives you the items recieved in the licent so far
[3:06 PM] jaxsphere: ?
[3:06 PM] aszs: no
[3:06 PM] jaxsphere: right...its like count()
[3:06 PM] jaxsphere: the num items from the initial find()
[3:07 PM] aszs: but maybe the store got some metadata with the result size
[3:07 PM] brian_skinner: aszs: right, good point
[3:07 PM] aszs: so inProgress() would be true but getLength() has a real value
[3:08 PM] brian_skinner: aszs: yup
[3:09 PM] brian_skinner: going back to another question
[3:09 PM] brian_skinner: aszs:	* get/getValues(): if item isn't present return undefined
[3:09 PM] ttrenka: guys, I'm sorry but I gotta run
[3:09 PM] brian_skinner: okay, thanks for coming ttrenka
[3:09 PM] jaxsphere: thanks tom
[3:09 PM] ttrenka: no worries, talk to y'all tomorrow
[3:09 PM] |<-- ttrenka has left freenode ()
[3:09 PM] aszs: thanks
[3:10 PM] aszs: brian: either undefined or raise an exception?
[3:10 PM] brian_skinner: for that get/getValues() question, should we throw an exception if item isn't defined?  or did you mean to say attribute?
[3:10 PM] aszs: item
[3:11 PM] brian_skinner: throw an exception
[3:11 PM] aszs: ok
[3:11 PM] jaxsphere: i need to go as well, but could do another meeting later this week if you want
[3:11 PM] brian_skinner: i can't see how that would ever be something other than a coding error
[3:11 PM] brian_skinner: jaxsphere: i'm free any day this week
[3:11 PM] aszs: an item is just id
[3:12 PM] brian_skinner: aszs: no, an item is an object -- some sort of opaque item handle
[3:12 PM] aszs: i could meet but i'd like to finish my implementation first
[3:12 PM] jaxsphere: how about Thurs 4pm est (1pm cst)
[3:12 PM] aszs: yes but it just maps to a key in a dict in my implementation
[3:13 PM] brian_skinner: jaxsphere: that time works for me
[3:13 PM] brian_skinner: aszs: oh, yes -- in some implementations it might just be a string
[3:13 PM] jaxsphere: k, will mark cal...have a good night!
[3:13 PM] brian_skinner: jaxsphere: thanks for coming
[3:13 PM] aszs: bye
[3:14 PM] <--| jaxsphere has left #dojo-meeting
[3:14 PM] brian_skinner: aszs: still, even if it is just a string, how would you ever end up calling store.get() and passing in something other than an item id string?
[3:15 PM] aszs: you might have some id string from some other source... with my rdf store the id is just the URI... in a openrecord store a UUID
[3:16 PM] brian_skinner: i see
[3:16 PM] aszs: but raising an exception is fine
[3:16 PM] aszs: in any event
[3:16 PM] aszs: ok, just changed my code to raise an exception
[3:16 PM] brian_skinner: yup, i guess i'm still in favor of raising an exception
[3:17 PM] brian_skinner: the caller can always do a store.isItem(item) check first, if they want to avoid ever getting exceptions
[3:17 PM] aszs: yes
[3:18 PM] aszs: well should we adjourn?
[3:18 PM] brian_skinner: yup, sounds good
[3:18 PM] brian_skinner: thanks for coming!
[3:18 PM] aszs: thanks for keeping these meetings going...
[3:19 PM] aszs: hopefully i'll have a test store up and running in a couple of days
[3:19 PM] brian_skinner: cool
[3:19 PM] brian_skinner: if I have time i'll start working on unit tests

Attachments (0)

  File By Size Attached Ver.