Re: IndexedDB: updates through cursors on indexes that change the key

On Tue, Feb 1, 2011 at 11:44 AM, Jeremy Orlow <jorlow@chromium.org> wrote:
> On Tue, Feb 1, 2011 at 10:07 AM, Hans Wennborg <hans@chromium.org> wrote:
>>
>> For cursors on object stores, we disallow updates that change the key:
>> one cannot provide an explicit key, and for object stores with a key
>> path, the spec says that "If the effective object store of this cursor
>> uses in-line keys and evaluating the key path of the value parameter
>> results in a different value than the cursor's effective key, this
>> method throws DATA_ERR."
>>
>> I suppose the reason is that an implementation may have trouble
>> handling such updates, i.e. changing the keys that the cursor iterates
>> over during the iteration is a bad idea.
>>
>> A similar situation can occur with cursors over indexes:
>>
>> Say that there is an object store with objects like {fname: 'John',
>> lname: 'Doe', phone: 1234}, and an index with 'fname' as key path.
>> When iterating over the index with a cursor, should it be allowed to
>> update the objects so that the key in the index, in this case the
>> 'fname', of an object is changed? The situation seems analogous to the
>> one above, but as far as I can see, the spec does not mention this.
>> Should it be allowed?
>>
>> I would be interested to hear your thoughts on this.
>
> I think we should remove the original limitation instead.  While a cursor is
> happening, anyone can call .remove() and .put() which is essentially the
> same as doing an .update() which changes a key.  So implementations will
> already need to handle this case one way or another.  What's there seems
> like a fairly artificial limitation.

The tricky part if you allow modifying the primary key is defining the
exact semantics around that, especially going forward if we add things
like events or audit logs or anything like that (something like that
is likely going to be needed for syncing). As things stand now, a call
to cursor.update() is semantically equivalent to a call to
objectStore.put(). If we allow modifying the key that is no longer the
case.

So we would then need to define things like does cursor.update() equal
objectStore.remove() and then objectStore.add() always? Or just when
the key is actually changed? And what happens if the new key already
exists in the database? Does that undo both the remove() and the
add(), fail, or do you risk losing the entry? Or does cursor.update()
equal objectStore.remove() and then objectStore.put() such that if an
entry with the key already exists, it is overwritten?

So I don't think the concern here is about confusing the cursor
object. Like Jeremy points out, cursors have to deal with the iterated
data changing anyway. I think the main reason for the current
restriction is to keep the set of operations that you can perform on
the data simpler.

Of course, if there is reason to allow modifying the primary key, then
we'll just have to deal with the more complex set of allowed
operations. But then it would probably also make sense to allow
modifying the primary key of an existing entry directly on the
objectStore, without having to go through a cursor.

/ Jonas

Received on Tuesday, 1 February 2011 23:03:23 UTC