Re: W3C Working Draft for Data Store API

Hi Eduardo,

On Tue, Feb 11, 2014 at 9:02 AM, Gene Lian <clian@mozilla.com> wrote:
> Hi Eduardo!
>
> ----- Original Message -----
>> From: "EDUARDO FULLEA CARRERA" <efc@tid.es>
>> To: "Gene Lian" <clian@mozilla.com>
>> Cc: public-sysapps@w3.org, "Ehsan Akhgari" <ehsan@mozilla.com>, "Andrew Overholt" <overholt@mozilla.com>, "Jonas
>> Sicking" <jonas@sicking.cc>
>> Sent: Thursday, February 6, 2014 10:47:43 PM
>> Subject: RE: W3C Working Draft for Data Store API
>
>> It is ok to have to separate operations but in order to avoid duplicated
>> operations we could drop 'add' with 'id' as argument and stick to:
>> update (data, id)
>> add (data)
>
> Yeap! I doubt the same thing. I'll ask around why Mozilla separates
> this in the first design.

I thought we have discussed that in
https://github.com/airpingu/data-store-api/issues/12

Giving it a second thought, let's start from use cases.

There are 3 different data adding use cases one would possibly like
DataStore to handle:
1. update data with a given id; if the id does not exist, fail.
2. insert data; a new id is returned on success, else fail.
3. insert data if it does not exist; if it exists, then update it.

The first 2 are trivial. The third has some challenge about how to
formalize, and how to implement it. One example was given as inserting
URL's in a DB, if they did not exist in the DB. This would not need
the update part: if the data exists, just don't add. On the other
hand, one knows the content, but not the id. So if we support 3., we
need a way to specify "if data exists". In most cases that can be
reduced to an id/primary key, but in some cases the content matters.
IMO a generic way to deal with this would be the following:

Promise<index> add(any data, DOMString[] props);

Where the 'props' array would contain the list of property names on
which comparison is done (with AND semantics) for checking whether the
data "exists" in the DB. For instance, for the URL case we'd write:

var myURL = { url: "what.ever.com/this"; myotherdata = 0; };
add(myURL, ["url"]).then(
  function(id) {  console.log("URL did not exist; inserted with id: " + id; },
  function() { console.log("URL already existed, no insert"); });

For a Contacts record, we may want to use the id as a check:

add(contact, ["id"]).then(...);
Where the 'contact' variable contains an 'id' property with a value
set, which is compared to the id's stored in the system. We could say
that would be the default property to check, so we could make the
'props' array optional, meaning we'd check on the property named 'id'.

As a consequence, the following API could be proposed:

1. Promise update(any data, DOMString id);  // trivial
2. Promise<index> insert(any data);  // trivial
3. Promise<index> add(any data, optional DOMString[] propsToCheck);
// When 'propsToCheck' is not given, it defaults to a list of one
property named 'id'.

However, the last API would likely open Pandora's box for
implementations (e.g. generating indexes on the fly, or just choose to
have an inefficient method). Exactly what this spec tried to avoid.
Even if the spec chooses not to implement this 3rd use case for
performance reasons, it needs to state a note about it, with
suggestion(s) to apps on how to implement such a use case. One example
would be to maintain a private associative map (object) about this,
implement the comparison function, use the DB interface to create the
needed indexes, enumerate records, compare etc, and just use the id
scheme with the DataStore API when it is known whether an insert or an
update is needed. This pushes all the complexity to the apps, but the
DataStore spec was quite open about that restricted scope from the
beginning.

So the alternative is to have just the first 2 functions from above,
and drop the last one.

How does this sound, and which way we go?

Best regards,
Zoltan

Received on Tuesday, 11 February 2014 08:19:08 UTC