Search code examples
keyindexeddbweb-sqlpolyfills

IndexedDB with inline keys, polyfill to Web SQL, how to get key to allow update?


I have been unable to update a record when using the IndexedDB shim to Web SQL: https://github.com/axemclion/IndexedDBShim

I am also using IDBWrapper: https://github.com/jensarps/IDBWrapper

Despite me using these libraries, I believe that my question might still be relevant, and I might still be advised appropriately, as it could be related just to general usage of IndexedDB and Web SQL

I am implementing IndexedDB storage, using inline keys.

_store = new IDBStore({
    storeName: 'person',
    keyPath: 'PersonId',
    autoIncrement: true,
    onStoreReady: _loadPersons
});

When I save an object to the store...

_store.put(person, _loadPersons);

...it will generate an auto-incrementing key, and then store this key value automatically on the object, named after the 'keyPath' property, in this case PersonId.

This works great. If I inspect the IndexedDB storage in Chrome, there are 2 columns. Key (Key path: 'PersonId') and Value (containing the object).

If I want to update the same object, I just make sure it contains a property named PersonId, and has the same value as they key I want to save, and it will update.

However, when using the IndexedDB shim which saves to Web SQL (e.g. in Safari for Windows, or mobile browsers), when I load the objects in they do not contain the PersonId property at all.

For reference, the _loadPersons callback is as follows:

_loadPersons = function () {
    _store.getAll(_setPersons);
};

If I inspect the Web SQL storage in Safari, there are 3 columns, key (which is in the format 1-0, 1-1, 1-2), inc (1, 2, 3) and value (which contains a JSON string of the object, missing the PersonId property.

I'm not sure how the inline keys feature works in IndexedDB, but it seems that whatever it does, it doesn't happen in Web SQL.

How should I be referring to objects that I want to update, when using this approach?

Should I just use out-of-line keys?

Has anyone else implemented an IndexedDB -> Web SQL structure, if so what libraries did they use and did they come across this issue?

UPDATE:

I have looked at the code behind an example of the Indexed DB JQuery plugin using the IndexedDB polyfill: http://nparashuram.com/jquery-indexeddb/example/. However this example all the items already have an 'itemId', and it doesn't have any logic for adding new items, just moving existing items to different places (cart, wishlist), so I can only assume that this approach would be an 'out-of-line keys' approach.

UPDATE 2:

The way I resolved my situation, to enable me to work with IndexedDBShim and IDBWrapper, is detailed as an answer below. However probably the better solution is to ditch these two libraries and try something else.


Solution

  • Have you try my own open source library https://bitbucket.org/ytkyaw/ydn-db/wiki/Home It has full shimming from WebSQL to IndexedDB including inline/outline/autoIncrement/compound/multiEntry key. There is qunit test as well.

    Edit, additional answers:

    if you used autoIncrementing inline keys, and you didn't store the timeStamp on the object manually, would Web SQL know which object to update?

    While autoIncrement inline key is used and a record value don't have primary key, it is considered as a new object (and it is). Note: Sqlite also has concept of auto increment numeric primary key.

    Also it looks like in Web SQL every time you refresh the demo makes a new store?

    Nop. If a new store is created on page refresh, it is not database.