Using IndexedDB API today – the IndexedDB polyfills

This is a guest post from Parashuram Narasimhan on how to use IndexedDB today.

Using the polyfills mentioned in this article, web developers can start using IndexedDB APIs in their applications and support a wider range of browsers.

The IndexedDB API has matured into a stable specification with support by major browser vendors. However, the specification is still not supported in all browsers, making it harder to use in production. There are also some interesting differences in the implementations among browsers that support the specification. This article explores a couple of polyfills that could be leveraged to enable developers to use IndexedDB across different browsers.

Polyfill using WebSql

WebSql was one of the first specifications for data storage in the browsers and is supported in some browsers that do not have an implementation of IndexeddB yet. However, the specification is no longer in active maintenance. As mentioned in the document: “it was on the W3C Recommendation track but specification work has stopped. The specification reached an impasse: all interested implementors have used the same SQL backend (Sqlite), but we need multiple independent implementations to proceed along a standardisation path”.

The polyfill assigns window.indexedDB to be window.mozIndexedDB, window.webkitIndexedDB or window.msIndexedDB; if any of those implementations are available. If no implementation is available, the polyfill assigns a ‘window.shimIndexedDB’ to window.indexedDB. Web applications can thus start using window.indexedDB as the starting point for all database operations. Internally, the polyfill uses the WebSql tables to store object store data and borrows heavily from the IndexedDB implementation in Firefox. For example, it has separate tables and databases to maintain a record of the database versions, or the values for object store definitions (IDBObjectStoreParameters). More implementation details about the internals can be found in the blog post on it.

The polyfill has been tested to work with various IndexedDB libraries like PouchDB, LINQ2IndexedDB, JQuery-IndexedDB and DB.JS. Since it leverages WebSql, applications can write code according to the IndexedDB API on web browsers like Opera and Safari, and additionally on mobile browsers like Safari on iPad/iPhone, or mobile development platforms like Cordova that have WebSql enabled browsers embedded in them.

It is implemented in Javascript and is a work in progress. Note that it may not fully confirm to the specification and you discover issues, you could file a bug or send a pull request to the source repository.

Polyfill for setVersion

An earlier version of the IndexedDB Specification used the “setVersion” call to change the version of the IndexedDB Database. This was later revised to an easier to use “onupgradeneeded” callback. Though Internet Explorer and Firefox support the newer “onupgradeneeded” to initiate database version changes for creating or deleting objectStores and Indexes, Google Chrome (22.0.1194.0 canary) still uses the older setVersion.

All browsers will soon use the newer “onupgradeneded” method soon; till then, this simple polyfill for setVersion lets you use the IndexedDB API with the onupgradeneeded method.

The polyfill substitutes the indexeddb.open() call with an openReqShim() call. The openReqShim() call invokes setVersion() and then converts it to the “onupgradeneeded” callback if only “setVersion()” is supported. If the implementation supports the “onupgradeneeded”, openReqShim() is simply a transparent call to the indexedb.open method. Hence, indexeddb.open() calls should be replaced with the openReqShim() call to use this polyfill.

Parashuram Narasimhan is a Programmer at Sneekpeeq. Before Sneakpeeq, he was a senior program manager for SQLCE at Microsoft, working on the IndexedDB implementation and specifications. He has written the Jquery IndexedDB plugin, a query layer for IndexedDB and is working on a WebSql shim for IndexedDB. He also like playing with latest HTML features in the web and their security implications. During his free time, he hacks at http://nparashuram.com/projects and posts the results at http://blog.nparashuram. He is also a "huge" fan of Mozilla Firefox and has been using it as his primary browser from version 1.

8 comments

Josh Matthews

I’ve also found the IDBWrapper library to be a nice cross-browser tool for similar purposes (and it happens to hide some of the IndexedDB weirdness behind a nice facade, too): http://jensarps.github.com/IDBWrapper/

It has support for both setVersion and onupgradeneed, and hence will work on Chrome and Safari. It also uses constants like READ_WRITE, etc for transactions, making it safe against the latest changes in the spec where numbers were replaced with string constants like “readonly”. However, browsers may remove these constants in the future and the library may have to be upgraded.