The Indexed DB API has the purpose to provide storage for large numbers of objects. This is necessary to satisfy offline data requirements. The web storage API is useful for storing data as key-value pairs, but has some limitations. It only has 5MB of storage space available, it does not provide in-order retrieval of keys, efficient searching over values, or storage of duplicate values for a key.
The Indexed DB specification provides an advanced key-value data management. It does this by using a transactional database to store their keys and corresponding values (more than one value for 1 key is allowed) and providing a means of traversing keys in a deterministic order.
The Indexed DB specification declares 2 different API’s. You have an asynchronous that is currently implemented by the most modern browsers (IE 10, Chrome 11.0, Firefox 4), and you have an synchronous API. This last one isn’t yet implemented in any browser. The synchronous Indexed DB API methods provide a blocking access pattern to Indexed DB databases. Since they block the calling thread they are only available from workers. But first some definitions
For every origin you can create an infinite number of databases. The only thing you need to create a database is an unique name. A database also has a version, this version will be used to determine the structure of the database. When a database is created for the first time, the version will be an empty string. Each database can only have one version at a time, this means the database can’t exist in multiple versions at once.
A database compromises one or more object stores. These object stores hold the data that is stored into the database. This data is stored as a list of records. Each record exists of a key and a value. The keys are sorted in ascending order by default and a key can never be exist multiple times within one object store.
Every object store has a name that is unique within the database. Optionally it has an key generator and a key path. A key generator generates a monotonically increasing numbers every time a key is needed. When a key path is given, the key path will be used as key. The last possibility to provide a key, is by explicitly specifying it when storing the value.
The set of object stores can be changed, but it can only change by using the Version_change transaction. This transaction will change the version of the database and change the set of object stores as you defined.
A key path is a DOMstring and defines how we can extract the key from the value. For example if you are using JSON, the DOMstring will be the name of your property.
To enable the most efficiently manner to retrieve records stored in the database, each record is organized by it’s key. A valid key can be one of the following types:
- Array of JS objects
- A DOMstring
- A data
- and a float
An index allows looking up records in a object store using properties of the values in the object stores records. It is a specialized key-value storage that has a referenced object store. The index has a list of records which hold the data stored in the index. The records in an index are automatically populated whenever records in the referenced object store are added, update or deleted. It’s possible that multiple indexes are referencing to the same object store, so when the object store changes all the indexes get updated.
The keys for the index are derived from the referenced object store's values using a key path. The index also contains a unique flag. When it’s true it will enforce that the key will be unique over all the records in the object store.
A transaction will be used to interact with the database, it represents an atomic and durable set of data access and mutation operations. All data that is read or written to the database will happen using an transaction. To create a transaction, a connection is needed. Each transaction has a mode which declares what type of interactions are allowed within the transaction. This mode is set when creating the transaction and will remain the same for the lifetime of the transaction. It also has as scope, this declares the object stores that can be affected within the transaction. An active flag determines if new request can be added. And with the request list you get an overview of all the requests that have been placed against the transaction.
The available modes are:
Every read or write operation on the database is done by a request. A request exists out of a flag done which indicates if the request is completed and a source object. If the request is completed the result or error code become accessible.
A cursor is a mechanism to iterate over multiple records in the database. It compromises a range of records in either an index or a object store. The source of the cursor contains the index or object store we want to iterate. The cursor also has a position which indicates the object it is currently working with and a direction where to the cursor is moving. A position can’t be seen as an index, but rather as a key of the previously returned record. The key and value property of the cursor contain the key and value the cursor is currently holding.
This was a brief introduction to the Indexed DB API, more information about Indexed DB can be found here. In a future post I will handle about creating a database and his structure.