RE: [indexeddb] Do we need to support keyPaths with an empty string?

On Friday, January 20, 2012 2:31 PM, Jonas Sicking wrote:
> On Fri, Jan 20, 2012 at 12:23 PM, ben turner <bent.mozilla@gmail.com> wrote:
> > Mozilla is fine with removing the special |keyPath:""| behavior.
> > Please note that this will also mean that step 1 of the algorithm here
> >
> >
> > http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#dfn-steps-f
> > or-extracting-a-key-from-a-value-using-a-key-path
> >
> > will need to change.
> >
> > We do want to continue to allow set behavior without specifying the
> > key twice, though, so we would propose adding an additional option to
> > createObjectStore to accomplish this:
> >
> >  // Old way:
> >  var set = db.createObjectStore("mySet", { keyPath:"" });
> >  set.put(keyValue);
> >
> >  // New way:
> >  var set = db.createObjectStore("mySet", { isSet: true });
> >  set.put(keyValue);
> >
> > (We are not in love with "isSet", better names are highly encouraged!)
> >
> > What do you all think? This would allow us to continue to support nice
> > set behavior without making the empty string "magic".
> 
> I actually think that the current behavior that we have is pretty consistent. Any
> time you give the keyPath property a string we create an objectStore with a
> keyPath. And any time you have an objectStore with a keyPath you are not
> allowed to pass an explicit key since the key is gotten from the keyPath. There's
> no special handling of empty strings happening.
> 
> But I do agree that it can be somewhat confusing to tell ""/null/undefined apart
> since they are all falsy. In particular, an expression like
> 
> if (myObjectStore.keyPath) {
>   ...
> }
> 
> doesn't work to test if an objectStore has a keyPath or not. You instead need to
> check
> 
> if (myObjectStore.keyPath != null) {
>   ...
> }
> 
> or
> 
> if (typeof myObjectStore.keyPath == "string") {
>   ...
> }
> 
> Hence the "isSet" suggestion.
> 
> Though I also realized after talking to Ben that empty keyPaths show up in
> indexes too. Consider creating a objectStore which maps peoples names to
> email addresses. Then you can create an index when does the opposite
> mapping, or which ensures that email addresses are unique:
> 
> var store = db.createObjectStore("people"); var index =
> store.createIndex("reverse", "", { unique: true });
> store.add("john.doe@email.com", "John Doe"); store.add("mike@smith.org",
> "Mike Smith");
> 
> store.get("John Doe").onsuccess = function(e) {
>   alert("John's email is " + e.target.result); }
> index.getKey("mike@smith.org").onsuccess = function(e) {
>   alert("mike@smith.org is owned by " + e.target.result); }
> 
> Are people proposing we remove empty keyPaths here too?
> 
> / Jonas

Yes, I'm proposing removing empty string KeyPaths all together to avoid confusion.
I would like to know how often you expect developers to follow this pattern
instead of using objects.  Our believe is that objects will be the main value stored in object stores 
instead of single values.

Supporting keyPath with empty strings brings up all kinds of side effects. For example:

var store = db.createObjectStore("people"); 
var index = store.createIndex("reverse", "", { unique: true });
store.add({email: "john.doe@email.com"}, "John Doe"); 
store.add({email: "mike@smith.org"},"Mike Smith");

What should happen in this case, do we throw an exception? This is the scenario we see in FF and Chrome.
I don't believe it will be obvious to developers that this functionality behaves differently depending on the 
value being stored.

Having some type of flag seems more promising for object stores.  However, we still need to figure out how to deal with 
Indexes on sets, do we pass another flag to support the indexes on sets?  If we do that, then what do we do with the keyPath parameter to an index.
It seems we're overloading the functionality of these methods to support different patterns.

Israel

Received on Friday, 20 January 2012 23:39:40 UTC