IndexedDB API Basics

                      IndexedDB lets you store and retrieve objects which are indexed with a "key." All changes that you make to the database happens within transactions. Like most web storage solutions, IndexedDB follows a same-origin policy. So while you can access stored data within a domain, you cannot access data across different domains.

IndexedDB API Basics


The API includes both an asynchronous API and a synchronous API. The asynchronous API can be used in most cases, while the synchronous API is for use with WebWorkers. Currently, no major browser supports the synchronous API. But even if synchronous APIs are supported, in the majority of cases where you use IndexedDB, you are likely to use the asynchronous API anyway.

               An Indexed Database is a collection of "object stores" which you can just drop objects into. The stores are something like SQL tables, but in this case, there's no constraints on the object structure and so no need to define anything upfront. So this is similar to Web Storage, with the advantage that you can have as many databases as you like, and as many stores within each database. But unlike Web Storage, there are important performance benefits: An asynchronous API, and you can create indexes on stores to improve search speed.

Here are the main differences between the WebSQL and IndexDB databases.

CategoryWebSQLIndexedDB
AdvantagesA real, relational database implementation on the client (SQLite).* Allows fast indexing and searching of objects, so in a web application scenario, you can manage your data and read/write it fast.
* A NoSQL database that let you work with your JavaScript objects and indexing them based on your application needs.
* Works in asynchronous mode with moderately granular locking per transaction. This allows you to work inside the event-driven module of JavaScript.
Disadvantages* The spec is deprecated.
* Overhead of SQL language you need to master and transform your JavaScript objects into relational schema
* Not object driven
Harder to understand if you are coming from the world of relational databases.
LocationTables contain columns and rowsobjectStore contains Javascript objects and keys
Query MechanismSQLCursor APIs, Key Range API, and Application Code
TransactionLock can happen on databases, tables, or rows on READ_WRITE transactionsLock can happen on database VERSION_CHANGE transaction, on an objectStore READ_ONLY and READ_WRITE transactions.
Transaction CommitsTransaction creation is explicit. Default is to rollback unless we call commit.Transaction creation is explicit. Default is to commit unless we call abort or there is an error that is not caught.

1. How to Create IndexDB Database?

Indexed Database setup takes some work, because it enforces a database version system; if we attempt to open a new database, the result will be a database whose version is null, which is our cue to set it up. And in setting it up, we obviously want to set the version so it doesn't return null next time!  

Creating indexDB:


var indexedDB = window.indexedDB || window.webkitIndexedDB ||
                window.mozIndexedDB || window.msIndexedDB;
// Handle the prefix of Chrome to IDBTransaction/IDBKeyRange.
if ('webkitIndexedDB' in window) {
  window.IDBTransaction = window.webkitIDBTransaction;
  window.IDBKeyRange = window.webkitIDBKeyRange;
}
indexedDB.db = null;
// Hook up the errors to the console so we could see it.
// In the future, we need to push these messages to the user.
indexedDB.onerror = function(e) {
  console.log(e);
};


2. How to create IndexDB ObjectStore?

Creating ObjectStore in IndexDB:
In indexedDB, we create an object store inside a 'SetVersion' transaction. SetVersion is the only place in our code that we can alter the structure of the database. In it, we can create and delete object stores and build and remove indexes. Object stores contain your JavaScript objects and you can reach your data by key or by setting indexes. A call to setVersion returns an IDBRequest object where we can attach our callbacks. When successful, we start to create our object stores.we must call setVersion() and we set up the database once the version has been set.


indexedDB.open = function() {
  var request = indexedDB.open("todos");
  request.onsuccess = function(e) {
    var v = "2.0 beta"; // yes! you can put strings in the version not just numbers
    todoDB.indexedDB.db = e.target.result;
    var db = todoDB.indexedDB.db;
    // We can only create Object stores in a setVersion transaction;
    if (v!= db.version) {
      var setVrequest = db.setVersion(v);
      // onsuccess is the only place we can create Object Stores
      setVrequest.onfailure = todoDB.indexedDB.onerror;
      setVrequest.onsuccess = function(e) {
        if (db.objectStoreNames.contains("todo")) {
          db.deleteObjectStore("todo");
        }
        var store = db.createObjectStore("todo", {keyPath: "timeStamp"});
        todoDB.indexedDB.getAllTodoItems();
      };
    } else {
      todoDB.indexedDB.getAllTodoItems();
    }
  };
  request.onfailure = todoDB.indexedDB.onerror;
};

