Re: IndexedDB >> Proposed API Change: cursor.advance BACKWARD when direction is "prev"

On Fri, May 23, 2014 at 9:40 AM, marc fawzi <marc.fawzi@gmail.com> wrote:

> I thought .continue/advance was similar to the 'continue' statement in a
> for loop in that everything below the statement will be ignored and the
> loop would start again from the next index. So my console logging was
> giving confusing results. I figured it out and it works fine now.
>

Thanks for following up! At least two IDB implementers were worried that
you'd found some browser bugs we couldn't reproduce.


> For sanity's sake, I've resorted to adding a 'return'  in my code in the
> .success callback after every .advance and .continue so the execution flow
> is easier to follow. It's very confusing, from execution flow perspective,
> for execution to continue past .continue/.advance while at once looping
> asynchronously. I understand it's two different instances of the .success
> callback but it was entirely not clear to me from reading the docs on MDN
> (for example) that .advance / .continue are async.
>

Long term, we expect JS to evolve better ways of expressing async calls and
using async results. Promises are a first step, and hopefully the language
also grows some syntax for them. IDB should jump on that train somehow.


> Also, the description of .advance in browser vendor's documentation, e.g.
> on MDN, says "Advance the cursor position forward by two places" for
> cursor.advance(2) but what they should really say is "advance the cursor
> position forward by two results." For example, let's say cursor first
> landed on an item with primary key = 7, and you issue the statement
> cursor.advance(2), I would expect it to go to the item with primary key 5
> (for cursor direction = "prev") but instead it goes to the item with
> primary key 2 because that's the 2nd match for the range argument from the
> cursor's current position
>

What "range argument" are you referring to?

Assuming the store has [1,2,3,4,5,6,7,8,9] and the cursor's range is not
restricted, if the cursor's key=7 and direction='prev' then I would expect
after advance(2) that key=5. If you're seeing key=2 can you post a sample
somewhere (e.g. jsfiddle.com?)


> , which means that .advance(n) would be far more clear semantically
> speaking if it was simply done as .continue(n)  ... I guess if there is an
> understanding that the cursor is always at a matching item and that it
> could only continue/advance to the next/prev matching item, not literal
> 'positions' in the table (i.e. sequentially through the list of all items)
> then there would be no confusion but the very concept of a cursor is
> foreign to most front end developers, and that's where the confusion comes
> from for many.
>
> My inclination as a front end developer, so far removed from database
> terminology, would be
>
> 1) to deprecate .advance in favor of .continue(n) and
>

continue(n) already has meaning - it jumps ahead to the key with value n


>
> 2) if it makes sense (you have to say why it may not) have
> .continue()/.continue(n) cause the return of the execution flow similar to
> 'continue' in a for loop.
>

The API can't change the language - you return from functions via return or
throw. Further, there are reasons you may want to do further processing
after calling continue() - e.g. there may be multiple cursors (e.g. in a
join operation) or for better performance you can call continue() as early
as possible so that the database can do its work while you're processing
the previous result.



>
> What do you think?
>
>
>
> On Wed, May 21, 2014 at 10:42 AM, Joshua Bell <jsbell@google.com> wrote:
>
>>
>>
>>
>> On Wed, May 21, 2014 at 7:32 AM, Arthur Barstow <art.barstow@gmail.com>wrote:
>>
>>> [ Bcc www-tag ; Marc - please use public-webapps for IDB discussions ]
>>>
>>> On 5/20/14 7:46 PM, marc fawzi wrote:
>>>
>>>> Hi everyone,
>>>>
>>>> I've been using IndexedDB for a week or so and I've noticed that
>>>> cursor.advance(n) will always move n items forward regardless of cursor
>>>> direction. In other words, when the cursor direction is set to "prev" as
>>>> in: range = IDBKeyRange.only(someValue, "prev") and primary key is
>>>> auto-incremented, the cursor, upon cursor.advance(n), will actually advance
>>>> n items in the opposite direction to the cursor.continue() operation.
>>>
>>>
>> That runs contrary to the spec. Both continue() and advance() reference
>> the "steps for iterating a cursor" which picks up the direction from the
>> cursor object; neither entry point alters the steps to affect the direction.
>>
>> When you say "you've noticed", are you observing a particular browser's
>> implementation or are you interpreting the spec? I did a quick test and
>> Chrome, Firefox, and IE all appear to behave as I expected when intermixing
>> continue() and advance() calls with direction 'prev' - the cursor always
>> moves in the same direction regardless of which call is used.
>>
>> Can you share sample code that demonstrates the problem, and indicate
>> which browser(s) you've tested?
>>
>>
>>
>>
>>>  This is not only an issue of "broken symmetry" but it presents an
>>>> obstacle to doing things like: keeping a record of the primaryKey of the
>>>> last found item (after calling cursor.continue for say 200 times) and, long
>>>> after the transaction has ended, call our search function again and, upon
>>>> finding the same item it found first last time, advance the cursor to the
>>>> previously recorded primary key and call cursor.continue 200 times, from
>>>> that offset, and repeat whenever you need to fetch the next 200 matching
>>>> items. Such algorithm works in the forward direction (from oldest to newest
>>>> item) because cursor.advance(n) can be used to position the cursor forward
>>>> at the previously recorded primary key (of last found item) but it does not
>>>> work in the backward direction (from newest to oldest item) because there
>>>> is no way to make the cursor advance backward. It only advances forward,
>>>> regardless of its own set direction.
>>>>
>>>> This example is very rough and arbitrary. But it appears to me that the
>>>> cursor.advance needs to obey the cursor's own direction setting. It's
>>>> almost like having a car that only moves forward (and can't u-turn) and in
>>>> order to move backward you have to reverse the road. That's bonkers.
>>>>
>>>> What's up with that?
>>>>
>>>> How naive or terribly misguided am I being?
>>>>
>>>> Thanks in advance.
>>>>
>>>> Marc
>>>>
>>>
>>>
>>>
>>
>

Received on Friday, 23 May 2014 17:41:56 UTC