W3C

Indexed Database API

W3C Working Draft 05 January 2010

Latest Editor's Draft:
http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html
This Version:
http://www.w3.org/TR/2010/WD-IndexedDB-20100105/
Latest Published Version:
http://www.w3.org/TR/IndexedDB/
Previous version:
http://www.w3.org/TR/2009/WD-WebSimpleDB-20090929/
Editor:
Nikunj Mehta, Oracle Corp

Abstract

This document defines APIs for a database of records holding simple values and hierarchical objects. Each record consists of a key and some value. Moreover, the database maintains indexes over records it stores. An application developer directly uses an API to locate records either by their key or by using an index. A query language can be layered on this API. An indexed database can be implemented using a persistent B-tree data structure.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Applications Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All feedback is welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This section is non-normative.

User agents need to store large numbers of objects locally in order to satisfy off-line data requirements of Web applications. [WEBSTORAGE] is useful for storing pairs of keys and their corresponding values. However, it does not provide in-order retrieval of keys, efficient searching over values, or storage of duplicate values for a key.

This specification provides a concrete API to perform advanced key-value data management that is at the heart of most sophisticated query processors. It does so by using transactional databases to store keys and their corresponding values (one or more per key), and providing a means of traversing keys in a deterministic order. This is often implemented through the use of persistent B-tree data structures that are considered efficient for insertion and deletion as well as in-order traversal of very large numbers of data records.

Example

A script can efficiently find records in an object store that come closest to the required value provided the value is stored in either a primary or a secondary key. In the following example, the 'books' object store holds data about books which are stored by their 'isbn' attribute. Additionally, an index is maintained on the 'author' attribute of the objects stored in the object store. This index can be used to look up books for a given author. If an exact match is not found, the next matching author is located.

ECMAScript
var db = indexedDB.open('books', 'Book store', false);
if (db.version !== '1.0') {
  var olddb = indexedDB.open('books', 'Book store');
  olddb.createObjectStore('books', 'isbn');
  olddb.createIndex('BookAuthor', 'books', 'author', false);
  olddb.setVersion("1.0");  
}
// db.version === "1.0";  
var index = db.openIndex('BookAuthor');
var matching = index.get('fred');
if (matching)
  report(matching.isbn, matching.name, matching.author);
else
  report(null);

The next example performs the exact same logic as above asynchronously.

ECMAScript
function findFred() {
  db.request.onsuccess = function() {
    var index = db.request.result;
    index.request.onsuccess = function() {
      var matching = index.request.result;
      if (matching)
        report(matching.isbn, matching.name, matching.author);
      else
        report(null);    
    }
    index.get('fred');
  }
  db.openIndex('BookAuthor');
}

indexedDB.request.onsuccess = function() {
  var db = indexedDB.request.result;
  if (db.version !== '1.0') {
    indexedDB.request.onsuccess = function() {
      var olddb = indexedDB.request.result;
      olddb.request.onsuccess = function() {
        olddb.request.onsuccess = function() {
          olddb.request.onsuccess = function() {
            findFred(db);
          }
          olddb.setVersion("1.0");   
        }
        olddb.createIndex('BookAuthor', 'books', 'author', false);        
      }
      olddb.createObjectStore('books', 'isbn');
    }
    indexedDB.open('books', 'Book store');
  }
  findFred(db);
};        
indexedDB.open('books', 'Book store', false);
        

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].

This specification defines one class of products:

Conforming user agent

A user agent must behave as described in this specification in order to be considered conformant.

User agents may implement algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms.

A conforming Indexed Database API user agent must also be a conforming implementation of the IDL fragments of this specification, as described in the “Web IDL” specification. [WEBIDL]

This specification uses both the terms "conforming user agent(s)" and "user agent(s)" to refer to this product class.

2.1 Dependencies

This specification relies on several other underlying specifications.

HTML5
The terms and algorithms document base URL, event handler attributes, event handler event type, Function, origin, same origin, structured clone, structured clone algorithm, task, task source, and queue a task are defined by the HTML 5 specification [HTML5].
WebWorkers
The term Worker is defined by the WebWorkers specification [WEBWORKERS].

3. Indexed Database API

3.1 Constructs

An indexed database is made of records holding simple values and hierarchical objects. Each record consists of a key and some value.

3.1.1 Keys

In order to efficiently retrieve records stored in an indexed database, a user agent needs to organize each record by its key. Conforming user agents must support the use of values of IDL data types DOMString and long as well as the value null as keys.

For purposes of comparison, a DOMString key is always evaluated higher than any long key. Moreover, null always evaluates lower than any DOMString or long key.

Only data types with natural ordering can be used as keys. The ECMAScript undefined cannot be used as a key.

3.1.2 Values

Values can be any data type supported by the structured clone algorithm [HTML5]. This includes simple types such as DOMString and Date as well as Object and Array instances.

A database may choose to derive a key from the contents of the value being stored. In such a case, only Object instances may be stored as values. Only the direct enumerable properties of a stored Object instance can be used to derive a key value.

3.1.3 Object Store

An object store is a persistent storage that holds key-value pairs, also called records. An object store's records are sorted by keys so as to enable fast insertion and look up as well as ordered retrieval. Every object store has a name.

An object store must have a unique key generator, if it uses keys generated from a monotonically increasing sequence. Alternatively, if an application provides keys, they can either be identified as a part of the value being stored, also called in-line keys, or be identified separately, also called out-of-line keys. No two records in an object store may be identified by the same key. An object store must have a key path if it uses in-line keys. The key path must be the name of an enumerated property of all objects being stored in that object store.

Concurrent access to an object store may be isolated in one of three modes. Any number of readers may concurrently access an object store. A writer is not allowed if there is any reader concurrently accesing the object store, unless the reader is detached, i.e., looking at a snapshot view of the data that does not change once created.

The detached reading behavior may need more explanation.

The ObjectStore interface is used to access the metadata of an object store.

interface ObjectStore {
    const unsigned short READ_WRITE = 0;
    const unsigned short READ_ONLY = 1;
    const unsigned short SNAPSHOT_READ = 2;
    readonly attribute unsigned short mode;
    readonly attribute DOMString      name;
    readonly attribute DOMString      keyPath;
    readonly attribute DOMStringList  indexNames;
};
indexNames of type DOMStringList, readonly
On getting, provide a list of the names of indexes on objects in this object store.
No exceptions.
keyPath of type DOMString, readonly
On getting, provide the key path of this object store. If this attribute is null, the application must provide a key value for each modification operation.
No exceptions.
mode of type unsigned short, readonly
On getting, provide the mode for isolating access to data inside this object store
No exceptions.
name of type DOMString, readonly
On getting, provide the name of this object store.
No exceptions.
READ_ONLY of type unsigned short
Modification operations are not allowed on the object store in this mode.
READ_WRITE of type unsigned short
Modification operations are allowed on the object store in this mode.
SNAPSHOT_READ of type unsigned short
This mode is used solely for reading from a snapshot of the data in the object store.

3.1.4 Index

Records in an object store can be retrieved by means of the record's key. However, that may not be always adequate to recall records. An index is used to lookup records in an object store other than through a record key.

An index is a specialized persistent store that holds key-value pairs such that each value is the key of objects in the referenced object store. An index may allow duplicate values for a key, unlike an object store, only if its unique flag is not set. Every index has a name.

If an index is auto-populated, then the user agent populates records using the values stored in the referenced object store. An auto-populated index must have a key path, which must be the name of an enumerated property of all objects being stored in the referenced object store. The auto-populated index record corresponding to an object store record must satisfy the following index maintenance conditions:

