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

Re: [WebSQL] Any future plans, or has IndexedDB replaced WebSQL?

From: Keean Schupke <keean@fry-it.com>
Date: Thu, 31 Mar 2011 16:36:50 +0000
Message-ID: <AANLkTinPFNrEoHdAmfWVAWUAnFowO7owDJiXq1i4qs=Z@mail.gmail.com>
To: Nathan Kitchen <w3c@nathankitchen.com>
Cc: public-webapps@w3.org
No real reason - just trying to implement a minimal framework. Date objects
would be a definite must have going forward.

I was interested in trying to get something like this standardised, as I
believe it has none of the issues that stopped WebSQL, as it defines a
complete relational API independent of the implementation of SQL behind it.

The key thing is to get the browser implementors interested in implementing
it. If even one of the main browser implementors is not interested in
implementing it, then it will suffer the same fate as WebSQL.

Independent of standardisation (which I would like) I intend to try and
implement the same API on top of WebSQL and IndexedDB as a library. So
people are free to use the backend with the best performance without
changing their code. It aims to be as stateless as possible, and to
implement relational algebra on relations.


Cheers,
Keean.


On 31 March 2011 15:54, Nathan Kitchen <w3c@nathankitchen.com> wrote:

> That's nice, pretty much what I was thinking but somewhat more complete : )
> Is there not a w3 group progressing something like this? And if not, who
> would need to be lobbied to get one started?!
>
> As an aside, I note you didn't implement "date" as a supported data type.
> Was that a conscious decision, and if so what was the reasoning behind it?
>
> N
>
>
> On 31 March 2011 16:33, Keean Schupke <keean@fry-it.com> wrote:
>
>> Have a look at my RelationalDB API
>>
>> https://github.com/keean/RelationalDB
>>
>> In particular examples/candy.html
>>
>> A lot of work went into the underlying concepts - Its work originally
>> published by myself and others at the 2004 Haskell Workshop, and follows on
>> from HaskellDB which was the original inspiration behind C#s Linq
>> functionality).
>>
>> It implements the relational-algebra operators as methods that operate on
>> relation objects.
>>
>> Let me know what you think.
>>
>>
>> Cheers,
>> Keean.
>>
>>
>> On 31 March 2011 15:19, Nathan Kitchen <w3c@nathankitchen.com> wrote:
>>
>>> Hi.
>>>
>>> I've been watching discussions on IndexedDB for a while now, and wondered
>>> if anyone would mind spending a few moments to explain how IndexedDB is
>>> related (or not) to WebSQL. Is IndexedDB seen as replacing the functionality
>>> originally offered by WebSQL? If not, are there any plans to make a
>>> cross-platform variant of Web SQL?
>>>
>>> If (?) most web developers know SQL, is there a case to be made for
>>> abstracting SQL into JSON/JavaScript rather than moving to IndexedDB
>>> document storage? Reasons for asking this:
>>>
>>>    - Many of the posts appearing to come from "the dev community" rather
>>>    than W3C seem to expect more SQL-esque functionality from IndexedDB. If the
>>>    enthusiasts who get involved enough to post to the board are expecting
>>>    SQL/query type experience, maybe there is a driver for a native database API
>>>    supporting this.
>>>    - Several people have noted that third-party frameworks could
>>>    implement this functionality. This might be a daft question, but isn't it
>>>    easier to implement an "IndexedDB"-like framework on top of "WebSQL", than a
>>>    "WebSQL"-like framework on top of "IndexedDB" (overuse of quotes to indicate
>>>    the general concept).
>>>
>>> I had a ponder on how I'd like to see such a framework implemented (in
>>> both Access & SQLite :p ), and came up with a stack of pseudo-code below in
>>> my lunch break. Might make an interesting discussion point. It's not really
>>> IndexedDB, it's WebSQL v2. Or maybe WebJSQL or something. I'd be really
>>> interested to understand what advantages IndexedDB has over an
>>> implementation like the one below though.
>>>
>>> // DATABASE
>>> // First, open a database with the specified name. The number at the
>>> // end denotes the version of the specification that the application
>>> // plans to use. This allows forward-compatibility with vNext.
>>> var db = window.openDatabase("shoppinglist", 1.0);
>>>
>>> // MIGRATIONS
>>> // Next, create some migrations. These are predefined structures which
>>> // are validated by the browser database engine. A migration consists
>>> // of two actions: one "up", one "down". Each action specifies some
>>> // operations and parameters. It's up to the browser database to read
>>> // these and perform the appropriate action, as defined in the spec.
>>>
>>> // Other actions may include a "batch add" for "static" data. It could
>>> // also be valid to have key and index creation and removal as separate
>>> // actions.
>>>
>>> // SHOPPING TRIP
>>> var createTripTableAction = {
>>>     action: "create-table",
>>>     params: {
>>>         name: "trip",
>>>         columns: [
>>>           { name: "id", type: "whole-number", primaryKey: true },
>>>           { name: "name", type: "string", length: 32, regex:
>>> "[A-Z]{1,32}" } // regex: wouldn't that be nice...
>>>         ],
>>>         indexes: [
>>>           {
>>>             columns: [
>>>               { name: "name",   type: "full-text" }
>>>             ]
>>>           } // More indexes here if required
>>>         ]
>>>       }
>>>   };
>>>
>>> var removeTripTableAction = {
>>>     action: "remove-table",
>>>     params: {
>>>         name: "shopping",
>>>         cleardata: true
>>>       }
>>>   };
>>>
>>>
>>> // SHOPPING
>>> var createShoppingTableAction = {
>>>     action: "create-table",
>>>     params: {
>>>         name: "shopping",
>>>         columns: [
>>>           { name: "id", type: "whole-number", primaryKey: true },
>>>           { name: "tripid", type: "whole-number" },
>>>           { name: "name", type: "string", length: 128, nillable: false },
>>>           { name: "cost", type: "decimal-number" }
>>>         ],
>>>         keys: [
>>>           { local: "tripid", foreign: { table: "trips", column: "id" },
>>> cascade-delete: true } }
>>>         ],
>>>         indexes: [
>>>           {
>>>             columns: [
>>>               { name: "tripid", type: "asc" },
>>>               { name: "name",   type: "full-text" }
>>>             ]
>>>           }
>>>         ]
>>>       }
>>>   };
>>>
>>> var removeShoppingTableAction = {
>>>     action: "remove-table",
>>>     params: {
>>>         name: "shopping",
>>>         cleardata: true
>>>       }
>>>   };
>>>
>>> var migTrip = { up: createTripTableAction, down: removeTripTableAction };
>>> var migShopping = { up: createShoppingTableAction, down:
>>> removeShoppingTableAction };
>>>
>>> // Example calls which might be appropriate here, where the word
>>> // "callback" is placeholder for async operations:
>>>
>>> db.getVersion();                        // Returns 0
>>> db.migrations.add(migTrip);             // Persists the up/down actions
>>> as a list somewhere
>>> db.migrations.add(migShopping);         // Persists the up/down actions
>>> as a list somewhere
>>> db.migrateUp(2, callback);              // Runs the two migrations
>>> db.getVersion();                        // Returns 2
>>> db.migrateDown(0, callback);            // Runs all "down" migrations to
>>> schema version 0.
>>> db.getVersion();                        // Returns 0
>>> db.destroy(true);                       // Get rid of the database,
>>> optionally running "down" migrations
>>>
>>> // * Note that during migration operations the database should be locked:
>>> no other threads should
>>> // * be able to interact/access the database while this is taking place.
>>>
>>> // QUERIES
>>> // Invent a JSON structure for creating queries. There could be simple
>>> // versions to support simple queries similar to the one below. I
>>> personally
>>> // think that the key here is readability:
>>>
>>> var query = { from: "shopping", select: ["name", "cost"], where: [ {
>>> column: "name", operator: "equals", value: "cookies"} ] };
>>>
>>> // And provide the capability to evaluate more complex query structures
>>> if needed:
>>>
>>> var queryJoin = {
>>>     select: [ { table: "shopping", column: "name" }, { table: "shopping",
>>> column: "cost" } ],
>>>     join: [
>>>       { from: { table: "trips", column: "id" }, to: { table: "trips",
>>> column: "id" } }
>>>     ],
>>>     where: [
>>>       { operator: "and",
>>>         clause: [
>>>           { table: "trips", column: "name", operator: "equals", value:
>>> "Costco" },
>>>           { table: "shopping", column: "name", operator: "like", value:
>>> "*cookies" }  // Can only use "like" on full-text indexed columns
>>>         ]
>>>       }
>>>     ]
>>>   };
>>>
>>> // Querying returns results to callback methods
>>> db.query(query, callback);
>>>
>>>
>>> // CREATE/UPDATE
>>> // Treat everything as "put" operations. Optionally specifying the ID
>>> // (Primary Key) of the object being added to the database should update
>>> // an existing item.
>>>
>>> var toy = { tripid: 1, name: "Flag", cost: 12.99 };
>>> var toys = [
>>>     { tripid: 1, name: "Water pistol", cost: 27.50 }
>>>     { tripid: 1, name: "Football", cost: 4.99 }
>>>     { tripid: 1, name: "Rocket", cost: 8.99 }
>>>   ];
>>>
>>> db.put("shopping", toy, callback);
>>> db.put("shopping", toys, callback);
>>>
>>> var replacementToy = { id: 3, tripid: 1, name: "England Flag", cost:
>>> 12.99 };
>>>
>>> db.put("shopping", replacementToy);
>>>
>>> // There also needs to be functionality to batch update:
>>>
>>> var epicSale = { cost: 0.99 };
>>> var putQuery = {
>>>     where: [
>>>       { column: "tripid", operator: "equals", value: 1 }
>>>     ]
>>>   };
>>>
>>> // This effectively does: "UPDATE shopping SET cost=0.99 WHERE tripid=1;"
>>> db.put("shopping", putQuery, epicSale);
>>>
>>> // DELETE
>>> // Finally, provide the same kind of mechanisms for deleting data.
>>> db.remove("shopping", 1);
>>>
>>> var queryRemove = {
>>>     remove: { table: "shopping", column: "name" },
>>>     join: [
>>>       { from: { table: "trips", column: "id" }, to: { table: "trips",
>>> column: "id" } }
>>>     ],
>>>     where: [
>>>       { operator: "and",
>>>         clause: [
>>>           { table: "trips", column: "name", operator: "equals", value:
>>> "Costco" },
>>>           { table: "shopping", column: "name", operator: "like", value:
>>> "*cookies" }
>>>         ]
>>>       }
>>>     ]
>>>   };
>>>
>>> db.remove("shopping", queryRemove);
>>>
>>
>>
>
Received on Thursday, 31 March 2011 16:37:23 GMT

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