Based on your requirement, Safari on iOS has no alternative but WebSQL. WebSQL is supported in another mobile browser, such as Opera and Blackberry. I do not think that they will remove WebSQL support, even if they have IndexedDB. Somehow they complement each other.
On the other hand, during the war with the browser repository, IndexedDB wins forever. IE and FF will only have IndexedDB. The ironic fact is that FF implements IndexedDB on top of Sqlite.
What I would like to say is that IndexedDB is more than just a keystore. It has an index and a transaction. These two only do almost all of the SQL query functions, including union, conditional, and sorting. This is not obvious at first due to its asynchronous API.
IndexedDB performance is better than WebSQL. It is safer. It is more flexible for using javascript. Finally, it is easier to use.
To illustrate this, I will use the sudo code from my library , but you can use the IndexedDB API directly:
In the "people" storage, the "name" field and a list of indexed "hobby" fields are indicated. In JSON,
people = { name: 'Foo Bar', email: 'foo@bar.com' hobby: ['camping', 'swimming']};
Get a name from "people" whose hobby is "camping."
var req = db.keys('people', 'hobby', IDBKeyRange.only('camping')); req.done(function(campers) { db.keys('people', campers, 'name').done(function(names) { console.log(names); }); });
Interestingly, this code is not serialized. Therefore, it is very fast.
The following example illustrates a friendship graph request. friendship There is only one specified indexed field friend_list . It uses the key to store people's objects as the primary primary key. people repository of objects has many attributes, including the location field. The query is to find a list of friends who know me and other_guy and are in 'Singapore'.
var q1 = new ydn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(me)); var q2 = new dn.db.Iterator('friendship', 'friend_list', IDBKeyRange.only(other_guy)); // if location is not indexed, a filtered value query is used. var q3 = new ydn.db.Iterator('people', new ydn.db.Expression(['"location"', "'Singapore'", '='])); // if location is indexed, an index query is used. // var q3 = new ydn.db.Iterator('people', 'location', IDBKeyRange.only('Singapore')); var current_loop = 2; // start from inner loop var join_algo = function(keys, index_keys) { var advancement = []; advancement[keys.length - 1] = null; var has_adv = false; for (var i = 0; i < keys.length; i++) { if (!goog.isDef(keys[i])) { // completed iterator if (i != 0) { advancement[i] = false; // request to restart the iteration advancement[i - 1] = true; // advance outer iterator current_loop = i - 1; } // i == 0 means we are done. has_adv = true; break; } } if (!has_adv) { // continue looping current advancement[current_loop] = true; } return advancement; } var result = db.scan([q3, q1, q2], join_algo); result.done(function(keys, index_keys, values) { console.log(values); // should get desire list of friends });
Again this connection request is just a key scan and therefore very fast. By default, scan use the sorted-merge algorithm to find matching keys, but the naive algorithm for combining nested loops is shown here. Thus, joining a table is possible, but you need to code a join algorithm. But newer algorithms, such as merging zigzags, are faster than possible with Sqlite, because all inputs are sorted, cursors can move well, and more importantly, the connection process can use external knowledge that is not in the database. With SQL, the join operation is opaque.
In addition, IndexedDB can use methods such as streaming and map / reduction.