The Index interface is used to access the metadata of an index.

interface Index {
    readonly attribute DOMString name;
    readonly attribute DOMString storeName;
    readonly attribute DOMString keyPath;
    readonly attribute boolean   unique;
};
keyPath of type DOMString, readonly
On getting, provide the key path of this index. If this attribute is null, this index is not auto-populated.
No exceptions.
name of type DOMString, readonly
On getting, provide the name of this index.
No exceptions.
storeName of type DOMString, readonly
On getting, provide the name of this index's referenced object store.
No exceptions.
unique of type boolean, readonly
On getting, provide the unique flag of this index.
No exceptions.

3.1.5 Database

Each origin has an associated set of databases. A database comprises:

The object stores and indexes of a database are also referred as its objects.

Each database has a valid name and a human readable description A valid name is any string including the empty string. Names must be compared in a case-sensitive manner.

Implementations can support this even in environments that only support a subset of all strings as database names by mapping database names (e.g. using a hashing algorithm) to the supported set of names.

Each database also has a current version.

Each database has one version at a time; a database can't exist in multiple versions at once.

The object store name and index name must be valid and unique within the database.

When a database is opened, that creates a connection. There may be multiple connections to a given database at any given time. A connection that is attempting to read a given piece of data in a database is called a reader and one that is attempting to write that piece of data is called a writer. There may be zero or one active transaction in a connection.

A Database object represents a connection to a database. There is no way to enumerate the databases available for an origin from this API.

interface Database {
    readonly attribute DOMString     name;
    readonly attribute DOMString     description;
    readonly attribute DOMString     version;
    readonly attribute DOMStringList objectStores;
    readonly attribute DOMStringList indexes;
    readonly attribute Transaction   currentTransaction;
};
currentTransaction of type Transaction, readonly
On getting, this attribute must return a Transaction object corresponding to the transaction that is active in this database connection.
No exceptions.
description of type DOMString, readonly
On getting, this attribute must return the description of the connected database.
No exceptions.
indexes of type DOMStringList, readonly
On getting, this attribute must return a list of names of the indexes currently in the connected database.
No exceptions.
name of type DOMString, readonly
On getting, this attribute must return the name of the connected database.
No exceptions.
objectStores of type DOMStringList, readonly
On getting, this attribute must return a list of names of the object stores currently in the connected database.
No exceptions.
version of type DOMString, readonly
On getting, this attribute must return the version of this database. This attribute has the null value when the connected database is first created.
No exceptions.

3.1.6 Key Range

An individual record can be retrieved from an object store using either the record's key or the key applicable for some index that references that object store. Multiple records can be fetched using a key range. A key range is a continuous interval over some data type used for keys.

A key range may be left-bounded or right-bounded if there is a value that is, respectively, smaller than or larger than all its elements. A key range is said to be bounded if it is both left- and right-bounded and unbounded otherwise. A valid key range must be either half-bounded or bounded. A key range may be open, i.e., not including its endpoints or closed, i.e., including its endpoints. A key range may consist of a single value.

The KeyRange interface is used to define a key range.

interface KeyRange {
    const unsigned short SINGLE = 0;
    const unsigned short LEFT_OPEN = 1;
    const unsigned short RIGHT_OPEN = 2;
    const unsigned short LEFT_BOUND = 4;
    const unsigned short RIGHT_BOUND = 8;
    readonly attribute any            left;
    readonly attribute any            right;
    readonly attribute unsigned short flags;
    KeyRange only (in any value);
    KeyRange leftBound (in any bound, in optional boolean open);
    KeyRange rightBound (in any bound, in optional boolean open);
    KeyRange bound (in any left, in any right, in optional boolean openLeft, in optional boolean openRight);
};
flags of type unsigned short, readonly
Flags for bounding values
No exceptions.
left of type any, readonly
This value is the left-bound of the key range.
No exceptions.
right of type any, readonly
This value is the right-bound of the key range.
No exceptions.
bound
Create a new right-bound key range.
ParameterTypeNullableOptionalDescription
leftanyThe left-bound value
rightanyThe right-bound value
openLeftbooleanIs the left-bound value included in the key range.
openRightbooleanIs the right-bound value included in the key range.
No exceptions.
Return type: KeyRange
leftBound
Create a new left-bound key range.
ParameterTypeNullableOptionalDescription
boundanyThe left bound value
openbooleanIs the left-bound value included in the key range.
No exceptions.
Return type: KeyRange
only
Create a new single-valued key range.
ParameterTypeNullableOptionalDescription
valueanyThe only value
No exceptions.
Return type: KeyRange
rightBound
Create a new right-bound key range.
ParameterTypeNullableOptionalDescription
boundanyThe right bound value
openbooleanIs the right-bound value included in the key range.
No exceptions.
Return type: KeyRange
LEFT_BOUND of type unsigned short
This flag indicates a left-bound key range.
LEFT_OPEN of type unsigned short
This flag indicates a left-open key range.
RIGHT_BOUND of type unsigned short
This flag indicates a right-bound key range.
RIGHT_OPEN of type unsigned short
This flag indicates a right-open key range.
SINGLE of type unsigned short
This flag indicates a single-valued key range.

3.1.7 Cursor

Cursors are a transient mechanism used to iterate over multiple records in a database. The storage operations are performed on the underlying index or an object store.

A cursor comprises a range of records in either an index or an object store. A cursor maintains a position over this series, which moves in a direction that is either monotonically increasing or decreasing order of the record keys.

interface Cursor {
    const unsigned short NEXT = 0;
    const unsigned short NEXT_NO_DUPLICATE = 1;
    const unsigned short PREV = 2;
    const unsigned short PREV_NO_DUPLICATE = 3;
    readonly attribute unsigned short direction;
};
direction of type unsigned short, readonly
On getting, provide the traversal direction of the cursor.
No exceptions.
NEXT of type unsigned short
indicates that this cursor should yield all records, including duplicates and its direction is monotonically increasing order of keys.
NEXT_NO_DUPLICATE of type unsigned short
indicates that this cursor should yield all records, not including duplicates and its direction is monotonically increasing order of keys. For every key with duplicate values, only the first record is yielded.
PREV of type unsigned short
indicates that cursor should yield all records, including duplicates and its direction is monotonically decreasing order of keys.
PREV_NO_DUPLICATE of type unsigned short
indicates that this cursor should yield all records, not including duplicates and its direction is monotonically decreasing order of keys. For every key with duplicate values, only the first record is yielded.

3.1.8 Transaction

A transaction has a scope and a database. A transaction's scope is either static or dynamic. If the scope is static, it can cover either all the object stores and indexes in a database or it may include a subset of them.

A connection may have at most one transaction at any given time. Moreover, there may not be any overlap among the scopes of all open connections to a given database.

Transactions offer some protection from application and system failures. A transaction may be used to store multiple data records or to conditionally modify certain data records. A transaction represents an atomic and durable set of data access and mutation operations.

Transactions are expected to be short lived. Conforming user agents may terminate transactions that take too long to complete in order to free up storage resources that are locked by a long running transaction.

interface Transaction {
    attribute boolean  static;
    attribute Database db;
};
db of type Database
The database connection of which this transaction is a part
No exceptions.
static of type boolean
If true, then this transaction is static and false otherwise.
No exceptions.

3.2 Algorithms

3.2.1 Opening the database