Object Stores are created with a single call to createObjectStore(). The method takes a name of the store and an parameter object. The parameter object is very important as it lets you define important optional properties. In our case, we define a keyPath that is the property that makes an individual object in the store unique. That property in this example is "timeStamp". "timeStamp" must be present on every object that is stored in the objectStore.

Note: according to latest IndexedDB spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html setVersion() will be taken out. Thus, our code snippets here is going to change and the version setting will be part of the open() function of the database.

3. How to Store Objects in indexDB?

IndexedDB - Adding item:
We first get a quick reference to the database object todoDB.indexedDB.db, initiate a READ_WRITE transaction and get a reference to our object store. There are three types of transactions:

READ_WRITE - Allows records contained in object stores to be added, read, modified, and removed.
READ_ONLY - Allows records contained in object stores to be read.
VERSION_CHANGE - Used to create or update object store and indexes.
Now that the application has access to the object store, we can issue a simple put command with a basic JSON object. Notice that there is a timeStamp property. That is our unique key for the object and is used as the "keyPath". When the call to put is successful, our onsuccess event is triggered, and we are able to render the contents on the screen.


indexedDB.addTodo = function() {
  var db = todoDB.indexedDB.db;
  var trans = db.transaction(['todo'], IDBTransaction.READ_WRITE);
  var store = trans.objectStore('todo');
  var data = {
    "text": todoText, // todoText should be visible here
    "timeStamp": new Date().getTime()
  };
  var request = store.put(data);
  request.onsuccess = function(e) {
    todoDB.indexedDB.getAllTodoItems();
  };
  request.onerror = function(e) {
    console.log("Error Adding: ", e);
  };
};


4. How to retrieve the values or objects from IndexDB?

IndexedDB - Retrieving data:
We open a transaction on our object store. This is set to READ_ONLY, because we only wish to retrieve data. Next, we open a cursor and iterate with it on our list of todos. All of these commands used in this sample are asynchronous and, as such, the data is not returned from inside the transaction.


function showAll() {
  document.getElementById("ourList").innerHTML = "";
  var request = window.indexedDB.open("todos");
  request.onsuccess = function(event) {
    // Enumerate the entire object store.
    var db = todoDB.indexedDB.db;
    var trans = db.transaction(["todo"], IDBTransaction.READ_ONLY);
    var request = trans.objectStore("todo").openCursor();
    var ul = document.createElement("ul");
    request.onsuccess = function(event) {
      // This hack is to allow our code to run with Firefox (older versions then 6)
      var cursor = request.result || event.result;
      // If cursor is null then we've completed the enumeration - so update the DOM
      if (!cursor) {
        document.getElementById("ourList").appendChild(ul);
        return;
      }
      var li = document.createElement("div");
      li.textContent = "key: " + cursor.key + " => Todo text: " + cursor.value.text;
      ul.appendChild(li);
      cursor.continue();
    }
  }
}


5. How to delete the objects from IndexDB Database? 

IndexedDB - delete data:
Start a transaction, reference the Object Store with your object in and issue a delete command with the unique ID of your object.


indexedDB.deleteTodo = function(id, text) {
  if (confirm("Are you sure you want to Delete " + text + "?")) {
    var db = todoDB.indexedDB.db;
    var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE);
    var store = trans.objectStore("todo");
    var request = store.delete(id);
    request.onsuccess = function(e) {
      todoDB.indexedDB.getAllTodoItems();
    };
    request.onerror = function(e) {
      console.log("Error Adding: ", e);
    };
  }
};

Share this

Related Posts

Previous
Next Post »

1 comments:

comments