W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2011

Re: [IndexedDB] Design Flaws: Not Stateless, Not Treating Objects As Opaque

From: Keean Schupke <keean@fry-it.com>
Date: Sat, 26 Mar 2011 13:27:33 +0000
Message-ID: <AANLkTikdca1yZcbnWO1Ltj_Zp5s+Bujji=TNs84LNcEG@mail.gmail.com>
To: Joran Greef <joran@ronomon.com>
Cc: Nikunj Mehta <nikunj@o-micron.com>, public-webapps@w3.org
On 26 March 2011 09:50, Joran Greef <joran@ronomon.com> wrote:

> > On 26 Mar 2011, at 10:14 AM, Nikunj Mehta wrote:
> >
> > What is the minimum that can be in IDB? I am guessing the following:
> >
> > 1. Sorted key-opaque value transactional store
> > 2. Lookup of keys by values (or parts thereof)
>
> Yes, this is what we need. In programmer speak: objects (opaque strings),
> sets (hash indexes), sorted sets (range indexes).
>
> > I know of no efficient way of doing callbacks with JS. Moreover, avoiding
> indices completely seems to miss the point.
>
> Callbacks are unnecessary. This is what you would want to do as a developer
> using the current form of IDB:
>
> objectStore.putObject({ name: "Joran", emails: ["joran@gmail.com", "
> joran@ronomon.com"] }, { id: 'arbitraryObjectIdProvidedByTheApplication',
> indexes: ["emails=joran@gmail.com", "emails=joran@ronomon.com",
> "name=Joran"] });
>
> IDB would then store the user object using the id provided by the
> application, and make sure it's referenced by this id in the "emails=
> joran@gmail.com", "emails=joran@ronomon.com", "name=Joran" index
> references provided (creating these indexes along the way if need be). The
> application is responsible for passing in the extra "id" and "indexes"
> options to putObject.
>
> Supporting range indexes would be a question of expanding the above to let
> the developer pass in a sort score along with the index reference.
>
> > Next, originally, I also had floated the idea of application managed
> indices, but implementors thought of it as cruft.
>
> I can understand how application managed indices would lead to less work on
> the part of the spec committee. There seems to be some perverse human
> characteristic that likes to make easy things difficult. Ships will sail
> around the world but the Flat Earth Society will flourish.
>
> > I, for one, am not enamored by key paths. However, I am also morbidly
> aware of the perils in JS land when using callback like mechanisms.
> Certainly, I would like to hear from developers like you how you find IDB if
> you were to not use any createIndex at all. Or at least that you would like
> to manage your own indices.
>
> I am begging to be able to manage my indices. I know my data. I do not want
> to use any createIndex to declare indexes in advance of when I may or may
> not use them. What advantage would that give me? I want to create/update
> indexes only when I put or delete objects and I want to have control over
> which indexes to update accordingly. With one small change to the putObject
> and deleteObject interfaces, in the form of the "indexes" option, we can
> make that possible.
>
> We need these primitives in IDB: opaque strings, sets, sorted sets.
> Ideally, IDB need simply store these things and provide the standard
> interfaces (see Redis) to them along with a transactional mechanism. That's
> the perfect low-level API on which to build almost any database wrapper.
>

I am not sure about this API:

objectStore.putObject({ name: "Joran", emails: ["joran@gmail.com", "
joran@ronomon.com"] }, { id: 'arbitraryObjectIdProvidedByTheApplication',
indexes: ["emails=joran@gmail.com", "emails=joran@ronomon.com",
"name=Joran"] });

passing index names like this "emails=joran@gmail.com" means passing the '='
out of the strings which is slow. Much better to use an object and enumerate
the keys:

objectStore.putObject({ name: "Joran", emails: ["joran@gmail.com", "
joran@ronomon.com"] }, { id: 'arbitraryObjectIdProvidedByTheApplication',
indexes: {emails: ["joran@gmail.com", "joran@ronomon.com"], name:
["Joran"]});

Other than that, there is the question of how the keys in the index should
be ordered. Personally I don't see anything wrong with using events, having
an 'onsuccess' event for 'putObject' allowing it to complete asynchronously.
That also allows other events to occur before onsuccess is called. Passing a
sort score as a binary blob compared byte by byte like a string would work
for this purpose, but I would prefer providing an 'event-handler' to map
from the object to the sort-score for this. The API would work something
like:

objectStore.open("store", function onsuccess(store) {

    // chinese_pinyin is a mapping from UTF-16 string to blob sort-score
provided in a library.
    store.registerOrdering("emails", function(obj) {return
ascii(join(obj.emails, ',');});

    // ascii is a mapping from UTF-16 string to blob sort-score provided in
a library.
    store.registerOrdering("name", function(obj) {return chinese_pinyin(
obj.name);});

    objectStore.putObject({ name: "Joran", emails: ["joran@gmail.com", "
joran@ronomon.com"]}, function onsuccess(id) {

        // ...
    });
});


I realise I used the word 'callback' in a previous post when I should have
used 'event'.


Cheers,
Keean.
Received on Saturday, 26 March 2011 13:28:07 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:43 GMT