The steps for opening a database are as follows. These steps must be run with an origin, a database name and description. All the steps must be run atomically:

  1. If there is already a database with the given name from the origin origin, then let db be that database.
  2. If no database with the given name from the origin origin exists, then create the database db with the name and description passed to these steps.
  3. Create a connection to db and call it result.
  4. Return result.

3.2.2 Object Store Storage steps

The steps for storing a record into an object store are as follows. These steps must be run with four parameters: the object store, a value, an optional key, and an optional no-overwrite flag.

  1. Let store be the object store, key be the key and value be the value passed to these steps.
  2. If store uses out-of-line keys but no key generator, then a key must be passed to these steps. If not, terminate these steps and set error code DATA_ERR.
  3. If store uses in-line keys, then let key be the property of object at store's key path.
  4. If key is defined and not null, then skip the next step.
  5. Produce a structured clone of value and call it object.
  6. Perform the following steps.
    1. Using store's key generator, produce the next key and store it as key.
    2. If store uses in-line keys, then store key as the property value for object at store's key path.
  7. If the no-overwrite flag was passed to these steps and is set, and a record already exists with its key being key, then terminate these steps and set error code CONSTRAINT_ERR.
  8. Store a record in store containing key as its key and object as its value. If any indexes are auto-populated for store, then store a record in that index according to index maintenance conditions.

    Storing would mean inserting if no record exists for that key or updating an existing record, otherwise. Auto populated index record will also be respectively inserted or updated depending on what storing results in.
  9. Return the key.

3.2.3 Index Storage steps

The steps for storing a record into an index are as follows. These steps must be run with four parameters: the index, a key, a value, and a no-overwrite flag.

  1. Let index be the index, key be the key and value be the value passed to these steps.
  2. If index has a key path, then terminate these steps and set error code CONSTRAINT_ERR.
  3. If the no-overwrite flag was passed to these steps and is set, and a record already exists in index with its key being key, then terminate these steps and set error code CONSTRAINT_ERR.
  4. If no record exists in index's referenced object store whose key is value, then terminate these steps and set error code CONSTRAINT_ERR.
  5. Store a record in index containing key as its key and value as its value.

    Storing would mean inserting if no record exists for that key or updating an existing record, otherwise.
  6. Return the key.

3.2.4 Object Store Retrieval steps

The steps for retrieving a record from an object store are as follows. These steps must be run with two parameters - the record key and the object store.

  1. Let key be the key and store be the object store passed to these steps.
  2. If no record exists with key key in store, then terminate these steps and set error code NOT_FOUND_ERR.
  3. Return the a new structured clone of the value in the record with key key in store.

3.2.5 Index Referenced Value Retrieval steps

The steps for retrieving a record from an index are as follows. These steps must be run with two parameters - the record key and the index.

  1. Let key be the key and index be the index passed to these steps.
  2. If no record exists with key key in index, then terminate these steps and set error code NOT_FOUND_ERR.
  3. Let value be the value of the record with key key in index.
  4. Return the value for the record with key value in index's referenced object store.

3.2.6 Index Value Retrieval steps

The steps for retrieving a value from an index are as follows. These steps must be run with two parameters - the record key and the index.

  1. Let key be the key and index be the index passed to these steps.
  2. If no record exists with key key in index, then terminate these steps and set error code NOT_FOUND_ERR.
  3. Return the value of the record with key key in index.

3.2.7 Obejct Store Deletion steps

The steps for deleting a record from an object store are as follows. These steps must be run with two parameters: the key of the record to be deleted and the object store.

  1. Let key be the key and store be the object store passed to these steps.
  2. If no record exists with key key in store, then terminate these steps and set error code NOT_FOUND_ERR.
  3. If any indexes are auto-populated for store, then remove the record in that index according to index maintenance conditions.
  4. Remove the record from store with key key.

3.2.8 Index Deletion steps

The steps for deleting a record from an index are as follows. These steps must be run with two parameters: the key of the record to be deleted and the index.

  1. Let key be the key and index be the index passed to these steps.
  2. If no record exists with key key in index, then terminate these steps and set error code NOT_FOUND_ERR.
  3. Remove the records from index with key key.

3.2.9 Transaction Creation steps

When the user agent is to create a transaction it must run the following steps. These steps must be run with two parameters - database and an optional list of names of database objects to be reserved.

  1. If the database passed to these steps has an active transaction, then terminate these steps and set error code NON_TRANSIENT_ERR.
  2. Pick the appropriate steps:
    If these steps are not called with a list of database objects
    Acquire a lock on the entire database.
    If these steps are called with a non-empty list of database objects
    1. If any of the objects in this array is not a database object, then set code to NON_TRANSIENT_ERR and jump to the last step.
    2. Acquire appropriate locks on each of the database objects and the objects they depend on in an ordered sequence.
      If the database does not allow fine grained locking, then a user agent may obtain a shared or exclusive lock on the database.
    If these steps are called with an empty array of database objects
    Do not acquire locks on any database objects now. Locks are obtained as the application attempts to access those objects.
    Using the database in this style may lead to deadlocks. Programmers must use caution to acquire and release database objects in the same global order to avoid deadlocks.
  3. If a timeout duration is passed to these steps and is exceeded when acquiring locks, then set code to TIMEOUT_ERR and jump to the last step.
  4. Open a new transaction to the database, and create a Transaction object that represents that transaction. Let transaction be this object.
  5. Set the current transaction of this Database object to transaction.
  6. Return transaction. End these steps.
  7. This step is only performed in case of error. If this step is performed synchronously, then raise a newly constructed DatabaseException exception exception with the code code.

3.3 Synchronous APIs

3.3.1 Opening a database connection

Worker objects must implement the EnvironmentSync interface.

WorkerUtils implements EnvironmentSync;
interface EnvironmentSync {
    readonly attribute IndexedDatabase indexedDB;
};
indexedDB of type IndexedDatabase, readonly
This attribute provides applications a means of accessing capabilities of indexed databases.
No exceptions.
interface IndexedDatabase {
    DatabaseSync open (in DOMString name, in DOMString description, in optional boolean modifyDatabase) raises (DatabaseException);
};
open

The synchronous API for databases blocks the calling thread until a DatabaseSync object is ready to return. When this method is invoked, the user agent must run the following steps:

  1. Let origin be the origin of the scripts in the worker.
  2. Perform the steps for opening a database, with origin, the name parameter and description parameter, and call its result as result.
  3. If the steps were aborted with an error code, then throw a newly constructed DatabaseException exception with the code of that error and abort these steps.
  4. Create a DatabaseSync object using result and call it db.
  5. Return db.
ParameterTypeNullableOptionalDescription
nameDOMStringThe name for the database
descriptionDOMStringThe description for the database
modifyDatabasebooleanThis defaults to true
ExceptionDescription
DatabaseException
UNKNOWN_ERRif an error occurs while the database connection is being opened
NON_TRANSIENT_ERRif the name parameter is not valid
Return type: DatabaseSync

3.3.2 Database connection

A database connection can be used to manipulate the objects of that database. That is also the only means of obtaining a transaction for that database.

interface DatabaseSync : Database {
    ObjectStoreSync createObjectStore ([Null=Empty] in DOMString name, [Null=Null] in DOMString keyPath, in optional boolean autoIncrement) raises (DatabaseException);
    ObjectStoreSync openObjectStore (in DOMString name, in optional unsigned short mode) raises (DatabaseException);
    IndexSync       createIndex ([Null=Empty] in DOMString name, [Null=Empty] in DOMString storeName, in DOMString keyPath, in optional boolean unique) raises (DatabaseException);
    IndexSync       openIndex (in DOMString name) raises (DatabaseException);
    void            removeObjectStore (in DOMString storeName) raises (DatabaseException);
    void            removeIndex (in DOMString indexName) raises (DatabaseException);
    void            setVersion ([Null=Null] in DOMString version);
    TransactionSync transaction (in optional DOMStringList storeNames, in optional unsigned int timeout) raises (DatabaseException);
};
createIndex

