W3C home > Mailing lists > Public > public-webapps@w3.org > April to June 2010

Re: [IndexedDB] KeyPaths and missing properties.

From: Jeremy Orlow <jorlow@chromium.org>
Date: Thu, 20 May 2010 10:47:41 +0100
Message-ID: <AANLkTin1CFvh5AwJx6gYSamyIUtLbUEt1fzGByURcX7a@mail.gmail.com>
To: Jonas Sicking <jonas@sicking.cc>
Cc: Webapps WG <public-webapps@w3.org>
On Thu, May 20, 2010 at 1:24 AM, Jonas Sicking <jonas@sicking.cc> wrote:

> On Wed, May 19, 2010 at 4:58 PM, Jeremy Orlow <jorlow@chromium.org> wrote:
> > On Wed, May 19, 2010 at 9:38 PM, Jonas Sicking <jonas@sicking.cc> wrote:
> >>
> >> On Wed, May 19, 2010 at 2:36 AM, Jeremy Orlow <jorlow@chromium.org>
> wrote:
> >> > Interesting you'd bring this up.  Andrei and I were just looking at
> >> > indexes
> >> > as specced and wondered whether it still makes sense to allow indexes
> to
> >> > not
> >> > have a keyPath.
> >>
> >> I think so. Consider for example a objectStore that contains entries
> like:
> >>
> >> { name: "Elvis Presley", born: "1935-1-8", death: "1977-8-16" }
> >>
> >> But index on how old the person was when he/she died. I guess you
> >> could require that people store a property containing the age, however
> >> it seems unfortunate to require modifying the stored data.
> >>
> >> Worse, you might have entries like:
> >>
> >> { id: 5, givenName: "Benny", otherNames: ["Göran", "Bror"],
> >> familyName: "Andersson", age: 63, interest: "Music" }
> >>
> >> in order to search for people, you might want to search for a name, no
> >> matter if that is a given name, a family name, or second name.
> >> Currently you can accomplish this by inserting 4 entries into an
> >> index, all pointing to the same entry in the objectStore. I can't
> >> think of a sane way to accomplish this using only keyPath.
> >
> > I think the main use case here is the need to allow an unknown quantity
> of
> > entries in the index to one entry in the objectStore.  What if we allowed
> > keyEntry's to be any javascript expression and allow them to return
> arrays
> > of indexible data.  In this case, the expression would return an array of
> > otherNames + the givenName + the familyName.  The keyPath already is
> > essentially just a javascript expression, so this doesn't seem like too
> big
> > of a leap.
> > This would also support your age upon death use case.  (Though I think
> > requiring the developer to store that age if they want it indexed isn't
> too
> > bad of an answer either.)
> > Thoughts?
> I think it's an interesting idea, and one that came up when we were
> talking to developers way back before IndexedDB spec was started.
> However then we more discussed it in the sense that libraries would be
> using the technique, rather than that the API would use it.

I agree this is on the borderline between something we should leave to
libraries (for at least v1) and something we should spec now.

The problem with using a javascript expression is how do you provide
> it? If you're allowed to pass in a function, that also means that
> you're pulling in the full scope of that function. This obviously
> doesn't work since the index generally outlives the scope and is used
> in other browsing sessions and other tabs.

Sorry, I should have been more clear.  I think a string (like what's
currently specced) is definitely the way to go.  You're right about the
scoping issues, but what if we ran the expressions without access to the
global scope?  In addition to solving this problem (index works when you
first create it, but next time you open the browser it does't) it'd also
keep developers from doing really horrible things...like doing synchronous

> So you'd have to pass in the javascript expression as a string. This
> certainly works but is more than a little ugly. It also complicates
> the implementation a good bit since it now has to include a javascript
> engine. Not a huge issue given that all browsers has one anyway, but
> feels a bit iffy.

Hm.  I'm looking at the spec, and I can't find where (if anywhere) it talks
about what's allowed as a key path.  I guess I had assumed that it was
essentially javascript (or maybe some subset) and that we'd at least need to
be parsing it anyway.  If we don't adopt this idea because we're worried
about depending on javascript, then we should spec out the keyPath syntax
pretty precisely to ensure we don't have such a dependency.


> Oh, interesting!  Do you know why the structured clone algorithm is
> specced
> > that way?
> > Anyway, I'd agree that disallowing it is probably the right answer.
> Hmm.. it turns out I'm wrong. It does not in fact drop id property.
> Ugh, that complicates serializing arrays quite a bit :(
> I still think it's surprising to add properties to arrays, and so I'd
> prefer to treat arrays like primitives and other non-plain-objects and
> make it an error.

I'm fine with this.  I can't think of any use cases it'd get in the way

On Thu, May 20, 2010 at 1:39 AM, Jonas Sicking <jonas@sicking.cc> wrote:

> > I still think it's an interesting idea, though I'm not sold on it.
> > Especially for the first version of the spec.
> It seems like there would be a lot of edge cases to define here. First
> of all, how is the value passed in to this expression? Do we say that
> it's available through some "value" variable? So that if you want to
> index on the "foo" property, you pass in an expression like
> "value.foo"? Or do we want the value to be the global object, so that
> if you wanted to index on the "foo" property the expression would
> simply be "foo"?

Since we're already talking about requiring that data being inserted into
objectStores with a keyPath (for its primary key or in one of its indexes),
setting it as the global object seems reasonable.  And it matches what's
currently specced for the simple 1 entityStore entry to 1 index entry (per
index) case.

Also, what happens if the javascript expression modifies the value?
> Does the implementation have to clone the value before calling each
> "index expression"?

In order of how much I like the idea:
1) In an ideal world, we'd spec it to be read only, but I'm not sure if most
JS engines have an easy way to do something like that.
2) Another possibility is to make the order in which indexes are processed
deterministic.  That way, if someone does modify it, it'll at least
be consistent.
3) Cloning is another possibility, but it seems like it'd have a performance
impact.  Maybe optimized implementations could copy-on-write it, though?

Received on Thursday, 20 May 2010 09:48:32 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 20 October 2015 13:55:34 UTC