CARVIEW |
Indexed Database API
W3C Recommendation
- This version:
- https://www.w3.org/TR/2015/REC-IndexedDB-20150108/
- Latest published version:
- https://www.w3.org/TR/IndexedDB/
- Latest editor's draft:
- https://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html
- Implementation report:
- https://w3c.github.io/test-results/IndexedDB/all.html
- Previous version:
- https://www.w3.org/TR/2014/PR-IndexedDB-20141120/
- Editors:
- Nikunj Mehta, Invited Expert
- Jonas Sicking, Mozilla
- Eliot Graff, Microsoft
- Andrei Popescu, Google
- Jeremy Orlow, Google
- Joshua Bell, Google
Please check the errata for any errors or issues reported since publication.
The English version of this specification is the only normative version. Non-normative translations may also be available.
Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
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 https://www.w3.org/TR/.
This is the W3C Recommendation for the Indexed Database API. Changes to this specification since the previous publication are summarized and enumerated in this document's Revision History appendix.
This specification's bugs and issues are managed in Bugzilla (new bug, open bugs). Feature requests for the next version of this specification are kept in the Indexed Database Features document.
This document was published by the Web Applications Working Group as a Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All comments are welcome.
Please see the Working Group's implementation report.
By publishing this Proposed Recommendation, W3C expects that the functionality specified in this Proposed Recommendation will not be affected by changes to DOM Level 3 Events, DOM4, Web IDL or Web Workers as those specifications proceed to Recommendation.
This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
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.
This document is governed by the 14 October 2005 W3C Process Document.
Table of Contents
- 1. Introduction
- 2. Conformance
- 3. Indexed Database API
- 3.1 Constructs
- 3.2 APIs
- 3.3 Algorithms
- 3.3.1 Opening a database
- 3.3.2 Transaction Creation steps
- 3.3.3 Steps for committing a transaction
- 3.3.4 Steps for aborting a transaction
- 3.3.5 Steps for asynchronously executing a request
- 3.3.6 Steps for extracting a key from a value using a key path
- 3.3.7
"versionchange"
transaction steps - 3.3.8 Steps for aborting a
"versionchange"
transaction - 3.3.9 Database closing steps
- 3.3.10 Database deletion steps
- 3.3.11 Fire a success event
- 3.3.12 Fire an error event
- 3.3.13 Steps to assign a key to a value using a key path
- 3.4 Database operations
- 4. Privacy
- 5. Authorization
- A. Requirements
- B. Revision History
- C. Acknowledgements
- D. References
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.
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 MAY, MUST, and MUST NOT 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]
NoteThis 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.
- DOM-LEVEL-3-EVENTS
- The terms default action and propagation path are defined by the Document Object Model (DOM) Level 3 Events Specification [DOM-LEVEL-3-EVENTS].
- DOM4
- The types
DOMException
andEvent
are defined by the W3C DOM4 Specification [DOM4]. - 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]. - WebIDL
- Many of the interface definitions and all of the IDL in this spec depends on [WEBIDL].
- WebWorkers
- The terms
Worker
andWorkerUtils
are defined by the WebWorkers specification [WEBWORKERS].
3. Indexed Database API
3.1 Constructs
3.1.1 Database
A database's origin is the same as the origin of the document or worker. Each origin has an associated set of databases.
The database origin is not affected by changes to document.domain
.
Each origin has an associated set of databases. A database comprises one or more object stores which hold the data stored in the database.
Every database has a name which identifies it within a specific origin. The name can be any string value, including the empty string, and stays constant for the lifetime of the database. Each database also has a current version. When a database is first created, its version is 0.
Implementations MUST support all names. If an implementation uses a storage mechanism which can't handle arbitrary database names, the implementation must use an escaping mechanism or something similar to map the provided name to a name that it can handle.
Each database has one version at a time; a database
can't exist in multiple versions at once. The only way to change the version is using a "versionchange"
transaction.
Databases has a delete pending flag which is used during deletion. When a database is requested to be deleted the flag is set to true and all attempts at opening the database are stalled until the database can be deleted.
The act of opening a database creates a connection. There MAY be multiple connections to a given database at any given time. Each connection has a closePending flag which initially is set to false.
When a connection is initially created it is in opened state. The connection can be closed through several means. If the connection is GCed or execution context where the connection is created is destroyed (for example due to the user navigating away from that page), the connection is closed. The connection can also be closed explicitly using the steps for closing a database connection. When the connection is closed the closePending flag is always set to true if it hasn't already been.
The IDBDatabase
interface represents a connection to a database.
3.1.2 Object Store
An object store is the primary storage mechanism for storing data in a database.
Each database has a set of object stores. The set of object stores can be changed,
but can only be changed using a "versionchange"
transaction, i.e. in response to a
upgradeneeded
event. When a new database is created it doesn't contain any object stores.
The object store has a list of records which hold the data stored in the object store. Each record consists of a key and a value. The list is sorted according to key in ascending order. There can never be multiple records in a given object store with the same key.
Every object store has a name. The name is unique within the database to which it belongs. Every object store also optionally has a key generator and an optional key path. If the object store has a key path it is said to use in-line keys. Otherwise it is said to use out-of-line keys.
The object store can derive the key from one of three sources:
- A key generator. A key generator generates a monotonically increasing numbers every time a key is needed.
- Keys can be derived via a key path.
- Keys can also be explicitly specified when a value is stored in the object store.
The IDBObjectStore
interface represents an object store. Note however that multiple instances of those
interfaces representing the same object store can exist.
3.1.3 Keys
In order to efficiently retrieve records stored in an indexed database,
each record is organized according to its key. A value is said to be a valid key
if it is one of the following ECMAScript [ECMA-262] types:
Number
primitive value,
String
primitive value,
Date
object, or
Array
object.
An Array
is only a valid key if every item in the array is defined and is
a valid key (i.e. sparse arrays can not be valid keys) and if the Array
doesn't directly or
indirectly contain itself.
Any non-numeric properties on an Array
are ignored, and thus do not affect whether the Array
is a valid key.
If the value is of type Number
, it is only a valid key if it is not NaN
.
If the value is of type Date
it is only a valid key if its [[PrimitiveValue]]
internal property, as defined by [ECMA-262], is not NaN
.
Conforming user agents MUST support all valid keys as keys.
Infinite Number
values are valid keys. As are empty Array
s.
Operations that accept keys MUST perform as if each key parameter value, in order, is copied by the structured clone algorithm [HTML5] and the copy is instead used as input to the operation, before proceding with rest of the operation.
This implicit copying step ensures that key values do not change after
the operation begins, due to side effects such as ECMAScript [ECMA-262] getters,
setters and type conversion functions including toString()
and
valueOf()
.
For purposes of comparison, all Array
s are greater than all String
,
Date
and Number
values; all String
values are greater than all
Date
and Number
values; and all Date
values are greater than all
Number
values. Values of type Number
are compared to other Number
values
numerically. Values of type Date
are compared to other Date
values chronologically.
Values of type String
are compared to other values of type String
by using the algorithm defined by step 4 of section 11.8.5, The Abstract Relational Comparison Algorithm,
of the ECMAScript Language Specification [ECMA-262].
Values of type Array
are compared to other values of type Array
as follows:
-
Let A be the first
Array
value and B be the secondArray
value. - Let length be the lesser of A's length and B's length.
- Let i be 0.
- If the ith value of A is less than the ith value of B, then A is less than B. Skip the remaining steps.
- If the ith value of A is greater than the ith value of B, then A is greater than B. Skip the remaining steps.
- Increase i by 1.
- If i is not equal to length, go back to step 4. Otherwise continue to next step.
- If A's length is less than B's length, then A is less than B. If A's length is greater than B's length, then A is greater than B. Otherwise A and B are equal.
Note that Array
s that contain other Array
s are allowed as valid keys.
In this case the algorithm above runs recursively when comparing the individual values in the arrays.
As a result of the above rules, negative infinity is the lowest possible value for a key.
There is no highest possible key value.
This is because an Array
of any candidate highest key followed by another valid key is even higher.
The terms greater than, less than and equal to are defined in the terms of the above comparisons.
The following examples illustrate the different behaviors when trying to use in-line keys and key generators to save an object to an object store.
3.1.4 Values
Each record is associated with a value. Conforming user agents MUST support
any ECMAScript [ECMA-262] value supported by the structured clone algorithm
[HTML5]. This includes simple types such as String
primitive values
and Date
objects as well as Object
and Array
instances, File
objects, Blob
objects, ImageData
objects, and so on. Record values are stored and retrieved
by value rather than by reference; later changes to a value have no effect on
the record stored in the database.
3.1.5 Key Path
A key path is a DOMString
or sequence<DOMString>
that defines how to extract a key
from a value. A valid key path is one of:
- An empty
DOMString
. - An identifier, which is a
DOMString
matching theIdentifierName
production from the ECMAScript Language Specification [ECMA-262]. - A
DOMString
consisting of two or more identifiers separated by periods (ASCII character code 46). - A non-empty
sequence<DOMString>
containing onlyDOMString
s conforming to the above requirements.
Spaces are not allowed within a key path.
To evaluate a key path, run the steps for extracting a key from a value using a key path.
Key path values can only be accessed from properties explicitly copied by the structured clone algorithm, as well as the following properties:
Blob.size
Blob.type
File.name
File.lastModifiedDate
Array.length
String.length
3.1.6 Index
It is sometimes useful to retrieve records in an object store through other means than their key. An index allows looking up records in an object store using properties of the values in the object stores records.
An index is a specialized persistent key-value storage and 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 inserted, updated or deleted. There can be several indexes referencing the same object store, in which changes to the object store cause all such indexes to get updated.
The values in the index's records are always values of keys in the index's referenced object store. The keys are derived from the referenced object store's values using a key path. If a given record with key X in the object store referenced by the index has the value A, and evaluating the index's key path on A yields the result Y, then the index will contain a record with key Y and value X.
Records in an index are said to have a referenced value. This is the value of the record in the index's referenced object store which has a key equal to the index's record's value. So in the example above, the record in the index whose key is Y and value is X has a referenced value of A.
Each record in an index references one and only one record in the index's referenced object store. However there can be multiple records in an index which reference the same record in the object store. And there can also be no records in an index which reference a given record in an object store.
The records in an index are always sorted according to the record's key. However unlike object stores, a given index can contain multiple records with the same key. Such records are additionally sorted according to the index's record's value (meaning the key of the record in the referenced object store).
Every index has a name. The name is unique within index's referenced object store.
Each index also has a unique flag. When this flag is set to true, the index enforces that no two records in the index has the same key. If a record in the index's referenced object store is attempted to be inserted or modified such that evaluating the index's key path on the records new value yields a result which already exists in the index, then the attempted modification to the object store fails.
Each index also has a multiEntry flag. This flag affects how the index behaves when the result of evaluating
the index's key path yields an Array
. If the multiEntry flag is false, then
a single record whose key is an Array
is added to the index. If the multiEntry flag is
true, then the one record is added to the index for each item in the Array
. The key for each
record is the value of respective item in the Array
.
The IDBIndex
interface
provides access to the metadata of an index. Note however that multiple instances of those
interfaces representing the same index can exist.
3.1.7 Transaction
A transaction is used to interact with the data in a database. Whenever data is read or written to the database it is done by using a transaction.
All transactions are created through a connection, which is the transaction's connection. The transaction has a mode that determines which types of interactions can be performed upon that transaction. The mode is set when the transaction is created and remains fixed for the life of the transaction. The transaction also has a scope that determines the object stores with which the transaction may interact. Transactions have an active flag, which determines if new requests can be made against the transaction. Finally, transactions also contain a request list of requests which have been made against the transaction.
Each transaction has a fixed scope, determined when the transaction is created. A transaction's scope remains fixed for the lifetime of that transaction.
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 data mutation operations.
Transactions are expected to be short lived. This is encouraged by the automatic committing functionality described below. Authors can still cause transactions to run for a long time; however, this usage pattern is not generally recommended as it can lead to a bad user experience.
The lifetime of a transaction is as follows:
-
A transaction is created using
IDBDatabase.transaction
. The arguments passed determine the scope of the transaction and whether the transaction is read-only. When a transaction is created its active flag is initially set to true. -
The implementation MUST allow requests to be placed against the transaction
whenever the active flag is true. This is the case even if the transaction has not yet been
started. Until the transaction is started
the implementation MUST NOT execute these requests; however, the implementation MUST keep track of the
requests and their order. Requests may be placed against a transaction only while that transaction
is active. If an attempt is made to place a request against a transaction when that transaction is not
active, the implementation MUST reject the attempt by
throwing a
DOMException
of typeTransactionInactiveError
. -
Once an implementation is able to enforce the constraints defined for the transaction mode, defined below,
the implementation MUST queue up an operation to start the transaction asynchronously.
The timing for when this happens is affected by:
- The mode in which the transaction is opened.
- Which object stores are included in the scope of the transaction.
- Once the transaction has been started the implementation can start executing the requests placed against the transaction. Unless otherwise defined, requests MUST be executed in the order in which they were made against the transaction. Likewise, their results MUST be returned in the order the requests were placed against a specific transaction. There is no guarantee about the order that results from requests in different transactions are returned. Similarly, the transaction modes ensure that two requests placed against different transactions can execute in any order without affecting what resulting data is stored in the database.
- A transaction can be aborted at any time before it is finished, even if the transaction isn't currently active or hasn't yet started. When a transaction is aborted the implementation MUST undo (roll back) any changes that were made to the database during that transaction. This includes both changes to the contents of object stores as well as additions and removals of object stores and indexes.
-
A transaction can fail for reasons not tied to a particular
IDBRequest
. For example due to IO errors when committing the transaction, or due to running into a quota limit where the implementation can't tie exceeding the quota to a partcular request. In this case the implementation MUST run the steps for aborting a transaction using the transaction as transaction and the appropriate error type as error. For example if quota was exceeded thenQuotaExceededError
should be used as error, and if an IO error happened,UnknownError
should be used as error. - When a transaction can no longer become active, the implementation MUST attempt to commit it, as long as the transaction has not been aborted. This usually happens after all requests placed against the transaction have been executed and their returned results handled, and no new requests have been placed against the transaction. When a transaction is committed, the implementation MUST atomically write any changes to the database made by requests placed against the transaction. That is, either all of the changes MUST be written, or if an error occurs, such as a disk write error, the implementation MUST NOT write any of the changes to the database. If such an error occurs, the implementation MUST abort the transaction by following the steps for aborting a transaction, otherwise it MUST commit the transaction by following the steps for committing a transaction.
- When a transaction is committed or aborted, it is said to be finished. If a transaction can't be finished, for example due to the implementation crashing or the user taking some explicit action to cancel it, the implementation MUST abort the transaction.
Transactions are opened in one of three modes. The mode determines how concurrent access to object stores in the transaction are isolated.
enum IDBTransactionMode {
"readonly",
"readwrite",
"versionchange"
};
Enumeration description | |
---|---|
readonly |
A "readonly" transaction is only allowed
to read data. No modifications can be done by this type of transaction. This has the advantage
that several "readonly" transactions can run at the same time even if their scopes
are overlapping, i.e. if they are using the same object stores. This type of transaction can
be created any time once a database has been opened using the
IDBDatabase.transaction
method.
|
readwrite |
A "readwrite" transaction is allowed to read, modify and
delete data from existing object stores. However object stores and indexes can't be added or removed.
Multiple "readwrite" transactions can't run at the same time if their scopes are overlapping
since that would mean that they can modify each other's data in the middle of the transaction.
This type of transaction can be created any time once a database has been opened using the
IDBDatabase.transaction
method.
|
versionchange |
A "versionchange" transaction is similar to a "readwrite" transaction,
however it can additionally create and remove object stores and indexes. It is the only type of
transaction that can do so. This type of transaction can't be manually created, but instead is created
automatically when a upgradeneeded event is fired.
|
Any number of transactions opened in "readonly"
mode are allowed to run concurrently,
even if the transaction's scope overlap and include the same object stores.
As long as a "readonly"
transaction is running, the data that the implementation returns
through requests created with that transaction MUST remain
constant. That is, two requests to read the same piece of data MUST yield the same result
both for the case when data is found and the result is that data, and for the case when data
is not found and a lack of data is indicated.
There are a number of ways that an implementation ensures this. The implementation can prevent any
"readwrite"
transaction, whose scope overlaps the scope of the "readonly"
transaction, from
starting until the "readonly"
transaction finishes. Or the implementation can allow the "readonly"
transaction to see a snapshot of the contents of the object stores which is taken when
the "readonly"
transaction started.
Similarly, implementations MUST ensure that a "readwrite"
transaction is only affected by
changes to object stores that are made using the transaction itself. For example, the
implementation MUST ensure that another transaction does not modify the contents of
object stores in the "readwrite"
transaction's scope. The implementation
MUST also ensure that if the "readwrite"
transaction completes successfully, the
changes written to object stores using the transaction can be committed to the
database without merge conflicts. An implementation MUST NOT abort a transaction
due to merge conflicts.
If multiple "readwrite"
transactions are attempting to access the same object store (i.e.
if they have overlapping scope), the transaction that was
created first MUST be the transaction which gets access to the object store first. Due to
the requirements in the previous paragraph, this also means that it is the only transaction
which has access to the object store until the transaction is finished.
Any transaction
created after a
"readwrite"
transaction MUST see the changes
written by the "readwrite"
transaction. So if
a
"readwrite"
transaction, A, is created, and
later another transaction B, is created, and the two
transactions have overlapping
scopes, then B MUST see any changes
made to any object stores that
are part of that overlapping scope. Due to the
requirements in the previous paragraph, this also means
that the B transaction does not have access to any
object stores in that
overlapping scope until the A transaction
is finished.
Generally speaking, the above requirements mean that any
transaction which has an overlapping scope with a
"readwrite"
transaction and which was created
after that
"readwrite"
transaction, can't run in
parallel with that
"readwrite"
transaction.
A "versionchange"
transaction never run concurrently with other transactions.
When a database is opened with a version number higher than the current version, a new
"versionchange"
transaction is automatically created and made available through the
upgradeneeded
event. The upgradeneeded
event isn't fired, and thus the
"versionchange"
transaction isn't started, until all other connections to the same
database are closed. This ensures that all other transactions are finished.
As long as a "versionchange"
transaction
is running, attempts to open more connections to the same database are delayed,
and any attempts to use the same connection to start additional transactions will result in
an exception being thrown. Thus "versionchange"
transactions not only ensure that
no other transactions are running concurrently, but also ensure that no other transactions are queued
against the same database as long as the transaction is running.
"versionchange"
transaction is automatically created
when a database version number is provided that is greater than the current database version.
This transaction will be active inside the upgradeneeded
event handler,
allowing the creation of new object stores and indexes.
User agents MUST ensure a reasonable level of fairness across transactions to prevent
starvation. For example, if multiple "readonly"
transactions are started one after another
the implementation MUST NOT indefinitely prevent a pending "readwrite"
transaction from starting.
Each transaction object implement the IDBTransaction
interface.
3.1.8 Requests
Each reading and writing operation on a database is done using a request. Every request represents one read or write operation. Requests have a done flag which initially is false, and a source object. Every request also has a result and an error attribute, neither of which are accessible until the done flag is set to true.
Finally, requests have a request transaction. When a request is created, it is
always placed against a transaction using
the steps for asynchronously executing a request.
The steps set the request transaction to be that transaction.
The steps do not set the request transaction to be that request for the request returned from an
IDBFactory.open
call however.
That function create requests which have a null request transaction.
enum IDBRequestReadyState {
"pending",
"done"
};
Enumeration description | |
---|---|
pending | The done flag of the request is false. |
done | The done flag of the request is true. |
3.1.9 Key Range
Records can be retrieved from object stores and indexes using either keys or key ranges. A key range is a continuous interval over some data type used for keys.
A key range MAY be lower-bounded or upper-bounded (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 lower-bounded and upper-bounded. If a key range is neither lower-bounded nor upper-bounded it is said to be unbounded. A key range MAY be open (the key range does not include its endpoints) or closed (the key range includes its endpoints). A key range MAY consist of a single value.
The IDBKeyRange
interface defines a
key range.
interface IDBKeyRange {
readonly attribute any lower;
readonly attribute any upper;
readonly attribute boolean lowerOpen;
readonly attribute boolean upperOpen;
static IDBKeyRange
only (any value);
static IDBKeyRange
lowerBound (any lower, optional boolean open = false);
static IDBKeyRange
upperBound (any upper, optional boolean open = false);
static IDBKeyRange
bound (any lower, any upper, optional boolean lowerOpen = false, optional boolean upperOpen = false);
};
lower
of type any, readonly- This value is the lower-bound of the key range.
lowerOpen
of type boolean, readonly- Returns false if the lower-bound value is included in the key range. Returns true if the lower-bound value is excluded from the key range.
upper
of type any, readonly- This value is the upper-bound of the key range.
upperOpen
of type boolean, readonly- Returns false if the upper-bound value is included in the key range. Returns true if the upper-bound value is excluded from the key range.
bound
, static-
Creates and returns a new key range with lower set to
lower, lowerOpen set to lowerOpen,
upper set to upper and
upperOpen set to upperOpen.
If either the lower parameter or upper parameter is not valid key, or the lower key is greater than the upper key, or the lower key and upper key match and either of the bounds are open, the implementation MUST throw a
DOMException
of typeDataError
.Parameter Type Nullable Optional Description lower any
✘ ✘ The lower-bound value upper any
✘ ✘ The upper-bound value lowerOpen boolean = false
✘ ✔ Set to false if the lower-bound should be included in the key range. Set to true if the lower-bound value should be excluded from the key range. Defaults to false (lower-bound value is included). upperOpen boolean = false
✘ ✔ Set to false if the upper-bound should be included in the key range. Set to true if the upper-bound value should be excluded from the key range. Defaults to false (upper-bound value is included). Return type:IDBKeyRange
lowerBound
, static-
Creates and returns a new key range with lower set to
lower, lowerOpen set to open,
upper set to
undefined
and upperOpen set to true.If the value parameter is not a valid key, the implementation MUST throw a
DOMException
of typeDataError
.Parameter Type Nullable Optional Description lower any
✘ ✘ The lower bound value open boolean = false
✘ ✔ Set to false if the lower-bound should be included in the key range. Set to true if the lower-bound value should be excluded from the key range. Defaults to false (lower-bound value is included). Return type:IDBKeyRange
only
, static-
Creates and returns a new key range with both lower and
upper set to value and both
lowerOpen and upperOpen
set to false.
If the value parameter is not a valid key, the implementation MUST throw a
DOMException
of typeDataError
.Parameter Type Nullable Optional Description value any
✘ ✘ The only value Return type:IDBKeyRange
upperBound
, static-
Creates and returns a new key range with lower set to
undefined
, lowerOpen set to true, upper set to upper and upperOpen set to open.If the value parameter is not a valid key, the implementation MUST throw a
DOMException
of typeDataError
.Parameter Type Nullable Optional Description upper any
✘ ✘ The upper bound value open boolean = false
✘ ✔ Set to false if the upper-bound should be included in the key range. Set to true if the upper-bound value should be excluded from the key range. Defaults to false (upper-bound value is included). Return type:IDBKeyRange
A key is in a key range if both the following conditions are fulfilled:
3.1.10 Cursor
Cursors are a transient mechanism used to iterate over multiple records in a database. 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. The cursor has a source that indicates which index or object store is associated with the records over which the cursor is iterating. A cursor maintains a position over this series, which moves in a direction that is in either monotonically increasing or decreasing order of the record keys. Cursors also have a key and a value which represent the key and the value of the last iterated record. Cursors finally have a got value flag. When this flag is false, the cursor is either in the process of loading the next value or it has reached the end of its range, when it is true, it indicates that the cursor is currently holding a value and that it is ready to iterate to the next one.
There are four possible values for a cursor's direction. The direction of a cursor determines if the cursor initial position is at the start of its source or at its end. It also determines in which direction the cursor moves when iterated, and if it skips duplicated values when iterating indexes. The allowed values for a cursor's direction is as follows:
enum IDBCursorDirection {
"next",
"nextunique",
"prev",
"prevunique"
};
Enumeration description | |
---|---|
next | This direction causes the cursor to be opened at the start of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically increasing order of keys. |
nextunique | This direction causes the cursor to be opened at the start of the
source. When iterated, the cursor should not yield records with
the same key, but otherwise yield all records, in monotonically increasing order of keys. For every key
with duplicate values, only the first record is yielded. When the source is
an object store or a unique index, this direction has the exact same behavior as "next" . |
prev | This direction causes the cursor to be opened at the end of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically decreasing order of keys. |
prevunique | This direction causes the cursor to be opened at the end of the
source. When iterated, the cursor should not yield records with
the same key, but otherwise yield all records, in monotonically decreasing order of keys. For every key
with duplicate values, only the first record is yielded. When the source is
an object store or a unique index, this direction has the exact same behavior as "prev" . |
If the source of a cursor is an object store, the effective object store of the cursor is that object store and the effective key of the cursor is the cursor's position. If the source of a cursor is an index, the effective object store of the cursor is that index's referenced object store and the effective key is the cursor's object store position.
It is possible for the list of records which the cursor is iterating over to change before the full range of the cursor has been iterated. In order to handle this, cursors maintain their position not as an index, but rather as a key of the previously returned record. For a forward iterating cursor, the next time the cursor is asked to iterate to the next record it returns the record with the lowest key greater than the one previously returned. For a backwards iterating cursor, the situation is opposite and it returns the record with the highest key less than the one previously returned.
For cursors iterating indexes the situation is a little bit more complicated since multiple records can have the same key and are therefore also sorted by value. When iterating indexes the cursor also has an object store position, which indicates the value of the previously found record in the index. Both position and the object store position are used when finding the next appropriate record.
Cursor objects implement the IDBCursor
interfaces. There is only ever one
IDBCursor
instance representing
a given cursor. However there is no limit on how many cursors can be used at the
same time.
3.1.11 Exceptions
Each of the exceptions defined in the IndexedDB spec is a DOMException
with a specific type. [DOM4]
Existing DOM Level 4 exceptions will set their code to a legacy value; however, the new indexedDB type exceptions will have a code value of 0.
The message value is optional.
IndexedDB uses the following new DOMException
types with their various messages.
All of these new types will have a code value of 0
zero.
Type | Message (Optional) |
---|---|
UnknownError |
The operation failed for reasons unrelated to the database itself and not covered by any other errors. |
ConstraintError |
A mutation operation in the transaction failed because a constraint was not satisfied. For example, an object such as an object store or index already exists and a request attempted to create a new one. |
DataError |
Data provided to an operation does not meet requirements. |
TransactionInactiveError |
A request was placed against a transaction which is currently not active, or which is finished. |
ReadOnlyError |
The mutating operation was attempted in a "readonly" transaction. |
VersionError |
An attempt was made to open a database using a lower version than the existing version. |
IndexedDB reuses the following existing DOMException types from [DOM4]. These types will continue to return the codes and names as specified in DOM4; however, they will have the following messages when thrown from an IndexedDB API:
Type | Message (Optional) |
---|---|
NotFoundError |
The operation failed because the requested database object could not be found. For example, an object store did not exist but was being opened. |
InvalidStateError |
An operation was called on an object on which it is not allowed or at a time when it is not allowed. Also occurs if a request is made on a source object that has been deleted or removed. Use TransactionInactiveError or ReadOnlyError when possible, as they are more specific variations of InvalidStateError. |
InvalidAccessError |
An invalid operation was performed on an object. For example transaction creation attempt was made, but an empty scope was provided. |
AbortError |
A request was aborted, for example through a call to IDBTransaction.abort .
|
TimeoutError |
A lock for the transaction could not be obtained in a reasonable time. |
QuotaExceededError |
The operation failed because there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database. |
SyntaxError |
The keypath argument contains an invalid key path. |
DataCloneError |
The data being stored could not be cloned by the internal structured cloning algorithm. |
3.1.12 Options Object
Options objects are dictionary objects [WEBIDL]
which are used to supply optional parameters to some indexedDB functions like
createObjectStore
and
createIndex
. The attributes on the object
correspond to optional parameters on the function called.
The following WebIDL defines IDBObjectStoreParameters dictionary type.
dictionary IDBObjectStoreParameters {
(DOMString or sequence<DOMString>)? keyPath = null;
boolean autoIncrement = false;
};
autoIncrement
of type boolean, defaulting tofalse
keyPath
of type (DOMString or sequence<DOMString>), nullable, defaulting tonull
The following WebIDL defines IDBIndexParameters dictionary type.
dictionary IDBIndexParameters {
boolean unique = false;
boolean multiEntry = false;
};
multiEntry
of type boolean, defaulting tofalse
unique
of type boolean, defaulting tofalse
The following WebIDL defines IDBVersionChangeEventInit dictionary type.
dictionary IDBVersionChangeEventInit : EventInit {
unsigned long long oldVersion = 0;
unsigned long long? newVersion = null;
};
newVersion
of type unsigned long long, nullable, defaulting tonull
oldVersion
of type unsigned long long, defaulting to0
3.1.13 Key Generators
When a object store is created it can be specified to use a key generator. A key generator keeps an internal current number. The current number is always a positive integer. Whenever the key generator is used to generate a new key, the generator's current number is returned and then incremented to prepare for the next time a new key is needed. Implementations MUST use the following rules for generating numbers when a key generator is used.
- Every object store that uses key generators use a separate generator. I.e. interacting with one object store never affects the key generator of any other object store.
-
The current number of a key generator is always set to
1
when the object store for that key generator is first created. -
When a key generator is used to generate a new key for a object store, the
key generator's current number is used as the new key value and then the
key generator's current number is increased by
1
. -
When a record is stored and an key value is specified in the call to store the record, if the specified key value is a
Number
greater than or equal to the key generator's current number, then the key generator's current number is set to the smallest integer number greater than the explicit key. A key can be specified both for object stores which use in-line keys, by setting the property on the stored value which the object store's key path points to, and for object stores which use out-of-line keys, by passing a key argument to the call to store the record.Only specified keys values which are
Number
values affect the current number of the key generator.Date
s andArray
s which containNumber
s do not affect the current number of the key generator. Nor doDOMString
values which could be parsed as numbers. NegativeNumber
s do not affect the current number since they are always lower than the current number. -
Modifying a key generator's current number is considered part of a database operation.
This means that if the operation fails and the operation is reverted, the current number
is reverted to the value it had before the operation started. This applies both to modifications
that happen due to the current number getting increased by
1
when the key generator is used, and to modifications that happen due to a record being stored with a key value specified in the call to store the record. - Likewise, if a transaction is aborted, the current number of the key generator's for all object stores in the transaction's scope is reverted to the values they had before the transaction was started.
-
When the current number of a key generator reaches above the value
2^53
(9007199254740992
) any attempts to use the key generator to generate a new key will result in aConstraintError
. It is still possible to insert records into the object store by specifying an explicit key, however the only way to use a key generator again for the object store is to delete the object store and create a new one.NoteAs long as key generators are used in a normal fashion this will not be a problem. If you generate a new key 1000 times per second day and night, you won't run into this limit for over 285000 years.
-
The current number for a key generator never decreases, other than as a result of
database operations being reverted. Deleting a record from an object store
never affects the object store's key generator. Even clearing all records from an
object store, for example using the
clear()
function, does not affect the current number of the object store's key generator.
A practical result of this is that the first key generated for an object store is always 1
(unless a higher numeric key is inserted first) and the key generated for an object store is always a
positive integer higher than the highest numeric key in the store. The same key is never generated
twice for the same object store unless a transaction is rolled back.
3.2 APIs
The API methods return without blocking the calling thread.
All asynchronous operations immediately return an IDBRequest
instance.
This object does not initially contain any information about the result of the operation.
Once information becomes available, an event is fired on the request and the information becomes
available through the properties of the IDBRequest
instance.
3.2.1 The IDBRequest
Interface
The IDBRequest
interface provides means to access results of
asynchronous requests to databases and database
objects using event handler attributes [HTML5].
interface IDBRequest : EventTarget {
readonly attribute any result;
readonly attribute DOMError error;
readonly attribute (IDBObjectStore
or IDBIndex
or IDBCursor
)? source;
readonly attribute IDBTransaction
transaction;
readonly attribute IDBRequestReadyState
readyState;
attribute EventHandler onsuccess;
attribute EventHandler onerror;
};
error
of type DOMError, readonly-
When the done flag is true,
getting this property MUST return the error of the request. This is null when no error occurred.
When the done flag is false,
getting this property MUST throw a
DOMException
of typeInvalidStateError
. onerror
of type EventHandler,- The event handler for the
error
event. onsuccess
of type EventHandler,- The event handler for the
success
event. readyState
of typeIDBRequestReadyState
, readonly- When the done flag is false, returns
"pending"
, otherwise returns"done"
. result
of type any, readonly-
When the done flag is true,
getting this property MUST return the result of
the request. This is
undefined
when the request resulted in an error. When the done flag is false, getting this property MUST throw aDOMException
of typeInvalidStateError
. source
of type (IDBObjectStore or IDBIndex or IDBCursor), readonly , nullable-
Getting this property MUST return the source
for the request. Returns
null
when there is no source set. transaction
of typeIDBTransaction
, readonly-
Getting this property MUST return the transaction
for the request. This property can be null for certain requests, such as for request
returned from
IDBFactory.open
.
When a request is made, a new request is returned with its
done flag set to false.
If a request completes successfully, the
done flag is set to true, the
result
is set to the result of the request, and an event with type success
is fired
at the request.
If an error occurs while performing the operation, the
done flag is set to true, the
error attribute is set to a DOMError
type that matches the error,
and an event with type error
is fired at the request.
The open
and deleteDatabase
functions on
uses a separate interface for its requests in order to make use of the
IDBFactory
blocked
event and upgradeneeded
event easier.
interface IDBOpenDBRequest : IDBRequest
{
attribute EventHandler onblocked;
attribute EventHandler onupgradeneeded;
};
onblocked
of type EventHandler,- The event handler for the
blocked
event. onupgradeneeded
of type EventHandler,- The event handler for the
upgradeneeded
event.
The task source for these tasks is the database access task source.
3.2.2 Event interfaces
This specification fires events with the following custom interfaces:
[Constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict)]
interface IDBVersionChangeEvent : Event {
readonly attribute unsigned long long oldVersion;
readonly attribute unsigned long long? newVersion;
};
newVersion
of type unsigned long long, readonly , nullable- Returns the new version of the database.
See the steps for running a
"versionchange"
transaction. oldVersion
of type unsigned long long, readonly- Returns the old version of the database.
Events are constructed as defined in Constructing events, in [DOM4].
3.2.3 Opening a database
Window implements IDBEnvironment
;
All instances of the Window
type are defined to also implement the IDBEnvironment
interface.
WorkerUtils implements IDBEnvironment
;
All instances of the WorkerUtils
type are defined to also implement the IDBEnvironment
interface.
[NoInterfaceObject]
interface IDBEnvironment {
readonly attribute IDBFactory
indexedDB;
};
indexedDB
of typeIDBFactory
, readonly- This attribute provides applications a mechanism for accessing capabilities of indexed databases.
Every method for making asynchronous requests returns an
IDBRequest
object that communicates back to the requesting
application through events.
This design means that any number of requests can be active on any database
at a time.
interface IDBFactory {
IDBOpenDBRequest
open (DOMString name, [EnforceRange] optional unsigned long long version);
IDBOpenDBRequest
deleteDatabase (DOMString name);
short cmp (any first, any second);
};
cmp
-
If either first or second is not a valid key, the implementation MUST throw a
DOMException
of typeDataError
.Otherwise, this method MUST compare two keys. The method returns 1 if the first key is greater than the second, -1 if the first is less than the second, and 0 if the first is equal to the second.
Parameter Type Nullable Optional Description first any
✘ ✘ The first key to compare. second any
✘ ✘ The second key to compare. Return type:short
deleteDatabase
-
When invoked, this method MUST create a request and return it. The created request must implement the
IDBOpenDBRequest
interface and have its source set to null. The method then queues up an operation to run the steps for deleting a database. Let origin be the origin of theIDBEnvironment
used to access thisIDBFactory
and name be the name parameter passed to this function.If an error is returned from the steps above, the implementation MUST set the error attribute of the request to a
DOMError
whosename
is the same as the error returned, and dispatch an event at the request. The event must use theEvent
interface and have itstype
set to"error"
. The event does bubble but is not cancelable. The propagation path of the event is just the request.If the steps above are successful, the implementation MUST set the result of the request to
undefined
and fire a success event at the request. The event MUST implement theIDBVersionChangeEvent
interface and haveoldVersion
set to database version and have thenewVersion
property set to null.NoteThe firing of
"success"
or"error"
events do not follow the normal steps to fire a success event or fire an error event as there is no active transaction at the time when they fire.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name for the database Return type:IDBOpenDBRequest
open
-
If the value of version is
0
(zero), the implementation MUST throw aTypeError
.Otherwise, this method MUST create a request and return it. The created request MUST implement the
IDBOpenDBRequest
interface and have its source set tonull
. The method then queues up an operation to run the steps for opening a database. Let origin be the origin of theIDBEnvironment
used to access thisIDBFactory
, name and version be the name and version parameters passed to this function, and request be the newly created request. If the version parameter is not specified, let version beundefined
.NoteIf version is not specified and a database with that name already exists, a connection will be opened without changing the version. If version is not specified and no database with that name exists, a new database will be created with version equal to
1
.If an error is returned from the steps above, the implementation MUST set the error attribute of the request to a
DOMError
whosename
is the same as the error returned, and dispatch an event at the request. The event must use theEvent
interface and have itstype
set to"error"
. The event does bubble but is not cancelable. The propagation path of the event is just the request.If the steps above are successful, the implementation MUST set the
result
to the connection created by the steps above and dispatch an event at request. The event must use theEvent
interface and have itstype
set to"success"
. The event does not bubble and is not cancelable. The propagation path of the event is just the request. If the steps above resulted in a"versionchange"
transaction being run, then firing the"success"
event MUST be done after the“versionchange”
transaction completes.NoteThe last requirement is to ensure that in case another version upgrade is about to happen, the success event is fired on the connection first so that the page gets a chance to register a listener for the
versionchange
event.NoteThe firing of
"success"
or"error"
events do not follow the normal steps to fire a success event or fire an error event as there is no active transaction at the time when they fire.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name for the database version unsigned long long
✘ ✔ The version for the database Return type:IDBOpenDBRequest
3.2.4 Database
A database object can be used to manipulate the objects of that database. It is also the only way to obtain a transaction for that database.
interface IDBDatabase : EventTarget {
readonly attribute DOMString name;
readonly attribute unsigned long long version;
readonly attribute DOMStringList objectStoreNames;
IDBObjectStore
createObjectStore (DOMString name, optional IDBObjectStoreParameters
optionalParameters);
void deleteObjectStore (DOMString name);
IDBTransaction
transaction ((DOMString or sequence<DOMString>) storeNames, optional IDBTransactionMode
mode = "readonly");
void close ();
attribute EventHandler onabort;
attribute EventHandler onerror;
attribute EventHandler onversionchange;
};
name
of type DOMString, readonly-
On getting, this attribute MUST return the name
of the connected database. The attribute MUST
return this name even if the closePending flag is set on the connection.
In other words, the value of this attribute
stays constant for the lifetime of the
IDBDatabase
instance. objectStoreNames
of type DOMStringList, readonly-
On getting, this attribute MUST return a list of names of the
object stores currently in the
connected database. The list MUST
be sorted in ascending order using the algorithm defined by step 4
of section 11.8.5, The Abstract Relational Comparison Algorithm
of the ECMAScript Language Specification [ECMA-262].
Once the closePending flag is set on the connection, this
attribute MUST return a snapshot of the list of names of the object
stores taken at the time when the
close
method was called. Even if other connections are later used to change the set of object stores that exist in the database. In other words, the value of this attribute stays constant for the lifetime of theIDBDatabase
instance, except during a"versionchange"
transaction ifcreateObjectStore
ordeleteObjectStore
is called on thisIDBDatabase
instance itself. onabort
of type EventHandler,- The event handler for the
abort
event. onerror
of type EventHandler,- The event handler for the
error
event. onversionchange
of type EventHandler,- The event handler for the
versionchange
event. version
of type unsigned long long, readonly-
On getting, this attribute MUST return the version of the
database when this
IDBDatabase
instance was created. When aIDBDatabase
instance is created, this is always the number passed as the version argument passed to theopen
call used to create theIDBDatabase
instance. This value remains constant for the lifetime of theIDBDatabase
object. If the connection is closed, this attribute represents a snapshot of the version that the database had when the connection was closed. Even if another connection is later used to modify the version, that attribute on closed instances are not changed.
close
-
This method returns immediately and performs the steps for closing a database connection.
No parameters.Return type:
void
createObjectStore
-
This method creates and returns a new object store with the given name in the connected database. Note that this method must only be called from within a
"versionchange"
transaction.If this database is not running a
"versionchange"
transaction, or if this function is called on aIDBDatabase
object other than that transaction's connection, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the"versionchange"
transaction is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If an object store with the name name already exists in this database, the implementation MUST throw aDOMException
of typeConstraintError
.If the optionalParameters argument is specified and has a
keyPath
property which is notundefined
ornull
, then set keyPath to the value of this property. If keyPath is not a valid key path, the implementation MUST throw aDOMException
of typeSyntaxError
.If the optionalParameters argument is specified, and
autoIncrement
is set to true, then set autoIncrement to true. If autoIncrement is true and keyPath is an emptyDOMString
or anysequence<DOMString>
, the implementation MUST throw aDOMException
of typeInvalidAccessError
.Otherwise the implementation MUST create a new object store in the connected database and return an
IDBObjectStore
object representing it. Set the created object store's name to name. If autoIncrement is true, then the created object store uses a key generator. If keyPath is defined, set the created object store's key path to the value of keyPath.This method synchronously modifies the
IDBDatabase.objectStoreNames
property. However it only changes theIDBDatabase.objectStoreNames
property on theIDBDatabase
instance on which it was called.In some implementations it is possible for the implementation to run into problems after queuing up an operation to create the object store after the
createObjectStore
function has returned. For example in implementations where metadata about the newly created objectStore is inserted into the database asynchronously, or where the implementation might need to ask the user for permission for quota reasons. Such implementations MUST still create and return anIDBObjectStore
object. Instead, once the implementation realizes that creating the objectStore has failed, it MUST abort the transaction using the steps for aborting a transaction using the appropriate error as error parameter. For example if creating the object store failed due to quota reasons,QuotaError
MUST be used as error.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name of a new object store optionalParameters IDBObjectStoreParameters
✘ ✔ The options object whose attributes are optional parameters to this function. keyPath
specifies the key path of the new object store. If the attribute isnull
, no key path is specified and thus keys are out-of-line.autoIncrement
specifies whether the object store created should have a key generator.Return type:IDBObjectStore
deleteObjectStore
-
This method destroys the object store with the given name in the connected database. Note that this method must only be called from within a
"versionchange"
transaction.If this database is not running a
"versionchange"
transaction, or if this function is called on aIDBDatabase
object other than that transactions connection, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the"versionchange"
transaction is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
.If there is no object store with name name, compared in a case-sensitive manner, in the connected database, the implementation MUST throw a
DOMException
of typeNotFoundError
.Otherwise, this method destroys the object store with the name name in the connected database.
This method synchronously modifies the
IDBDatabase.objectStoreNames
property. However it only changes theIDBDatabase.objectStoreNames
property on theIDBDatabase
instance on which it was called.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name of an existing object store Return type:void
transaction
-
If the value for the mode parameter is not
"readonly"
or"readwrite"
, the implementation MUST throw aTypeError
. If this method is called onIDBDatabase
object for which a"versionchange"
transaction is still running, the implementation MUST throw aDOMException
of typeInvalidStateError
. If this method is called on aIDBDatabase
instance where the closePending flag is set, the implementation MUST throw aDOMException
of typeInvalidStateError
. If any of the names in storeNames do not exist in this database, the implementation MUST throw aDOMException
of typeNotFoundError
. If storeNames is an empty list, the implementation MUST throw aDOMException
of typeInvalidAccessError
.Otherwise, this method MUST execute the steps for creating a transaction in an asychronous fashion. The storeNames and mode arguments are forwarded to the algorithm as-is. The connection argument is set to the
IDBDatabase
that thetransaction()
method was called on.The method returns an
IDBTransaction
object representing the transaction returned by the steps above.Parameter Type Nullable Optional Description storeNames (DOMString or sequence<DOMString>)
✘ ✘ The names of object stores in the scope of the new transaction mode IDBTransactionMode
= "readonly"✘ ✔ The mode for isolating access to data inside the given object stores. If this parameter is not provided, the default access mode is "readonly"
.Return type:IDBTransaction
3.2.5 Object Store
Object store objects implement the following interface:interface IDBObjectStore {
readonly attribute DOMString name;
readonly attribute any keyPath;
readonly attribute DOMStringList indexNames;
readonly attribute IDBTransaction
transaction;
readonly attribute boolean autoIncrement;
IDBRequest
put (any value, optional any key);
IDBRequest
add (any value, optional any key);
IDBRequest
delete (any key);
IDBRequest
get (any key);
IDBRequest
clear ();
IDBRequest
openCursor (optional any range, optional IDBCursorDirection
direction = "next");
IDBIndex
createIndex (DOMString name, (DOMString or sequence<DOMString>) keyPath, optional IDBIndexParameters
optionalParameters);
IDBIndex
index (DOMString name);
void deleteIndex (DOMString indexName);
IDBRequest
count (optional any key);
};
autoIncrement
of type boolean, readonly- On getting, provides the auto increment flag for this object store.
indexNames
of type DOMStringList, readonly-
On getting, provide a list of the names of indexes on objects in this object store. The list MUST be sorted in ascending order using the algorithm defined by step 4 of section 11.8.5, The Abstract Relational Comparison Algorithm of the ECMAScript Language Specification [ECMA-262].
Once the closePending flag is set on the connection, this attribute MUST return a snapshot of the list of names of the indexes taken at the time when the
close
method was called. Even if other connections are later used to change the set of indexes that exist in the object store. In other words, the value of this attribute stays constant for the lifetime of theIDBObjectStore
instance, except during a"versionchange"
transaction ifcreateIndex
ordeleteIndex
is called on thisIDBObjectStore
instance itself. keyPath
of type any, readonly-
On getting, returns a value representing the key path of this object store, or
null
if none. If the key path is aDOMString
, the value will be aDOMString
equal to the key path. If the key path is asequence<DOMString>
, the value will be a newArray
, populated by appendingString
s equal to eachDOMString
in the sequence.The returned value is not the same instance that was used when the object store was created. However, if this attribute returns an object (specifically an
Array
), it returns the same object instance every time it is inspected. Changing the properties of the object has no effect on the object store. name
of type DOMString, readonly- On getting, provide the name of this object store.
transaction
of typeIDBTransaction
, readonly- On getting, returns the transaction this object store belongs to.
add
-
If the transaction this
IDBObjectStore
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If any of the following conditions are true, the implementation MUST throw aDOMException
of typeDataError
:- The object store uses in-line keys and the key parameter was provided.
- The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
- The object store uses in-line keys and the result of evaluating the object store's key path yields a value and that value is not a valid key.
- The object store uses in-line keys but no key generator and the result of evaluating the object store's key path does not yield a value.
- The key parameter was provided but does not contain a valid key.
Otherwise, this method creates a structured clone of the value parameter. If the structure clone algorithm throws an exception, that exception is rethrown. Otherwise, run the steps for asynchronously executing a request and return the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for storing a record into an object store as operation, using thisIDBObjectStore
as store, the created clone as value, the key parameter as key, and with the no-overwrite flag flag set to true.NoteTo determine if a transaction has completed successfully, listen to the transaction’s
complete
event rather than theIDBObjectStore.add
request’ssuccess
event, because the transaction may still fail after thesuccess
event fires.Parameter Type Nullable Optional Description value any
✘ ✘ The value to be stored in the record key any
✘ ✔ The key used to identify the record Return type:IDBRequest
clear
-
If the transaction this
IDBObjectStore
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for clearing an object store as operation, using thisIDBObjectStore
as store.No parameters.Return type:IDBRequest
count
-
If the transaction this
IDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the optional key parameter is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for iterating a cursor as operation, using the created cursor as cursor. If provided, use the key parameter as key, otherwise, use undefined as key. If the result of the algorithm is null return0
(zero) as the result for the request. Otherwise, use the return cursor to determine the total number of objects that share the key or key range and return that value as the result for the request.Parameter Type Nullable Optional Description key any
✘ ✔ Key identifying the record to be retrieved. This can also be an IDBKeyRange
.Return type:IDBRequest
createIndex
-
This method creates and returns a new index with the given name in the object store. Note that this method must only be called from within a
"versionchange"
transaction.If this object store's database is not running a
"versionchange"
transaction, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If an index with the name name already exists in this object store, the implementation MUST throw aDOMException
of typeConstraintError
. If keyPath is not a valid key path, the implementation MUST throw aDOMException
of typeSyntaxError
. If keyPath is asequence<DOMString>
and the multiEntry property in the optionalParameters is true, the implementation MUST throw aDOMException
of typeInvalidAccessError
.Otherwise, the implementation MUST create a new index in the object store and return an
IDBIndex
object representing it. Set the created index's name to name and key path to keyPath. Set the created index's unique and multiEntry flags to the values of the unique and multiEntry properties in the optionalParameters argument.The index that is requested to be created can contain constraints on the data allowed in the index's referenced object store, such as requiring uniqueness of the values referenced by the index's keyPath. If the referenced object store already contains data which violates these constraints, this MUST NOT cause the implementation of createIndex to throw an exception or affect what it returns. The implementation MUST still create and return an
IDBIndex
object. Instead the implementation must queue up an operation to abort the"versionchange"
transaction which was used for the createIndex call.This method synchronously modifies the
IDBObjectStore.indexNames
property. However it only changes theIDBObjectStore.indexNames
property on theIDBObjectStore
instance on which it was called. Although this method does not return aIDBRequest
object, the index creation itself is processed as an asynchronous request within the"versionchange"
transaction.In some implementations it is possible for the implementation to asynchronously run into problems creating the index after the createIndex function has returned. For example in implementations where metadata about the newly created index is queued up to be inserted into the database asynchronously, or where the implementation might need to ask the user for permission for quota reasons. Such implementations MUST still create and return an
IDBIndex
object. Instead, once the implementation realizes that creating the index has failed, it MUST abort the transaction using the steps for aborting a transaction using the appropriate error as error parameter. For example if creating the index failed due to quota reasons,QuotaError
MUST be used as error and if the index can't be created due to unique constraints,ConstraintError
MUST be used as error.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name of a new index keyPath (DOMString or sequence<DOMString>)
✘ ✘ The key path used by the new index. optionalParameters IDBIndexParameters
✘ ✔ The options object whose attributes are optional parameters to this function. unique
specifies whether the index's unique flag is set.multiEntry
specifies whether the index's multiEntry flag is set.Return type:IDBIndex
delete
-
If the transaction this
IDBObjectStore
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If key is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for deleting records from an object store as operation, using thisIDBObjectStore
as store and the key parameter as key.NoteUnlike other methods which take keys or key ranges, this method does not allow null to be passed as key. This is to reduce the risk that a small bug would clear a whole object store.
Parameter Type Nullable Optional Description key any
✘ ✘ Key identifying the record to be deleted Return type:IDBRequest
deleteIndex
-
This method destroys the index with the given name in the object store. Note that this method must only be called from within a
"versionchange"
transaction.If this object store's database is not running a
"versionchange"
transaction, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If there is no index with the name name, compared in a case-sensitive manner, in the object store, the implementation MUST throw aDOMException
of typeNotFoundError
.Otherwise, this method destroys the index with the name name in the object store.
This method synchronously modifies the
IDBObjectStore.indexNames
property. However it only changes theIDBObjectStore.indexNames
property on theIDBObjectStore
instance on which it was called. Although this method does not return aIDBRequest
object, the index destruction itself is processed as an asynchronous request within the"versionchange"
transaction.Parameter Type Nullable Optional Description indexName DOMString
✘ ✘ The name of an existing index Return type:void
get
-
If the transaction this
IDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If key is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for retrieving a value from an object store as operation, using thisIDBObjectStore
as store and the key parameter as key.NoteThis function produces the same result if a record with the given key doesn't exist as when a record exists, but has
undefined
as value. If you need to tell the two situations apart, you can useopenCursor
with the same key. This will return a cursor withundefined
as value if a record exists, or no cursor if no such record exists.Parameter Type Nullable Optional Description key any
✘ ✘ Key identifying the record to be retrieved. This can also be an IDBKeyRange
in which case the function retreives the first existing value in that range.Return type:IDBRequest
index
-
Returns an
IDBIndex
representing an index that is part of the object store. Every call to this function on the sameIDBObjectStore
instance and with the same name returns the sameIDBIndex
instance. However the returedIDBIndex
instance is specific to thisIDBObjectStore
instance. If this function is called on a differentIDBObjectStore
instance, a differentIDBIndex
instance is returned. A result of this is that differentIDBTransaction
instances use differentIDBIndex
instances to represent the same index.If there is no index with the given name, compared in a case-sensitive manner, in the object store, the implementation MUST throw a
DOMException
of typeNotFoundError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The name of an existing index Return type:IDBIndex
openCursor
-
If the transaction this
IDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If key is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method creates a cursor. The cursor MUST implement the
IDBCursorWithValue
interface.The newly created cursor MUST have an undefined position, a direction set to the value of the direction parameter, false as got value flag value, and undefined key and value. The source of the cursor is the
IDBObjectStore
this function was called on.If the range parameter is a key range then the cursor's range MUST be set to that range. Otherwise, if the range parameter is a valid key then the cursor's range is set to key range containing only that key value. If the range parameter is not specified, the cursor's key range is left as undefined.
This method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for iterating a cursor as operation, using the created cursor as cursor and with undefined as key.Parameter Type Nullable Optional Description range any
✘ ✔ The key range to use as the cursor's range direction IDBCursorDirection
= "next"✘ ✔ The cursor's required direction Return type:IDBRequest
put
-
If the transaction this
IDBObjectStore
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBObjectStore
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If any of the following conditions are true, the implementation MUST throw aDOMException
of typeDataError
:- The object store uses in-line keys and the key parameter was provided.
- The object store uses out-of-line keys and has no key generator and the key parameter was not provided.
- The object store uses in-line keys and the result of evaluating the object store's key path yields a value and that value is not a valid key.
- The object store uses in-line keys but no key generator and the result of evaluating the object store's key path does not yield a value.
- The key parameter was provided but does not contain a valid key.
Otherwise, this method creates a structured clone of the value parameter. If the structured clone algorithm throws an exception, that exception is rethrown. Otherwise, run the steps for asynchronously executing a request and return the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for storing a record into an object store as operation, using thisIDBObjectStore
as store, the created clone as value, the key parameter as key, and with the no-overwrite flag flag set to false.Parameter Type Nullable Optional Description value any
✘ ✘ The value to be stored in the record key any
✘ ✔ The key used to identify the record Return type:IDBRequest
3.2.6 Index
Index objects implement the following interface:
interface IDBIndex {
readonly attribute DOMString name;
readonly attribute IDBObjectStore
objectStore;
readonly attribute any keyPath;
readonly attribute boolean multiEntry;
readonly attribute boolean unique;
IDBRequest
openCursor (optional any range, optional IDBCursorDirection
direction = "next");
IDBRequest
openKeyCursor (optional any range, optional IDBCursorDirection
direction = "next");
IDBRequest
get (any key);
IDBRequest
getKey (any key);
IDBRequest
count (optional any key);
};
keyPath
of type any, readonly-
On getting, returns a value representing the key path of this index. If the key path is a
DOMString
, the value will be aDOMString
equal to the key path. If the key path is asequence<DOMString>
, the value will be a newArray
, populated by appendingString
s equal to eachDOMString
in the sequence.The returned value is not the same instance that was used when the index was created. However, if this attribute returns an object (specifically an
Array
), it returns the same object instance every time it is inspected. Changing the properties of the object has no effect on the index. multiEntry
of type boolean, readonly- On getting, provide the multiEntry flag of this index.
name
of type DOMString, readonly- On getting, provide the name of this index.
objectStore
of typeIDBObjectStore
, readonly-
On getting, returns a reference to the
IDBObjectStore
instance for the referenced object store in thisIDBIndex
's transaction. This MUST return the sameIDBObjectStore
instance as was used to get a reference to thisIDBIndex
. unique
of type boolean, readonly- On getting, provide the unique flag of this index.
count
-
If the transaction this
IDBIndex
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the index or the index's object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the optional key parameter is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBIndex
as source and the steps for iterating a cursor as operation, using the created cursor as cursor. If provided, use the key parameter as key, otherwise, use undefined as key. If the result of the algorithm is null return0
(zero) as the result for the request. Otherwise, use the return cursor to determine the total number of objects that share the key or key range and return that value as the result for the request.Parameter Type Nullable Optional Description key any
✘ ✔ Key identifying the record to be retrieved. This can also be an IDBKeyRange
.Return type:IDBRequest
get
-
If the transaction this
IDBIndex
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the index or the index's object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the key parameter is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for retrieving a referenced value from an index as operation, using thisIDBIndex
as index and the key parameter as key.NoteThis function produces the same result if a record with the given key doesn't exist as when a record exists, but has
undefined
as value. If you need to tell the two situations apart, you can useopenCursor
with the same key. This will return a cursor withundefined
as value if a record exists, or no cursor if no such record exists.Parameter Type Nullable Optional Description key any
✘ ✘ Key identifying the record to be retrieved. This can also be an IDBKeyRange
in which case the function retreives the first existing value in that range.Return type:IDBRequest
getKey
-
Gets the key of the record from the referenced object store entry.
If the transaction this
IDBIndex
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the index or the index's object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the key parameter is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for retrieving a value from an index as operation, using thisIDBIndex
as index and the key parameter as key.Parameter Type Nullable Optional Description key any
✘ ✘ Key identifying the record to be retrieved. This can also be an IDBKeyRange
in which case the function retreives the first existing value in that range.Return type:IDBRequest
openCursor
-
If the transaction this
IDBIndex
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the index or the index's object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the range parameter is specified but is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method creates a cursor. The cursor MUST implement the
IDBCursorWithValue
interface.The newly created cursor MUST have an undefined position, a direction set to the value of the direction parameter, false as got value flag value, and undefined key and value. The source of the cursor is the
IDBIndex
this function was called on.If the range parameter is a key range then the cursor's range is set to that range. Otherwise, if the range parameter is a valid key then the cursor's range is set to key range containing only that key value. If the range parameter is not specified, the cursor's key range is left as undefined.
This method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBIndex
as source and the steps for iterating a cursor as operation, using the created cursor as cursor and with undefined as keyParameter Type Nullable Optional Description range any
✘ ✔ The key range to use as the cursor's range direction IDBCursorDirection
= "next"✘ ✔ The cursor's required direction Return type:IDBRequest
openKeyCursor
-
If the transaction this
IDBIndex
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the index or the index's object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the range parameter is specified but is not a valid key or a key range, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method creates a cursor. The cursor MUST implement the
IDBCursor
interface, but MUST NOT implement theIDBCursorWithValue
interface.The newly created cursor MUST have an undefined position, a direction set to the value of the direction parameter, false as got value flag value, and undefined key and value. The source of the cursor is the
IDBIndex
this function was called on.If the range parameter is a key range then the cursor's range is set to that range. Otherwise, if the range parameter is a valid key then the cursor's range is set to key range containing only that key value. If the range parameter is not specified, the cursor's key range is left as undefined.
This method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBObjectStore
as source and the steps for iterating a cursor as operation, using the created cursor as cursor and with undefined as keyParameter Type Nullable Optional Description range any
✘ ✔ The key range to use as the cursor's range direction IDBCursorDirection
= "next"✘ ✔ The cursor's required direction Return type:IDBRequest
3.2.7 Cursor
Cursor objects implement the following interface:
interface IDBCursor {
readonly attribute (IDBObjectStore
or IDBIndex
) source;
readonly attribute IDBCursorDirection
direction;
readonly attribute any key;
readonly attribute any primaryKey;
IDBRequest
update (any value);
void advance ([EnforceRange] unsigned long count);
void continue (optional any key);
IDBRequest
delete ();
};
direction
of typeIDBCursorDirection
, readonly- On getting, provide the traversal direction of the cursor.
key
of type any, readonly- Returns the cursor's current key.
Note that if this property returns an object (specifically an
Array
), it returns the same object instance every time it is inspected, until the cursor's key is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database. primaryKey
of type any, readonly- Returns the cursor's current effective key.
Note that if this property returns an object (specifically an
Array
), it returns the same object instance every time it is inspected, until the cursor's effective key is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database. source
of type (IDBObjectStore or IDBIndex), readonly-
On getting, returns the
IDBObjectStore
orIDBIndex
which this cursor is iterating. This attribute never returns null or throws an exception, even if the cursor is currently being iterated, has iterated past its end, or its transaction is not active.
advance
-
If the value for count is
0
(zero), the implementation MUST throw aTypeError
. If the transaction thisIDBCursor
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the cursor's source or effective object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If this cursor's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, the implementation MUST throw aDOMException
of typeInvalidStateError
.Otherwise, this method runs the steps for asynchronously executing a request. However, the steps are slightly modified such that instead of creating a new IDBRequest, it reuses the request originally created when this cursor was created. The done flag on the request is set to false before the request is returned. The steps are run with the cursor's source as source. The operation runs the steps for iterating a cursor count number of times with null as key and this cursor as cursor.
Before this method returns, unless an exception was thrown, it sets the got value flag on the cursor to false.
NoteCalling this method more than once before new cursor data has been loaded is not allowed. For example, calling
advance()
twice from the same onsuccess handler results in anDOMException
of typeInvalidStateError
being thrown on the second call because the cursor's got value has been set to false.Parameter Type Nullable Optional Description count unsigned long
✘ ✘ The number of advances forward the cursor should make. Return type:void
continue
-
If the transaction this
IDBCursor
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the cursor's source or effective object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If this cursor's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the key parameter is specified and fulfills any of these conditions, the implementation MUST throw aDOMException
of typeDataError
:- The parameter is not a valid key.
-
The parameter is less than or equal to this cursor's position
and this cursor's direction is
"next"
or"nextunique"
. -
The parameter is greater than or equal to this cursor's position
and this cursor's direction is
"prev"
or"prevunique"
.
Otherwise, this method runs the steps for asynchronously executing a request. However, the steps are slightly modified such that instead of creating a new IDBRequest, it reuses the request originally created when this cursor was created. The done flag on the request is set to false before the request is returned. The steps are run with the cursor's source as source and the steps for iterating a cursor as operation, using this cursor as cursor and the key parameter as key.
Before this method returns, unless an exception was thrown, it sets the got value flag on the cursor to false.
NoteCalling this method more than once before new cursor data has been loaded is not allowed. For example, calling
continue()
twice from the same onsuccess handler results in aDOMException
of typeInvalidStateError
being thrown on the second call because the cursor's got value has been set to false.Parameter Type Nullable Optional Description key any
✘ ✔ The next key to position this cursor at Return type:void
delete
-
If the transaction this
IDBCursor
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBCursor
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the cursor's source or effective object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If this cursor's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, or if this cursor does not implement theIDBCursorWithValue
interface, the implementation MUST throw aDOMException
of typeInvalidStateError
.Otherwise, this method runs the steps for asynchronously executing a request and returns the
IDBRequest
created by these steps. The steps are run with thisIDBCursor
as source and the steps for deleting records from an object store as operation, using this cursor's effective object store and effective key as store and key respectively.No parameters.Return type:IDBRequest
update
-
If the transaction this
IDBCursor
belongs to has its mode set to"readonly"
, the implementation MUST throw aDOMException
of typeReadOnlyError
. If the transaction thisIDBCursor
belongs to is not active, the implementation MUST throw aDOMException
of typeTransactionInactiveError
. If the cursor's source or effective object store has been deleted, the implementation MUST throw aDOMException
of typeInvalidStateError
. If this cursor's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, or if this cursor does not implement theIDBCursorWithValue
interface, the implementation MUST throw aDOMException
of typeInvalidStateError
. If the effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key, the implementation MUST throw aDOMException
of typeDataError
.Otherwise, this method creates a structured clone of the value parameter. If the structured clone algorithm throws an exception, that exception is rethrown. Otherwise, run the steps for asynchronously executing a request and return the
IDBRequest
created by these steps. The steps are run with thisIDBCursor
as source and the steps for storing a record into an object store as operation, using this cursor's effective object store as store, the created clone as value, this cursor's effective key as key, and with the no-overwrite flag flag set to false.NoteA result of running the steps for storing a record into an object store is that if the record has been deleted since the cursor moved to it, a new record will be created.
Parameter Type Nullable Optional Description value any
✘ ✘ The new value to store at the current position. Return type:IDBRequest
interface IDBCursorWithValue : IDBCursor
{
readonly attribute any value;
};
value
of type any, readonly- Returns the cursor's current value. Note that if this property returns an object, it returns the same object instance every time it is inspected, until the cursor's value is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database.
3.2.8 Transaction
Transaction objects implement the following interface:
interface IDBTransaction : EventTarget {
readonly attribute IDBTransactionMode
mode;
readonly attribute IDBDatabase
db;
readonly attribute DOMError error;
IDBObjectStore
objectStore (DOMString name);
void abort ();
attribute EventHandler onabort;
attribute EventHandler oncomplete;
attribute EventHandler onerror;
};
db
of typeIDBDatabase
, readonly- The database connection of which this transaction is a part
error
of type DOMError, readonly-
If this transaction is not finished, is finished but was successfully
committed, or was aborted due to a call to the
abort
function, this property returnsnull
. If this transaction was aborted due to a failed request, this property returns the sameDOMError
as the request which caused this transaction to be aborted. If this transaction was aborted due to an error when committing the transaction, and not due to a failed request, this property returns aDOMError
which contains the reason for the transaction failure (e.g.QuotaExceededError
orUnknownError
). mode
of typeIDBTransactionMode
, readonly- On getting, provide the mode for isolating access to data inside the object stores that are in the scope of the transaction.
onabort
of type EventHandler,- The event handler for the
abort
event. oncomplete
of type EventHandler,- The event handler for the
complete
event.NoteTo determine if a transaction has completed successfully, listen to the transaction’s
complete
event rather than thesuccess
event of a particular request, because the transaction may still fail after thesuccess
event fires. onerror
of type EventHandler,- The event handler for the
error
event.
abort
-
If this transaction is finished, the implementation MUST throw a
DOMException
of typeInvalidStateError
.Otherwise, this method sets the transaction's active flag to false and aborts the transaction by running the steps for aborting a transaction with the error parameter set to
null
.No parameters.Return type:void
objectStore
-
Returns an
IDBObjectStore
representing an object store that is part of the scope of this transaction. Every call to this function on the sameIDBTransaction
instance and with the same name returns the sameIDBObjectStore
instance. However the returnedIDBObjectStore
instance is specific to thisIDBTransaction
. If this function is called on a differentIDBTransaction
, a differentIDBObjectStore
instance is returned.If the requested object store is not in this transaction's scope, the implementation MUST throw a
DOMException
of typeNotFoundError
. If the transaction has finished, the implementation MUST throw aDOMException
of typeInvalidStateError
.Parameter Type Nullable Optional Description name DOMString
✘ ✘ The requested object store Return type:IDBObjectStore
3.3 Algorithms
3.3.1 Opening a database
The steps for opening a database are defined in the following steps. The algorithm in these steps takes four arguments: the origin which requested the database to be opened, a database name, a database version, and a request.
- If these steps fail for any reason, return an error with the appropriate type and abort this algorithm.
- If there is already a database with the given name from the origin origin, then let db be that database.
-
If db was found in previous step, wait until the following conditions are all fulfilled:
-
No already existing connections to db, have
non-finished
"versionchange"
transaction. - If db has its delete pending flag set, wait until db has been deleted.
NoteIf several connections with the same origin and name are waiting due to the above conditions, and those connections have a higher version than the database's current version, then once any of those connections can proceed to the next step in this algorithm it will immediately start a
"versionchange"
transaction. This prevents the other connections from proceeding until that"versionchange"
transaction is finished. -
No already existing connections to db, have
non-finished
-
If no database with the given name from the origin origin was found, or if it was
deleted during the previous step, then create a database with name name,
with
0
as version, and with no object stores. Let db be the new database. -
If version is
undefined
, then let version be1
if db was created in the previous step, or the current version of db otherwise. -
If the version of db is higher than version, abort these steps and return
a
DOMError
of type VersionError. - Create a new connection to db and let connection represent it.
-
If the version of db is lower than version, then run the
steps for running a
"versionchange"
transaction using connection, version and request. -
If the previous step resulted in an error, then return that error and abort these steps.
If the
"versionchange"
transaction in the previous step was aborted, or if connection is closed, return aDOMError
of type AbortError and abort these steps. In either of these cases, ensure that connection is closed by running the steps for closing a database connection before these steps are aborted. - Return connection.
3.3.2 Transaction Creation steps
When the user agent is to create a transaction it MUST run the following steps. This algorithm takes three arguments: a connection, a mode, and the list storeNames naming the object stores to be included in the scope of the transaction.
-
If storeNames is of type
sequence<DOMString>
then let scope be the set of unique strings in the sequence. Otherwise, storeNames must be aDOMString
; let scope be a set containing one string equal to storeNames. If any of the strings in scope identifies an object store which doesn't exist, throw aDOMException
of typeNotFoundError
. If scope is an empty set throw aDOMException
of typeInvalidAccessError
. -
If the closePending flag is set on connection then
throw a
DOMException
of typeInvalidStateError
. - Create a transaction using connection as connection, mode as mode, and the object stores identified in scope as scope.
- Return the created transaction and queue up the remaining steps. When control is returned to the event loop, the implementation MUST set the active flag to false.
- Wait until the transaction can be started according to the transaction lifetime rules.
3.3.3 Steps for committing a transaction
When taking the steps for committing a transaction the implementation MUST execute the following algorithm. This algorithm takes one argument, the transaction to commit.
- All the changes made to the database by the transaction are written to the database.
-
If an error occurs while writing the changes to the database, abort the transaction by following
the steps for aborting a transaction with the transaction parameter set to transaction
and the error parameter set to a value appropriate for the error, for example
QuotaExceededError
orUnknownError
. -
Queue up an operation to dispatch an event at transaction.
The event must use the
Event
interface and have itstype
set to"complete"
. The event does not bubble and is not cancelable. The propagation path for the event is transaction's connection and then transaction.NoteEven if an exception is thrown from one of the event handlers of this event, the transaction is still committed since writing the database changes happens before the event takes places. Only after the transaction has been successfully written is the
"complete"
event fired.
3.3.4 Steps for aborting a transaction
When taking the steps for aborting a transaction the implementation MUST execute the following algorithm. This algorithm takes two arguments: the transaction to abort, and an error name.
-
All the changes made to the database by the transaction are reverted. For
"versionchange"
transactions this includes changes to the set of object stores and indexes, as well as the change to the version. Also run the steps for aborting a"versionchange"
transaction which reverts changes to allIDBDatabase
andIDBObjectStore
instances. -
Unless error was set to
null
, create aDOMError
object and set itsname
to error. Set transaction'serror
property to this newly createdDOMError
. -
If the transaction's request list contain any requests whose done flag
is still false, abort the steps for asynchronously executing a request for each such request and queue
a task to perform the following steps:
-
Set the done flag on the request to true, set
result of the request to
undefined
and set the request's error attribute to aDOMError
with a type of AbortError. -
Dispatch an event at request. The event must use
the
Event
interface and have itstype
set to"error"
. The event bubbles and is cancelable. The propagation path for the event is transaction's connection, then transaction and finally the request. There is no default action for the event.
NoteThis does not always result in any
error
events being fired. For example if a transaction is aborted due to an error while committing the transaction, or if it was the last remaining request that failed. -
Set the done flag on the request to true, set
result of the request to
-
Queue up an operation to dispatch an event at transaction.
The event must use the
Event
interface and have itstype
set to"abort"
. The event does bubble but is not cancelable. The propagation path for the event is transaction's connection and then transaction.
3.3.5 Steps for asynchronously executing a request
When taking the steps for asynchronously executing a request the implementation MUST run the following algorithm. The algorithm takes a source object and an operation to perform on a database.
These steps can be aborted at any point if the transaction the created request belongs to is aborted using the steps for aborting a transaction
- Let transaction be the transaction associated with source.
-
If transaction is not active
throw a
DOMException
of typeTransactionInactiveError
. -
Create an
IDBRequest
object and set request to this object. Set request's source to source and add request to the end of the list of requests in transaction. Return this object and queue up the execution of the remaining steps in this algorithm.NoteCursors override this step to reuse an existing
IDBRequest
. However they still put theIDBRequest
at the end of the list of requests in transaction. - Wait until all previously added requests in transaction have their done flag set to true.
- Perform operation.
-
If performing operation succeeded then set the done flag
on the request to true, set result of the request
to the result of the request and set the error attribute of the request to
undefined
. Finally fire a success event at request. -
If performing operation failed then revert all changes made by operation,
set the done flag on the request to true,
set result of the request
to
undefined
and set the error attribute on the request to aDOMError
with the same error type as the operation that failed. Finally fire an error event at request.NoteThis only reverts the changes done by this request, not any other changes made by the transaction.
3.3.6 Steps for extracting a key from a value using a key path
When taking the steps for extracting a key from a value using a key path, the implementation MUST run the following algorithm. The algorithm takes a key path named keyPath and a value named value and in some cases returns a key which may or may not be a valid key.
-
If keyPath is a
sequence<DOMString>
, then let result be newly constructed emptyArray
. For each item in the keyPath sequence, perform the following substeps:- Evaluate the steps for extracting a key from a value using a key path using the item from the keyPath sequence as keyPath and value as value.
- If the result of the previous step was not a valid key, then abort the overall algorithm and no value is returned.
- Add the result of the first sub-step to end of the result array.
NoteThis will only ever "recurse" one level since key path sequences can't ever be nested.
- If keyPath is the empty string, return value and skip the remaining steps.
- Let remainingKeyPath be keyPath and object be value.
- If remainingKeyPath has a period in it, assign identifier to be everything before the first period and assign remainingKeyPath to be everything after that first period. Otherwise, assign identifier to be remainingKeyPath and assign remainingKeyPath to be null.
- If object does not have an property named identifier, then skip the rest of these steps and no value is returned.
- Assign object to be the value of the property named identifier on object.
- If remainingKeyPath is not null, go to step 4.
- Return object.
3.3.7 "versionchange"
transaction steps
The steps for running a "versionchange"
transaction are
as follows. This algorithm takes three arguments:
a connection object which is used to update the database,
a new version to be set for the database,
and a request.
-
Let openDatabases be the set of all
IDBDatabase
objects, except connection, connected to the same database as connection. -
Fire a
versionchange
event at each object in openDatabases that is open. The event MUST NOT be fired on objects which has theclosePending
flag set. The event MUST use theIDBVersionChangeEvent
interface and have theoldVersion
property set to db's version and have thenewVersion
property set to version. This event MUST NOT bubble or be cancelable. The propagation path for the event is just theIDBDatabase
object itself.NoteFiring this event might cause one or more of the other objects in openDatabases to be closed, in which case the
versionchange
event MUST NOT be fired at those objects if that hasn't yet been done. -
If any of the connections in openDatabases are still not closed, queue up a
blocked
event for the request. The event MUST use theIDBVersionChangeEvent
interface and have theoldVersion
property set to db's version and have thenewVersion
property set to version. This event MUST NOT bubble or be cancelable. The propagation path for the event is just request. - Wait until all objects in openDatabases are closed and all of their transactions are finished.
-
Create a new transaction with mode set to
"versionchange"
and connection used as connection. The scope of the transaction includes every object store in connection. Set its active flag to false. Let transaction represent this transaction. - Start transaction. Note that until this transaction is finished, no other connections can be opened to the same database.
- Let old version be database's version.
- Set the version of database to version. This change is considered part of the transaction, and so if the transaction is aborted, this change is reverted.
-
Schedule a task to run the following steps:
-
Set the
result
property of request to connection. -
Set the
transaction
property of request to transaction. -
Fire a
upgradeneeded
event targeted at request. The event MUST use theIDBVersionChangeEvent
interface and have theoldVersion
property set to old version and have thenewVersion
property set to version. The done flag on the request is set to true. -
If an exception was propagated out from any event handler while dispatching the event in the previous step, abort
the transaction by following the steps for aborting a transaction with the error property set to
AbortError
. -
If for any reason the
"versionchange"
transaction is aborted theIDBDatabase
instance which represents connection will remain unchanged. I.e., itsname
,version
, andobjectStoreNames
properties will remain the value they were before the transaction was aborted. The default attributes for theIDBDatabase
are:Attribute Value name
the name provided to IDBFactory.open
version
0
(zero)objectStoresNames
null
-
Set the
- Execute the transaction.
-
When the transaction is finished,
immediately set request's
transaction
property tonull
. This MUST be done in the same task as the task firing thecomplete
orabort
event, but after those events has been fired.
3.3.8 Steps for aborting a "versionchange"
transaction
The steps for aborting a "versionchange"
transaction are as follows.
-
IDBDatabase.name
is not modified at all. Even if the transaction is used to create a new database, and thus there is no on-disk database,IDBDatabase.name
remains as it was. -
Revert
IDBDatabase.version
to the version the on-disk database had before the transaction was started. If the"versionchange"
transaction was started because the database was newly created, revertIDBDatabase.version
to version 0; if the transaction was started in response to a version upgrade, revert to the version it had before the transaction was started. Note that the only time that theIDBDatabase.version
property ever changes value is during a"versionchange"
transaction. -
Revert
IDBDatabase.objectStoreNames
to the list of names that it had before the transaction was started. If the"versionchange"
transaction was started because the database was newly created, revert it to an empty list. If the"versionchange"
transaction was started in response to a version upgrade, revert to the list of object store names it had before the transaction was started. -
Revert
IDBObjectStore.indexNames
(for each object store) to the list of names thatIDBObjectStore.indexNames
had before the transaction was started. For any object store that was created by the transaction, revert the list to an empty list. For any object store that existed before the transaction was started, revert to the list of index names it had before the transaction was started. For any object store that was deleted during the transaction, revert the list of names to the list it had before the transaction was started, potentially a non-empty list.NoteAlthough you cannot access object stores by using the
IDBTransaction.objectStore
function after a transaction is aborted, the page may still have references to object store instances. In that caseIDBObjectStore.indexNames
can still be accessed.
3.3.9 Database closing steps
The steps for closing a database connection are as follows. These steps take one argument, a connection object.
-
Set the internal
closePending
flag of connection to true. - Wait for all transactions created using connection to complete. Once they are complete, connection is closed.
Once the closePending
flag has ben set to true no new transactions can be
created using connection. All functions that
create transactions first check the closePending flag first and
throw an exception if it is true.
Once the connection is closed, this can unblock the steps for running a "versionchange"
transaction, and the steps for deleting a database, which both
wait for connections to a given database to be closed
before continuing.
3.3.10 Database deletion steps
The steps for deleting a database are as follows. The algorithm in these steps takes three arguments: the origin that requested the database to be deleted, a database name, and a request.
- If there is already a database with the given name from the origin origin, then let db be that database.
- If no database was found, then these steps are considered successful. Abort these steps.
- Set db's delete pending flag to true.
-
Let openDatabases be the set of all
IDBDatabase
objects connected to db. -
Fire a
versionchange
event at each object in openDatabases that is open. The event MUST NOT be fired on objects which has theclosePending
flag set. The event MUST use theIDBVersionChangeEvent
interface and have theoldVersion
property set to db's version and have thenewVersion
property set tonull
. This event MUST NOT bubble or be cancelable.NoteFiring this event might cause one or more of the other objects in openDatabases to be closed, in which case the
versionchange
event MUST NOT be fired at those objects if that hasn't yet been done. -
If any of the connections in openDatabases are still not closed, and request was provided, fire a
blocked
event at request. The event MUST use theIDBVersionChangeEvent
interface and have theoldVersion
property set to db's version and have thenewVersion
property set tonull
. This event MUST NOT bubble or be cancelable. - Wait until all objects in openDatabases are closed and all of their transactions are finished.
- Delete db.
3.3.11 Fire a success event
To fire a success event at a request, the implementation MUST run the following steps:
- Set transaction to the transaction associated with the source.
- Set the active flag of transaction to true.
-
Dispatch an event at request. The event must use
the
Event
interface and have itstype
set to"success"
. The event does not bubble and is not cancelable. The propagation path for the event is the transaction's connection, then transaction and finally request. - Set the active flag of transaction to false.
-
If an exception was propagated out from any event handler while dispatching the event in step 3,
abort the transaction by following the steps for aborting a transaction using transaction as
transaction parameter, and
AbortError
as error.
3.3.12 Fire an error event
To fire an error event at a request, the implementation MUST run the following steps:
- Set transaction to the transaction associated with the source.
- Set the active flag of transaction to true.
-
Dispatch an event at request. The event must use
the
Event
interface and have itstype
set to"error"
. The event bubbles and is cancelable. The propagation path for the event is the transaction's connection, then transaction and finally request. The event's default action is to abort the transaction by running the steps for aborting a transaction using transaction as transaction and thename
of request'serror
property as error. However the default action is not taken if any of the event handlers threw an exception. - Set the active flag of transaction to false.
-
If an exception was propagated out from any event handler while dispatching the event in step 3,
abort the transaction by following the steps for aborting a transaction using transaction as
transaction parameter, and
AbortError
as error. This is done even if the error event is not canceled.NoteThis means that if an error event is fired and any of the event handlers throw an exception, the
error
property on the transaction is set to anAbortError
rather than whateverDOMError
theerror
property on the request was set to. Even ifpreventDefault
is never called.
3.3.13 Steps to assign a key to a value using a key path
The steps to assign a key to a value using a key path are as follows:
- Let remainingKeyPath be keyPath and object be value.
-
If object is not an
Object
object or anArray
object (see structured clone algorithm [HTML5]), then throw aDOMException
of typeDataError
. - If remainingKeyPath has a period in it, assign identifier to be everything before the first period, and assign remainingKeyPath to be everything after that first period. Otherwise, go to step 7.
-
If object does not have a property named identifier, then set a property named identifier
on object with the value of a new
Object
. - Assign object to be the value of the property named identifier on object.
- Go to step 2.
-
Note
The steps leading here ensure that remainingKeyPath is a single identifier name (that is, a string without periods) by this step. The steps also ensure that object is an
Object
or anArray
, and not aDate
,RegExp
,Blob
, or other nonsupported type. - Let identifier be remainingKeyPath.
- Set a property named identifier on object with the value key.
The intent is that these steps are only executed if evaluating the key path did not yield a value.
In other words, before you run these steps, first evaluate the key path against value,
and only if that does not yield a value (where undefined
does count as a value) do you generate a key and
use these steps to modify value to contain the generated key.
The key path used here is always a DOMString
and never an sequence<DOMString>
since it is not
possible to create a object store whose multiEntry flag is true and whose
key path is an sequence<DOMString>
.
3.4 Database operations
This section describes various operations done on the data in object stores and indexes in a database. These operations are run by the steps for asynchronously executing a request.
3.4.1 Object Store Storage Operation
The steps for storing a record into an object store are as follows. The algorithm run by these steps takes four arguments: an object store store, a value, an optional key, and a no-overwrite flag.
- If store does use in-line keys and evaluting store's key path on value does yield a value, then set key to that result.
-
If store uses a key generator and key is undefined, set
key to the next generated key. If store also uses in-line keys,
then set the property in value pointed to by store's
key path to the new value for key, as shown in the
steps to assign a key to a value using a key path. If the current number of a key generator
reaches above the value
2^53
(9007199254740992
) any attempt to use the key generator to generate a new key fails with aConstraintError
. -
If store uses a key generator, this key generator was not used to generate a value
for key in the previous step, key is defined to a
Number
and this number is larger than, or equal to, the next key that store's key generator would generate, change store's key generator such that the next key it generates is the lowest integer larger than key. -
If the no-overwrite flag was passed to these steps and is set, and
a record already exists in store with its key equal to key, then
this operation failed with a
ConstraintError
. Abort this algorithm without taking any further steps. - If a record already exists in store with its key equal to key, then remove the record from store using the steps for deleting records from an object store.
- Store a record in store containing key as its key and object as its value. The record is stored in the object store's list such that the list is sorted according key of the records in ascending order.
-
If there are any indexes which reference store, perform the
following sub steps on each such index.
- Set index to the index.
- Evaluate index's key path on value. If this does not yield a value, take no further actions for this index. Otherwise set the result to index key.
-
If index's multiEntry flag is false or if index key is not an
Array
, and if index key is not a valid key, take no further actions for this index. -
If index's multiEntry flag is true, and index key is an
Array
, remove any elements from index key that are not valid keys and remove any duplicate elements from index key such that only one instance of the duplicate value remains.NoteFor example, the following value of index key
[10, 20, null, 30, 20]
is converted to[10, 20, 30]
.NoteAfter this step index key is or contains only valid keys.
-
If index's multiEntry flag is false, or if index key is not an
Array
, and if index already contains a record with key equal to index key, and index has its unique flag set to true, then this operation failed with aConstraintError
. Abort this algorithm without taking any further steps. -
If index's multiEntry flag is true and index key is an
Array
, and if index already contains a record with key equal to any of the values in index key, and index has its unique flag set to true, then this operation failed with aConstraintError
. Abort this algorithm without taking any further steps. -
If index's multiEntry flag is false, or if index key is not an
Array
, then store a record in index containig index key as its key and key as its value. The record is stored in index's list of records such that the list is sorted primarily on the records keys, and secondarily on the records values, in ascending order. -
If index's multiEntry flag is true and index key is an
Array
, then for each item in index key store a record in index containig the items value as its key and key as its value. The records are stored in index's list of records such that the list is sorted primarily on the records keys, and secondarily on the records values, in ascending order.NoteNote that it is legal for the
Array
to have length 0, in this case no records are added to the index.NoteIf any of the items in the
Array
are themselves anArray
, then the innerArray
is used as a key for that entry. In other words,Array
s are not recursively "unpacked" to produce multiple rows. Only the outer-mostArray
is.
- The result of this algorithm is key.
3.4.2 Object Store Retrieval Operation
The steps for retrieving a value from an object store are as follows. These steps MUST be run with two parameters - the record key and the object store.
- Let key be the key and store be the object store passed to these steps.
- If key is not a key range then retreive the record with key key from store. If key is a key range, then retreive the first record from store whose key is in key.
-
If no record was found, the result of this algorithm is
undefined
. - The result of this algorithm is a new structured clone of the value in the found record.
3.4.3 Index Referenced Value Retrieval Operation
The steps for retrieving a referenced value from an index are as follows. These steps MUST be run with two parameters - the record key and the index.
- Let key be the key and index be the index passed to these steps.
- If key is not a key range then find the first record with key key from index. If key is a key range, then find the first record from index whose key is in key.
-
If no record was found, the result of this algorithm is
undefined
. - Otherwise, the result of the operation is a structured clone of the referenced value of the found record.
3.4.4 Index Value Retrieval Operation
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.
- Let key be the key and index be the index passed to these steps.
- If key is not a key range then find the first record with key key from index. If key is a key range, then find the first record from index whose key is in key.
-
If no record was found, the result of this algorithm is
undefined
. - If a record was found, the result of this algorithm is the value of the found record.
3.4.5 Object Store Deletion Operation
The steps for deleting records from an object store are as follows. The algorithm run by these steps takes two parameters: an object store store and a key.
- If the key parameter is a key range then let range be that key range. Otherwise, let range be a key range which containing only key.
- Remove all records, if any, from store with key in range.
- In all indexes which reference store, remove all records whose value is in range, if any such records exist.
-
The result of this algorithm is
undefined
.
3.4.6 Object Store Clear Operation
The steps for clearing an object store are as follows. The algorithm run by these steps takes one parameter: an object store store.
3.4.7 Cursor Iteration Operation
The steps for iterating a cursor are as follows. The algorithm run by these steps takes two parameters: a cursor and optional key to iterate to.
-
Let source be cursor's source, let
records be list of records in source, let direction
be cursor's direction, let position be cursor's
position, let object store position be cursor's object store position
and let range be cursor's range.
Note
source is always an object store or an index.
-
If direction is
"next"
, let found record be the first record in records which satisfy all of the following requirements:- If key is defined, the record's key is greater than or equal to key.
- If position is defined, and source is an object store, the record's key is greater than position.
- If position is defined, and source is an index, the record's key is equal to position and the record's value is greater than object store position or the record's key is greater than position.
- If range is defined, the record's key is in range.
If direction is
"nextunique"
, let found record be the first record in records which satisfy all of the following requirements:- If key is defined, the record's key is greater than or equal to key.
- If position is defined, the record's key is greater than position.
- If range is defined, the record's key is in range.
If direction is
"prev"
, let found record be the last record in records which satisfy all of the following requirements:- If key is defined, the record's key is less than or equal to key.
- If position is defined, and source is an object store, the record's key is less than position.
- If position is defined, and source is an index, the record's key is equal to position and the record's value is less than object store position or the record's key is less than position.
- If range is defined, the record's key is in range.
If direction is
"prevunique"
, let temp record be the last record in records which satisfy all of the following requirements:- If key is defined, the record's key is less than or equal to key.
- If position is defined, the record's key is less than position.
- If range is defined, the record's key is in range.
If temp record is defined, let found record be the first record in records whose key is equal to temp record's key.
-
If found record is not defined, set cursor's key to
undefined
. If source is an index, set cursor's object store position toundefined
. If cursor implementsIDBCursorWithValue
then set cursor's value toundefined
. The result of this algorithm isnull
. Abort these steps. -
Set cursor's position to found record's key. If source is an index, set cursor's object store position to found record's value.
-
Set cursor's key to found record's key.
If cursor implements
IDBCursorWithValue
then set cursor's value to a structured clone of found record referenced value. -
Set cursor's got value flag to true.
Note
Once data has been successfully read, schedule a task which when run will set the cursor's value and fire a success event.
- The result of the algorithm is cursor.
4. Privacy
This section is non-normative.
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 id object (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
iframe
s. - 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.2 Cookie resurrection
If the user interface for persistent storage presents data in the persistent storage features described in this specification separately from data in HTTP session cookies, then users are likely to delete data in one and not the other. This would allow sites to use the two features as redundant backup for each other, defeating a user's attempts to protect his privacy.
4.3 Sensitivity of data
User agents should treat persistently stored data as potentially sensitive; it is 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
This section is non-normative.
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 wish list 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 wish list; 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
B. Revision History
The following is an informative summary of the changes since the last publication of this specification. A complete revision history of the Editor's Drafts of this specification can be found here.
C. Acknowledgements
Special thanks and great appreciation to Nikunj Mehta, the original author of this specification, who was employed by Oracle Corp when he wrote the early drafts.
Garret Swart was extremely influential in the design of this specification.
Special thanks to Chris Anderson, Pablo Castro, Kristof Degrave, Jake Drew, Ben Dilts, João Eiras: Alec Flett, Dana Florescu, David Grogan, Israel Hilerio, Kyle Huey, Laxminarayan G Kamath A, Anne van Kesteren, Tobie Langel, Kang-Hao Lu, Andrea Marchesini, Glenn Maynard, Ms2ger, Odin Omdal, Danillo Paiva, Olli Pettay, Simon Pieters, Yonathan Randolph, Arun Ranganathan, Margo Seltzer, Maciej Stachowiak, Ben Turner, Hans Wennborg, Shawn Wilsher, Boris Zbarsky Zhiqiang Zhang, and Kris Zyp, all of whose feedback and suggestions have led to improvements to this specification.
D. References
D.1 Normative references
- [DOM-LEVEL-3-EVENTS]
- Gary Kacmarcik; Travis Leithead; Jacob Rossi; Doug Schepers; Björn Höhrmann; Philippe Le Hégaret; Tom Pixley. Document Object Model (DOM) Level 3 Events Specification. 25 September 2014. W3C Working Draft. URL: https://www.w3.org/TR/DOM-Level-3-Events/
- [DOM4]
- Anne van Kesteren; Aryeh Gregor; Ms2ger; Alex Russell; Robin Berjon. W3C DOM4. 10 July 2014. W3C Last Call Working Draft. URL: https://www.w3.org/TR/dom/
- [ECMA-262]
- ECMAScript Language Specification, Edition 5.1. June 2011. URL: https://www.ecma-international.org/publications/standards/Ecma-262.htm
- [HTML5]
- Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. HTML5. 28 October 2014. W3C Recommendation. URL: https://www.w3.org/TR/html5/
- [RFC2119]
- S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
- [WEBIDL]
- Cameron McCormack. Web IDL. 19 April 2012. W3C Candidate Recommendation. URL: https://www.w3.org/TR/WebIDL/
- [WEBWORKERS]
- Ian Hickson. Web Workers. 1 May 2012. W3C Candidate Recommendation. URL: https://www.w3.org/TR/workers/
D.2 Informative references
- [COOKIES]
- A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6265
- [WEBSTORAGE]
- Ian Hickson. Web Storage. 30 July 2013. W3C Recommendation. URL: https://www.w3.org/TR/webstorage/