This method creates a and returns a new index with the given name in the connected database.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of a new index
storeNameDOMStringThe name of an existing object store referenced by the new index
keyPathDOMStringThe key path used by the new index
uniquebooleanThe unique flag for the new index
ExceptionDescription
DatabaseException
CONSTRAINT_ERR If an index with the same name, compared in a case-sensitive manner, already exists in the connected database.
NOT_FOUND_ERR If the object store with the given name does not exist in the connected database.
Return type: IndexSync
createObjectStore

This method creates a and returns a new object store with the given name in the connected database.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of a new object store
keyPathDOMStringThe key path of a new object store. If null path is specified, then the object store created will not have a key path and will use out-of-line keys.
autoIncrementbooleanWhether the object store created should have a key generator.
ExceptionDescription
DatabaseException
CONSTRAINT_ERR If an object store with the same name, compared in a case-sensitive manner, already exists in the connected database.
Return type: ObjectStoreSync
openIndex

This method opens the index with the given name in the connected database for the mode specified.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of an existing index
ExceptionDescription
DatabaseException
NOT_FOUND_ERR If the index with the given name does not exist in the connected database.
Return type: IndexSync
openObjectStore

This method opens the object store with the given name in the connected database for the mode specified.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of an existing object store
modeunsigned shortThe mode used to access the object store
ExceptionDescription
DatabaseException
NOT_FOUND_ERR If an object store with the same name, compared in a case-sensitive manner, already exists in the connected database.
Return type: ObjectStoreSync
removeIndex

This method is used to destroy an index with the given name.

ParameterTypeNullableOptionalDescription
indexNameDOMStringThe name of an existing index
ExceptionDescription
DatabaseException
NOT_FOUND_ERR If the index with the given name does not exist in the connected database.
Return type: void
removeObjectStore

This method is used to destroy an object store with the given name as well as all indexes that are referencing that object store.

ParameterTypeNullableOptionalDescription
storeNameDOMStringThe name of an existing object store
ExceptionDescription
DatabaseException
NOT_FOUND_ERR If the object store with the given name, compared in a case-sensitive manner, does not already exist in the connected database.
Return type: void
setVersion
This method is used to set the version of the connected database.
ParameterTypeNullableOptionalDescription
versionDOMStringThe version to store in the database
No exceptions.
Return type: void
transaction
Perform the steps for creating a transaction with the list of database objects for acquiring locks required in this transaction and an optional timeout duration, and return the resulting TransactionSync object.
ParameterTypeNullableOptionalDescription
storeNamesDOMStringListThe names of object stores and indexes in the scope of the new transaction
timeoutunsigned intThe interval which this operation is allowed to take to reserve all the database objects identified in the new transaction's scope. The default is user agent specific
ExceptionDescription
DatabaseException
TIMEOUT_ERR If reserving all the database objects identified in the new transaction's scope takes longer than the specified interval.
Return type: TransactionSync

3.3.3 Object Store

Example

In the following example, we set up an object store to use the key path id. This object store is also designed to use a key generator.

ECMAScript
var db = indexedDB.open('AddressBook', 'Address Book');
if (db.version !== '1') {
   var olddb = indexedDB.open('AddressBook', 'Address Book');
   olddb.createObjectStore('Contact', 'id', true);
   olddb.setVersion('1');
}

Using this database, we can store records in the Contact object store.

ECMAScript
var store = db.openObjectStore('Contact');

var lincoln = {name: 'Lincoln', number: '7012'};
var contact = store.put(lincoln);
// contact.id === 1

A stored value can be retrieved using the same key used by the first put operation.

ECMAScript
var contact = store.<>get(1);
// contact.name === 'Lincoln'

A second put operation will overwrite the record stored by the first put operation.

ECMAScript
var abraham = {id: 1, name: 'Abraham', number: '2107'};
store.put(abraham);

Now when the object store is read with the same key, the result is different compared to the object read earlier.

ECMAScript
var contact = store.get(1);
// contact.id === 1 && contact.name === 'Abraham';

Additionally, all the records of an object store matching a certain key range can be retrieved in key order.

ECMAScript
var range = new KeyRange.bound(2, 4);
var cursor = store.openCursor(range);
// each value is a contact and each key is the id for that  
// contact whose id is between 2 and 4, both inclusive
cursor.continue();
interface ObjectStoreSync : ObjectStore {
    any        put (in any value, in optional any key, in optional boolean noOverwrite) raises (DatabaseException);
    void       delete (in any key) raises (DatabaseException);
    any        get (in any key) raises (DatabaseException);
    CursorSync openCursor (in optional KeyRange range, in optional unsigned short direction) raises (DatabaseException);
};
delete
Remove the record from this object store by following the steps for deleting a record from an object store corresponding to the given key.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be removed
ExceptionDescription
DatabaseException
NOT_FOUND_ERRA record did not exist in this object store for the key key
Return type: void
get
Retrieve the value from this object store for the record corresponding to the given key by following the steps for retrieving a record from an object store. The value returned from this method is the retrieved value.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
ExceptionDescription
DatabaseException
SERIAL_ERRThe data being stored could not be deserialized by the internal structured cloning algorithm
NOT_FOUND_ERRA record did not exist in this object store for the key key parameter.
Return type: any
openCursor
Create a cursor over the records of this object store. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
ExceptionDescription
DatabaseException
NOT_FOUND_ERRNo records exist in this object store for the requested key range.
Return type: CursorSync
put
Store the given value in this object store by following the steps for storing a record into an object store. The returned object from this method is the key for the stored record.
ParameterTypeNullableOptionalDescription
valueanyThe value to be stored in the record
keyanyThe key used to identify the record
noOverwritebooleanWhether to overwrite an existing record with the same key
ExceptionDescription
DatabaseException
DATA_ERRThis object store uses out-of-line keys and no key generator but the key parameter was not passed
SERIAL_ERRThe data being stored could not be serialized by the internal structured cloning algorithm
CONSTRAINT_ERRThe noOverwrite parameter was true and a record exists in this object store for the key key parameter.
Return type: any

3.3.4 Index

Example

An index can be created for retrieving records other than by using record keys. Continuing the earlier example, an auto-populated index could be maintained on the name property of objects in the Contact object store.

ECMAScript
var db = indexedDB.open('AddressBook', 'Address Book');
if (db.version === '1') {
   var olddb = indexedDB.open('AddressBook', 'Address Book');
   olddb.createObjectStore('Contact', 'id', true);
   olddb.createIndex('ContactName', 'Contact', 'name', false);
   olddb.setVersion('2');
}

For example, the id of an object with the name property value 'Lincoln' can be retrieved using the ContactName index.

ECMAScript
var index = db.openIndex('ContactName');
var id = index.get('Lincoln');
// id === 1

Additionally, all the records of an object store matching a certain range index keys can be retrieved in key order. When objects are retrieved from the Contact object store, they are arranged by the value of the id attribute. On the other hand, when objects are retrieved using the ContactName index, they are arranged by the value of the name property.

