Indexed database
Usually when developing web applications, there are some scenarios where we want to store certain non-sensitive information in the client system, in other words in the browser memory.
With the introduction of HTML 5, there are many new features available and a few of them can be used to address the preceding specified scenario. For example local storage and indexed database. In this article we will see indexed databases in more details.
An Indexed database is nothing but an object store that can store JavaScript objects of any type. An important aspect to understand about an indexed db is, it is not similar to the relational database where you have your collection of rows, columns and records, however it maintains the indexes over records it stores and users can query records by key or look up index.
Each indexed database is domain-bound, meaning that the indexed database created by the domain abc.com cannot be accessed or used by xyz.com.
Asynchronous approach
Nearly all operations done on the indexed db are asynchronous in nature, typically done using "request" objects. When any asynchronous API call is made, it returns the reference to the "request" object that has callback methods for "onerror" and "onsuccess".
Fundamental constructs
Object store
An Object store is nothing but a container of objects within the indexed database. An indexed db can have multiple object stores that are separate entities from each other. (You can relate it to a folder structure in a file system or tables in SQL Server).
Keys
Each object store can contain a collection of records. Each record is a simple key/value pair, however a key must be unique to each record. All records inside an object store are automatically sorted by ascending order of keys.
Each record should have a unique key that can be given "in-line", in other words inside the record itself. Consider the example below:
- var object = { id: articleid, articlename: name, articleauthor: author };
In the example above, you can see that the key "id" is specified inline, in other words it is a part of the object.
Key Path
Key path is nothing but the string identifier that is used to denote the key, if it is given inline as shown in the preceding example.
Using the keypath the key is extracted from the value of an object. In other words, in the example above, the article id will be used as a key for the record and we must specify the "id" as the key path when creating the object store so that all entries in the object store will use article id as unique key.
- createObjectStore("articles", { keyPath: "id" });
Transactions
Similar to the relational database, all operations on the indexed db fall under the context of transactions that are created from the connection objects.
There are two key concepts associated with the term transactions when we talk about indexed databases, in other words scope and mode.
- Scope: transaction scope in simple terms can be considered to be the area in which transactions will happen. For example you might provider the name of a store when initiating the transaction object that defines the scope of the transaction.
- Mode: you can relate this to the action that you want to do on an object or store. It has the following three modes:
- Read only: allows read actions.
- Read Write: allows read and write actions.
- Version change: allows read/write actions with deletion of object stores and indexes.
Versioning
Indexed databases have versions associated with them. They are usually used to ensure the client has the latest version of the database. If you change the schema of your indexed database and want to push those changes forcefully to the client, then you need to change the version number to do it.
Getting started
All right, enough of the theory and let's get started with some real action.
In this first section of the article, we will see how to create and open the indexed database for further actions. We will also get a deeper look at indexed db APIs and parameters.
In the example below, we will create and open the indexed database with name articles and we will also create the object store with name techartciles in which we will store articles related to metadata in next the part of this series.
- <script>
-
- var articlesDb;
-
- var request = indexedDB.open('articles', 1);
In the preceding example, we have defined a global JavaScript variable that we will be using throughout our application once we initialize the indexed database.
The next statement uses the indexedDB global variable by which we are trying to open / create the indexed database with the name article and version = 1. Note that since this is an asynchronous request, so far the request is keeping the reference.
We will now define onerror, onsuccess and onupgradeneeded call backs.
- request.onerror = function (e) {
- console.log('error occured while creating indexed db.')
- }
-
- request.onsuccess = function (e) {
- articlesDb = request.result;
- console.log('Indexed db created successfully!!');
- }
-
- request.onupgradeneeded = function (e) {
-
-
- var objectStore = e.target.result.createObjectStore("techarticles", { keyPath: "id", autoIncrement: true });
- }
- </script>
You might have observed that we are using an upgrade callback to create the object store with the name techarticles.
When creating the database, the event "onupgradeneeded" is called first then the "onsuccess" or "onerror" callback.
Note that the key path is set to the "id" that we will be using when adding new items to the indexed database with inline key.
Now If we run this web application and observe the console, we should get the message "Indexed db created successfully!!" .
In Part 2 of this article, we will see how to add, update and delete records in the indexed database that we created and will also see how to delete an object store, clear an object store and get all the records in a specific object store.