On Tue, Feb 1, 2011 at 2:56 PM, Jonas Sicking <jo...@sicking.cc> wrote:
> On Tue, Feb 1, 2011 at 11:44 AM, Jeremy Orlow <jor...@chromium.org> wrote: > > On Tue, Feb 1, 2011 at 10:07 AM, Hans Wennborg <h...@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. Good points (against having it remove the original key if it changes). After some more thought: The original idea behind cursor.delete() and cursor.update() was that they would basically just be aliases for objectStore.delete() and objectStore.put(). Maybe calling .update() with a changed primary key should simply have the same behavior as .put(). Thus the value corresponding to the original key would be left unmodified and the new key would then correspond to the new value. I can't think of any examples where the current behavior would get in someone's way though. So I guess maybe we should just leave it as is. But I still hate the idea of it being subtly different from being a straight up alias to put. J