ECMAScript
var range = new KeyRange.bound('L', 'M');
var cursor = index.openCursor(range);
// each value is a contact and each key is the name for that  
// contact whose name's first letter is either L or M
cursor.continue();

If, on the other hand, we only want the names but not the Contact objects for a given range, then we can use a different mechanism for that.

ECMAScript
var range = new KeyRange.bound('L', 'M');
var cursor = index.openObjectCursor(range);
// each value is a contact and each key is the name for that  
// contact whose name's first letter is either L or M
cursor.continue();
interface IndexSync {
    void openObjectCursor (in optional KeyRange range, in optional unsigned short direction) raises (DatabaseException);
    void openCursor (in optional KeyRange range, in optional unsigned short direction) raises (DatabaseException);
    any  put (in any value, in optional any key, in optional boolean noOverwrite) raises (DatabaseException);
    any  getObject (in any key) raises (DatabaseException);
    any  get (in any key) raises (DatabaseException);
    void delete (in any key) raises (DatabaseException);
};
delete
Remove the records from this index by following the steps for deleting a record from an index corresponding to the given key.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be removed
ExceptionDescription
DatabaseException
NOT_FOUND_ERRA record did not exist in this index for the key key
Return type: void
get
Retrieve the value from this index for the record corresponding to the given key by following the steps for retrieving a value from an index. The value returned from this method is the retrieved value.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
ExceptionDescription
DatabaseException
NOT_FOUND_ERRA record did not exist in this index for the key key parameter.
Return type: any
getObject
Retrieve the value from this index's referenced object store for the record corresponding to the given key by following the steps for retrieving a record from an index. The value returned from this method is the retrieved value.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
ExceptionDescription
DatabaseException
NOT_FOUND_ERRA record did not exist in this index for the key key parameter.
Return type: any
openCursor
Create a cursor over the records of this index. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
ExceptionDescription
DatabaseException
NOT_FOUND_ERRNo records exist in this index for the requested key range.
Return type: void
openObjectCursor
Create a cursor over the records of this index's referenced object store as arranged by this index. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
ExceptionDescription
DatabaseException
NOT_FOUND_ERRNo records exist in this index for the requested key range.
Return type: void
put
Store the given value in this index by following the steps for storing a record into an index. The returned object from this method is the key for the stored record.
ParameterTypeNullableOptionalDescription
valueanyThe value to be stored in the record
keyanyThe key used to identify the record
noOverwritebooleanWhether to overwrite an existing record with the same key. This defaults to false.
ExceptionDescription
DatabaseException
CONSTRAINT_ERRThe noOverwrite parameter was true and a record exists in this index for the key key parameter or this index is auto-populated or if no record exists with key value parameter in the index's referenced object store.
Return type: any

3.3.5 Cursor

Using the synchronous API, an application can process all the records in the cursor's range. No two values provided by the user agent to callbacks processing data in this cursor can be identical.

Example

By default, a cursor walks over objects starting at the first record and ending at the last record including all the duplicates encountered along the way. If the cursor callback returns true, then the iteration is stopped.

ECMAScript
var objects = ...
var cursor = objects.openCursor();
// act on each object and continue the cursor to its end
cursor.continue();

To start at the last record and end in the first record, the cursor should be created with the direction parameter PREV.

ECMAScript
var objects = ...
var count = objects.openCursor(Cursor.PREV);
// act on each object and continue the cursor to its end
cursor.continue();

To start at a certain key and end in the last record, i.e., for a lower-bounded cursor, while skipping duplicates, the cursor should be created with both the required start key and the direction parameter.

ECMAScript
var objects = ...
var range = KeyRange.leftBound(key);
objects.openCursor(range, Cursor.NEXT_NO_DUPLICATE);
// act on each object and continue the cursor to its end
cursor.continue();

It is also possible to create a bounded cursor, i.e., with application-specified starting and ending points, the cursor should be created with both the required keys. If the range is inclusive of both keys, then additional flags are required. In the following example, all keys with values in the inclusive range (start, end) are returned with all their duplicates, from the beginning of the range to its end.

ECMAScript
var objects = ...
var range = KeyRange.bound(start, end);
objects.openCursor(range);
// act on each object and continue the cursor to its end
cursor.continue();
interface CursorSync {
    readonly attribute any                key;
             attribute any                value setraises (DatabaseException);
    readonly attribute unsigned long long count;
    bool continue (in optional any key);
    void delete () raises (DatabaseException);
};
count of type unsigned long long, readonly
On getting, provide the total number of objects that share the current key.
No exceptions.
key of type any, readonly
The key for the record at the cursor's position.
No exceptions.
value of type any
The value for the record at the cursor's position.
ExceptionOn GetOn SetDescription
DatabaseException
DATA_ERRIf the underlying object store uses in-line keys and the property at the key path does not match the key in this cursor's position.
SERIAL_ERRThe data being stored could not be serialized by the internal structured cloning algorithm
NOT_ALLOWED_ERRThe underlying index or object store does not support updating the item because it is open in the READ_ONLY or SNAPSHOT_READ mode.
continue
Advance the cursor to the next position along its direction to the item whose key matches the optional parameter. If no such parameter is provided, advance to the immediate next position. If the cursor has reached the end of its range, then this method returns false, otherwise it returns true.
ParameterTypeNullableOptionalDescription
keyanyThe next key to position this cursor at
No exceptions.
Return type: bool
delete

Delete the object at the cursor's position.

No parameters.
ExceptionDescription
DatabaseException
NOT_ALLOWED_ERRThe underlying index or object store does not support updating the item because it is open in the READ_ONLY or SNAPSHOT_READ mode.
Return type: void

3.3.6 Transaction

When an application creates a transaction synchronously, it blocks until the user agent is able to reserve the required database objects.

interface TransactionSync : Transaction {
    void abort () raises (DatabaseException);
    void commit () raises (DatabaseException);
};
abort
This method is used to signal the need to cancel the effects of operations performed in this transaction. To perform this method, the user agent ignores all the changes performed to the objects of this database since the creation of this transaction.
No parameters.
ExceptionDescription
DatabaseException
NON_TRANSIENT_ERRIf this transaction has already been committed or aborted.
Return type: void
commit
This method is used to signal the normal and satisfactory completion of a transaction. At this point, the user agent should durably store all the changes performed to the objects of this database since the creation of this transaction.
No parameters.
ExceptionDescription
DatabaseException
RECOVERABLE_ERRIf this transaction's scope is dynamic, and the user agent cannot commit all the changes due to another transaction.
NON_TRANSIENT_ERRIf this transaction has already been committed or aborted.
Return type: void
Applications must not assume that committing the transaction produces an instantaneously durable result. The user agent may delay flushing data to durable storage until an appropriate time.

Once a transaction is aborted or committed, the active transaction on this database connection is removed. A new transaction can be created to perform operations atomically.

3.3.7 The DatabaseException Interface

exception DatabaseException {
    const unsigned short UNKNOWN_ERR = 0;
    const unsigned short NON_TRANSIENT_ERR = 1;
    const unsigned short NOT_FOUND_ERR = 2;
    const unsigned short CONSTRAINT_ERR = 3;
    const unsigned short DATA_ERR = 4;
    const unsigned short NOT_ALLOWED_ERR = 5;
    const unsigned short SERIAL_ERR = 11;
    const unsigned short RECOVERABLE_ERR = 21;
    const unsigned shrot TRANSIENT_ERR = 31;
    const unsigned short TIMEOUT_ERR = 32;
    const unsigned short DEADLOCK_ERR = 33;
    attribute unsigned short code;
    attribute DOMString      message;
};
code of type unsigned short
Return the most appropriate error code.
No exceptions.
message of type DOMString
Return an error message describing the exception raised. The message should be localized to the user's language.
No exceptions.
CONSTRAINT_ERR of type unsigned short
A mutation operation in the transaction failed due to a because a constraint was not satisfied. For example, an object such as an object store or index already exists and a new one was being attempted to be created.
DATA_ERR of type unsigned short
Data provided to an operation does not meet requirements.
DEADLOCK_ERR of type unsigned short
The current transaction was automatically rolled back by the database becuase of deadlock or other transaction serialization failures.
NON_TRANSIENT_ERR of type unsigned short
This error occurred because an operation was not allowed on an object. A retry of the same operation would fail unless the cause of the error is corrected.
NOT_ALLOWED_ERR of type unsigned short
A mutation operation was attempted on a database that did not allow mutations.
NOT_FOUND_ERR of type unsigned short
The operation failed because the requested database object could not be found. For example, an object store did not exist but was being opened.
RECOVERABLE_ERR of type unsigned short
The operation failed because the database was prevented from taking an action. The operation might be able to succeed if the application performs some recovery steps and retries the entire transaction. For example, there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database.
SERIAL_ERR of type unsigned short
The operation failed because of the size of the data set being returned or because there was a problem in serializing or deserializing the object being processed.
TIMEOUT_ERR of type unsigned short
A lock for the transaction could not be obtained in a reasonable time.
TRANSIENT_ERR of type unsigned shrot
The operation failed because of some temporary problems. The failed operation might be able to succeed when the operation is retried without any intervention by application-level functionality.
UNKNOWN_ERR of type unsigned short
The operation failed for reasons unrelated to the database itself and not covered by any other error code.

3.4 Asynchronous APIs

The asynchronous API returns without blocking the calling thread. This API can only be used in a Window. Asynchronous APIs are essentially the same as the synchronous ones except that the result of an operation is not available when the operation returns.

3.4.1 Event summary

This section is non-normative.

Events are fired during asynchronous access as database objects are created and data is consumed from these objects. As requests are made to database objects, the user agent loads information about them into memory and when the required object handle is available, it alerts the application through the firing of events. The events are as follows:

Event nameDispatched when...
success The database request has been completed and its results are available.
error There was an error performing the database request.

3.4.2 The DBRequest Interface

The DBRequest interface provides means to access results of asynchronous requests to databases and database objects using event handler attributes [DOM-LEVEL-3-EVENTS].

Example

In the following example, we open a database asynchronously. Various event handlers are registered for responding to various situations.

ECMAScript
indexedDB.request.onsuccess = function(evt) {...};
indexedDB.request.onerror = function(evt) {...};
indexedDB.open('AddressBook', 'Address Book');
interface DBRequest {
    void abort ();
    const unsigned short INITIAL = 0;
    const unsigned short LOADING = 1;
    const unsigned short DONE = 2;
    readonly attribute unsigned short readyState;
    readonly attribute DatabaseError  error;
    readonly attribute any            result;
             attribute Function       onsuccess;
             attribute Function       onerror;
};
error of type DatabaseError, readonly
The error that occurred during the requested operation
No exceptions.
onerror of type Function
The event handler for error event
No exceptions.
onsuccess of type Function
The event handler for success event
No exceptions.
readyState of type unsigned short, readonly
The state of this object
No exceptions.
result of type any, readonly
The result of a successful requested operation
No exceptions.
abort
Discontinue the in-flight request and return the readyState to INITIAL. No result or error is set.
No parameters.
No exceptions.
Return type: void
DONE of type unsigned short
This state indicates that a result to a previous request is available in the result attribute.
INITIAL of type unsigned short
This state indicates that a request has not been started.
LOADING of type unsigned short
This state indicates that a request has been started but its results is not yet available.
DBRequest implements EventTarget;

All instances of the DBRequest type are defined to also implement the EventTarget interface.

When a request is made, the readyState changes to LOADING. Once the result of the request is available, the readyState changes to DONE, place the result of the request in result, and aueue a task to fire an event with the name success, with no namespace, which does not bubble, is not cancelable, and which uses the Event interface at each Window object.

If an exception occurs while performing the operation, the readyState changes to DONE, the error information is placed in a new DatabaseError object at the error attribute, and queue a task to fire an event with the name error, with no namespace, which does not bubble, is not cancelable, and which uses the Event interface at each Window object.

The task source for these tasks is the database access task source.

3.4.3 Asynchronous Request API

Window objects must implement the Environment interface.

Window implements Environment;
interface Environment {
    readonly attribute IndexedDatabaseRequest indexedDB;
};
indexedDB of type IndexedDatabaseRequest, readonly
This attribute provides applications a means of accessing capabilities of indexed databases.
No exceptions.

Every interface for making asynchronous requests includes a DBRequest object that communicates back to the requesting application through events. This design means that only a single request can be active on any database or object handle at a time. If a second request is started, the user agent must abort any previous active request.

interface IndexedDatabaseRequest {
    readonly attribute DBRequest request;
    void open (in DOMString name, in DOMString description, in optional boolean modifyDatabase) raises (DatabaseException);
};
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
open

This method returns immediately and runs the following steps in a different thread. If an error occurs while the database connection is being opened, then this object's request error is populated with a new DatabaseError object whose code is set to UNKNOWN_ERR.

  1. Let origin be the origin of the active document from which the method was invoked.
  2. Perform the steps for opening a database, with origin, the name parameter and description parameter, and call its result as result.
  3. If the steps were aborted with an error code, then set this request's error with that code and abort these steps.
  4. Create a DatabaseRequest object for result and call it db.
  5. Set the result of this object's request to db.
ParameterTypeNullableOptionalDescription
nameDOMStringThe name for the database
descriptionDOMStringThe description for the database
modifyDatabasebooleanThis defaults to true
ExceptionDescription
DatabaseException
NON_TRANSIENT_ERRif the name parameter is not valid
Return type: void
interface DatabaseRequest : Database {
    readonly attribute DBRequest request;
    void createObjectStore ([Null=Empty] in DOMString name, [Null=Null] in DOMString keyPath, in optional boolean autoIncrement);
    void openObjectStore (in DOMString name, in optional unsigned short mode);
    void createIndex ([Null=Empty] in DOMString name, [Null=Empty] in DOMString storeName, in DOMString keyPath, in optional boolean unique);
    void openIndex (in DOMString name);
    void removeObjectStore (in DOMString storeName);
    void removeIndex (in DOMString indexName);
    void setVersion ([Null=Null] in DOMString version);
    void transaction (in optional DOMStringList storeNames, in optional unsigned int timeout);
};
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
createIndex

This method returns immediately and creates a new index with the given name and parameters in the connected database. If an index with the same name, compared in a case-sensitive manner, already exists in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to CONSTRAINT_ERR. If the object store with the given name does not exist in the connected database then this object's request error is populated with a new DatabaseError object whose code is set to NOT_FOUND_ERR. If the index is created, the result of this object's request is set to a new IndexRequest for that index.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of a new index
storeNameDOMStringThe name of an existing object store referenced by the new index
keyPathDOMStringThe key path used by the new index
uniquebooleanThe unique flag for the new index
No exceptions.
Return type: void
createObjectStore

This method returns immediately and creates a new object store with the given name in the connected database. If an object store with the same name, compared in a case-sensitive manner, already exists in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to CONSTRAINT_ERR. If the object store is created, the result of this object's request is set to a new ObjectStoreRequest for that object store.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of a new object store
keyPathDOMStringThe key path of a new object store. If null path is specified, then the object store created will not have a key path and will use out-of-line keys.
autoIncrementbooleanWhether the object store created should have a key generator.
No exceptions.
Return type: void
openIndex

This method returns immediately and opens the index with the given name in the connected database. If an index with the given name does not exist in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to NOT_FOUND_ERR. If the index is opened, the result of this object's request is set to a new IndexRequest for that index.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of an existing index
No exceptions.
Return type: void
openObjectStore

This method returns immediately and opens the object store with the given name in the connected database for the mode specified. If an object store with the given name does not exist in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to NOT_FOUND_ERR. If the object store is opened, the result of this object's request is set to a new ObjectStoreRequest for that object store.

ParameterTypeNullableOptionalDescription
nameDOMStringThe name of an existing object store
modeunsigned shortThe mode used to access the object store
No exceptions.
Return type: void
removeIndex

This method returns immediately and destroys the index with the given name in the connected database. If an index with the given name does not exist in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to NOT_FOUND_ERR.

ParameterTypeNullableOptionalDescription
indexNameDOMStringThe name of an existing index
No exceptions.
Return type: void
removeObjectStore

This method returns immediately and destroys the object store with the given name in the connected database as well as all indexes that are referencing that object store. If an object store with the given name does not exist in the connected database, then this object's request error is populated with a new DatabaseError object whose code is set to NOT_FOUND_ERR.

ParameterTypeNullableOptionalDescription
storeNameDOMStringThe name of an existing object store
No exceptions.
Return type: void
setVersion
This method returns immediately and sets the version of the connected database.
ParameterTypeNullableOptionalDescription
versionDOMStringThe version to store in the database
No exceptions.
Return type: void
transaction
This method returns immediately and performs the steps for creating a transaction with the list of database objects for acquiring locks required in this transaction and an optional timeout duration. If a transaction can be created successfully, then the result of this object's request is set to a new TransactionRequest object. If reserving all the database objects identified in the requested scope takes longer than the specified timeout interval, then the error of this object's request is set to the code TIMEOUT_ERR.
ParameterTypeNullableOptionalDescription
storeNamesDOMStringListThe names of object stores and indexes in the scope of the new transaction
timeoutunsigned intThe interval which this operation is allowed to take to reserve all the database objects identified in the new transaction's scope. The default is user agent specific
No exceptions.
Return type: void
interface ObjectStoreRequest : ObjectStore {
    readonly attribute DBRequest request;
    void put (in any value, in optional any key, in optional boolean noOverwrite);
    void delete (in any key);
    void get (in any key);
    void openCursor (in optional KeyRange range, in optional unsigned short direction);
};
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
delete
This method returns immediately and removes the record from this object store by following the steps for deleting a record from an object store corresponding to the given key. If a record did not exist in this object store for the key key parameter, then the error for this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be removed
No exceptions.
Return type: void
get
This method returns immediately and retrieves the value from this object store for the record corresponding to the given key by following the steps for retrieving a record from an object store. If the operation is successful, then the result of this object's request is set to the retrieved value. If a record did not exist in this object store for the key key parameter, then the error for this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
No exceptions.
Return type: void
openCursor
This method returns immediately and creates a cursor over the records of this object store. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records. If there is even a single record that matches the key range, then the result of this object's request is set to the CursorRequest object for that cursor. If no records match the key range, then the error of this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
No exceptions.
Return type: void
put
This method returns immediately and stores the given value in this object store by following the steps for storing a record into an object store. If the record can be successfully stored in the object store, then the result of this object's request is set to the key for the stored record. If the noOverwrite parameter was true and a record exists in this object store for the key key parameter, then the error for this object's request is set to code CONSTRAINT_ERR. If this object store uses out-of-line keys but does not use a key generator and the key parameter was not passed, then the error for this object's request is set to code DATA_ERR. If the data being stored could not be serialized by the internal structured cloning algorithm, then the error for this object's request is set to code SERIAL_ERR.
ParameterTypeNullableOptionalDescription
valueanyThe value to be stored in the record
keyanyThe key used to identify the record
noOverwritebooleanWhether to overwrite an existing record with the same key
No exceptions.
Return type: void
interface IndexRequest : Index {
    readonly attribute DBRequest request;
    void openObjectCursor (in optional KeyRange range, in optional unsigned short direction);
    void openCursor (in optional KeyRange range, in optional unsigned short direction);
    void put (in any value, in optional any key, in optional boolean noOverwrite);
    void getObject (in any key);
    void get (in any key);
    void delete (in any key);
};
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
delete
This method returns immediately and removes the records from this index by following the steps for deleting a record from an index corresponding to the given key. If a record did not exist in this index for the key key parameter, then the error for this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be removed
No exceptions.
Return type: void
get
This method returns immediately and retrieves the value from this index for the record corresponding to the given key parameter by following the steps for retrieving a value from an index. If the operation is successful, then the result of this object's request is set to the retrieved value. If a record did not exist in this index for the key key parameter, then the error for this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
No exceptions.
Return type: void
getObject
This method returns immediately and retrieves the value from this index's referenced object store for the record corresponding to the given key by following the steps for retrieving a record from an index. If the operation is successful, then the result of this object's request is set to the retrieved value. If a record did not exist in this index for the key key parameter, then the error for this object's request is set to code NOT_FOUND_ERR. -
ParameterTypeNullableOptionalDescription
keyanyKey identifying the record to be retrieved
No exceptions.
Return type: void
openCursor
This method returns immediately and creates a cursor over the records of this index. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records. If there is even a single record that matches the key range, then the result of this object's request is set to the CursorRequest object for that cursor. If no records match the key range, then the error of this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
No exceptions.
Return type: void
openObjectCursor
This method returns immediately and creates a cursor over the records of this index's referenced object store as arranged by this index. The range of this cursor matches the key range specified as the range parameter, or if that parameter is not specified or null, then the range includes all the records. If there is even a single record that matches the key range, then the result of this object's request is set to the CursorRequest object for that cursor. If no records match the key range, then the error of this object's request is set to code NOT_FOUND_ERR.
ParameterTypeNullableOptionalDescription
rangeKeyRangeThe key range to use as the cursor's range
directionunsigned shortThe cursor's required direction
No exceptions.
Return type: void
put
This method returns immediately and stores the given value in this index by following the steps for storing a record into an index. If the operation succeeds, then the result of this object's request is set to the key for the stored record. If the noOverwrite parameter was true and a record exists in this index for the key key parameter or this index is auto-populated or if no record exists with key value parameter in the index's referenced object store, then the error of this object's request is set to code CONSTRAINT_ERR.
ParameterTypeNullableOptionalDescription
valueanyThe value to be stored in the record
keyanyThe key used to identify the record
noOverwritebooleanWhether to overwrite an existing record with the same key. This defaults to false.
No exceptions.
Return type: void
interface CursorRequest : Cursor {
    readonly attribute DBRequest          request;
    readonly attribute any                key;
    readonly attribute any                value;
    readonly attribute unsigned long long count;
    void update (in any value);
    void continue (in optional any key);
    void delete ();
};
count of type unsigned long long, readonly
On getting, provide the total number of objects that share the key at the cursor's position.
No exceptions.
key of type any, readonly
The key for the record at the cursor's position.
No exceptions.
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
value of type any, readonly
The value for the record at the cursor's position.
No exceptions.
continue
This method returns immediately and advances the cursor to the next position along its direction to the item whose key matches the optional parameter. If no such parameter is provided, advance to the immediate next postion. If the cursor has reached the end of its range, then the error for this object's request is set to code NOT_ALLOWED_ERR.
ParameterTypeNullableOptionalDescription
keyanyThe next key to position this cursor at
No exceptions.
Return type: void
delete

This method returns immediately and deletes the object at the cursor's position. If the underlying index or object store does not support updating the item because it is open in the READ_ONLY or SNAPSHOT_READ mode, then the error for this object's request is set to code NOT_ALLOWED_ERR.

No parameters.
No exceptions.
Return type: void
update
This method returns immediately and sets the value for the record at the cursor's position. If the underlying object store uses in-line keys and the property at the key path does not match the key in this cursor's position, then the error for this object's request is set to code DATA_ERR. If the underlying index or object store does not support updating the item because it is open in the READ_ONLY or SNAPSHOT_READ mode, then the error for this object's request is set to code NOT_ALLOWED_ERR. If the data being stored could not be serialized by the internal structured cloning algorithm, then the error for this object's request is set to code SERIAL_ERR.
ParameterTypeNullableOptionalDescription
valueany
No exceptions.
Return type: void
interface TransactionRequest : Transaction {
    readonly attribute DBRequest request;
    void abort ();
    void commit ();
};
request of type DBRequest, readonly
The request associated with this object, which will be used to relay the results of processing back to the caller
No exceptions.
abort
This method returns immediately and undoes all the changes performed to the objects of this database since the creation of this transaction. If this transaction has already been committed or aborted, then the error for this object's request is set to code NON_TRANSIENT_ERR.
No parameters.
No exceptions.
Return type: void
commit
This method returns immediately and durably stores all the changes made to the objects of this database since the creation of this transaction. If this transaction has already been committed or aborted, then the error for this object's request is set to code NON_TRANSIENT_ERR. If this transaction's scope is dynamic, and the user agent cannot commit all the changes due to conflicts with another transaction, then the error for this object's request is set to code RECOVERABLE_ERR.
No parameters.
No exceptions.
Return type: void

3.4.4 Events

The following are the event handlers (and their corresponding event handler event types) that must be supported, as IDL attributes, by objects implementing the DBRequest interface:

Event handler Event handler event type
onsuccess success
onerror error

3.4.5 The DatabaseError Interface

Errors in the asynchronous database API are reported using callbacks that have a DatabaseError object as one of their arguments.

interface DatabaseError {
    attribute unsigned short code;
    attribute DOMString      message;
};
code of type unsigned short
Return the most appropriate error code.
No exceptions.
message of type DOMString
Return an error message describing the exception raised. The message should be localized to the user's language.
No exceptions.

4. Privacy

4.1 User tracking

A third-party host (or any object capable of getting content distributed to multiple sites) could use a unique identifier stored in its client-side database to track a user across multiple sessions, building a profile of the user's activities. In conjunction with a site that is aware of the user's real idobject (for example an e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous Web usage.

There are a number of techniques that can be used to mitigate the risk of user tracking:

Blocking third-party storage
User agents may restrict access to the database objects to scripts originating at the domain of the top-level document of the browsing context, for instance denying access to the API for pages from other domains running in iframes.
Expiring stored data

User agents may automatically delete stored data after a period of time.

This can restrict the ability of a site to track a user, as the site would then only be able to track the user across multiple sessions when he authenticates with the site itself (e.g. by making a purchase or logging in to a service).

However, this also puts the user's data at risk.

Treating persistent storage as cookies

User agents should present the database feature to the user in a way that associates them strongly with HTTP session cookies. [COOKIES]

This might encourage users to view such storage with healthy suspicion.

Site-specific white-listing of access to databases

User agents may require the user to authorize access to databases before a site can use the feature.

Origin-tracking of stored data

User agents may record the origins of sites that contained content from third-party origins that caused data to be stored.

If this information is then used to present the view of data currently in persistent storage, it would allow the user to make informed decisions about which parts of the persistent storage to prune. Combined with a blacklist ("delete this data and prevent this domain from ever storing data again"), the user can restrict the use of persistent storage to sites that he trusts.

Shared blacklists

User agents may allow users to share their persistent storage domain blacklists.

This would allow communities to act together to protect their privacy.

While these suggestions prevent trivial use of this API for user tracking, they do not block it altogether. Within a single domain, a site can continue to track the user during a session, and can then pass all this information to the third party along with any identifying information (names, credit card numbers, addresses) obtained by the site. If a third party cooperates with multiple sites to obtain such information, a profile can still be created.

However, user tracking is to some extent possible even with no cooperation from the user agent whatsoever, for instance by using session identifiers in URLs, a technique already commonly used for innocuous purposes but easily repurposed for user tracking (even retroactively). This information can then be shared with other sites, using using visitors' IP addresses and other user-specific data (e.g. user-agent headers and configuration settings) to combine separate sessions into coherent user profiles.

4.3 Sensitivity of data

User agents should treat persistently stored data as potentially sensitive; it's quite possible for e-mails, calendar appointments, health records, or other confidential documents to be stored in this mechanism.

To this end, user agents should ensure that when deleting data, it is promptly deleted from the underlying storage.

5. Authorization

5.1 DNS spoofing attacks

Because of the potential for DNS spoofing attacks, one cannot guarantee that a host claiming to be in a certain domain really is from that domain. To mitigate this, pages can use SSL. Pages using SSL can be sure that only pages using SSL that have certificates identifying them as being from the same domain can access their databases.

5.2 Cross-directory attacks

Different authors sharing one host name, for example users hosting content on geocities.com, all share one set of databases.

There is no feature to restrict the access by pathname. Authors on shared hosts are therefore recommended to avoid using these features, as it would be trivial for other authors to read the data and overwrite it.

Even if a path-restriction feature was made available, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.

5.3 Implementation risks

The two primary risks when implementing these persistent storage features are letting hostile sites read information from other domains, and letting hostile sites write information that is then read from other domains.

Letting third-party sites read data that is not supposed to be read from their domain causes information leakage, For example, a user's shopping wishlist on one domain could be used by another domain for targeted advertising; or a user's work-in-progress confidential documents stored by a word-processing site could be examined by the site of a competing company.

Letting third-party sites write data to the persistent storage of other domains can result in information spoofing, which is equally dangerous. For example, a hostile site could add records to a user's wishlist; or a hostile site could set a user's session identifier to a known ID that the hostile site can then use to track the user's actions on the victim site.

Thus, strictly following the origin model described in this specification is important for user security.

A. Requirements

Requirements will be written with an aim to verify that these were actually met by the API specified in this document.

B. References

B.1 Normative references

[COOKIES]
Adam Barth HTTP State Management Mechanism. IETF, November 2009
[DOM-LEVEL-3-EVENTS]
Björn Höhrmann; Tom Pixley; Philippe Le Hégaret. Document Object Model (DOM) Level 3 Events Specification. 21 December 2007. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221
[HTML5]
Ian Hickson; David Hyatt. HTML 5. 25 August 2009. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2009/WD-html5-20090825/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[WEBIDL]
Cameron McCormack. Web IDL. 19 December 2008. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2008/WD-WebIDL-20081219
[WEBWORKERS]
Ian Hickson. Web Workers. 29 October 2009. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2009/WD-workers-20091029/

B.2 Informative references

[WEBSTORAGE]
Ian Hickson. Web Storage. 10 September 2009. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2009/WD-webstorage-20090910/