From ee40bb3706a059d070f250d83b7ea111116a0e44 Mon Sep 17 00:00:00 2001
From: Joshua Bell
Date: Fri, 12 May 2017 09:41:12 -0700
Subject: [PATCH] Define db's associated upgrade tx to align with impls/tests
(Resolves #192)
Implementations and tests have create/deleteObjectStore throw "TransactionInactiveError" if the transaction has aborted but the abort event has not yet fired. The spec disagreed, or at least was imprecise about the definition of "finished".
To resolve this, databases are given an associated upgrade tx which is nulled out when the event fires, rather than relying on "finished". This simplifies text elsewhere too.
Covered by existing web-platform-tests.
---
index.bs | 154 ++++++++++++----------
index.html | 366 ++++++++++++++++++++++++++++-------------------------
2 files changed, 280 insertions(+), 240 deletions(-)
diff --git a/index.bs b/index.bs
index 449b146..ce321f9 100644
--- a/index.bs
+++ b/index.bs
@@ -418,9 +418,12 @@ created, its [=database/version=] is 0 (zero).
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 an [=upgrade transaction=].
+ version is using an [=/upgrade transaction=].
+A [=database=] has at most one associated upgrade transaction ,
+which is either null or an [=/upgrade transaction=], and is initially null.
+
@@ -484,7 +487,7 @@ connection=] with the [=/connection=] and with the |forced flag| set.
A [=/connection=] has an object store set , which is
initialized to the set of [=/object stores=] in the associated
[=database=] when the [=/connection=] is created. The contents of the
-set will remain constant except when an [=upgrade transaction=] is
+set will remain constant except when an [=/upgrade transaction=] is
running.
A [=/connection=]'s [=get the parent=] algorithm returns
@@ -508,7 +511,7 @@ storing data in a [=database=].
Each database has a set of [=/object stores=]. The set of [=/object
-stores=] can be changed, but only using an [=upgrade transaction=],
+stores=] can be changed, but only using an [=/upgrade transaction=],
i.e. in response to an [=upgradeneeded=]
event. When a
new database is created it doesn't contain any [=/object stores=].
@@ -562,12 +565,12 @@ An [=/object store handle=] has an index set , which is
initialized to the set of [=/indexes=] that reference the associated
[=object-store-handle/object store=] when the [=/object store handle=]
is created. The contents of the set will remain constant except when
-an [=upgrade transaction=] is running.
+an [=/upgrade transaction=] is running.
An [=/object store handle=] has a name , which is
initialized to the [=object-store/name=] of the associated
[=object-store-handle/object store=] when the [=/object store handle=]
-is created. The name will remain constant except when an [=upgrade
+is created. The name will remain constant except when an [=/upgrade
transaction=] is running.
@@ -916,7 +919,7 @@ particular [=/index=] within a [=/transaction=].
An [=index handle=] has a name , which is initialized to the
[=index/name=] of the associated [=index-handle/index=] when the
[=index handle=] is created. The name will remain constant except when
-an [=upgrade transaction=] is running.
+an [=/upgrade transaction=] is running.
@@ -1196,7 +1199,7 @@ with [=transaction/cleanup event loop=] matching the current
An upgrade transaction is a [=/transaction=] with [=transaction/mode=]
{{"versionchange"}}.
-An [=upgrade transaction=] is automatically created when running the
+An [=/upgrade transaction=] is automatically created when running the
steps to [=run an upgrade transaction=] after a [=/connection=]
is opened to a [=/database=], if a [=database/version=] greater than
the current [=database/version=] is specified. This [=/transaction=]
@@ -1204,26 +1207,26 @@ will be active inside the [=upgradeneeded=]
event
handler.
- An [=upgrade transaction=] enables the creation, renaming, and
+ An [=/upgrade transaction=] enables the creation, renaming, and
deletion of [=/object stores=] and [=/indexes=] in a [=/database=].
- An [=upgrade transaction=] is exclusive. The steps to [=open a
+ An [=/upgrade transaction=] is exclusive. The steps to [=open a
database=] ensure that only one [=/connection=] to the database is
- open when an [=upgrade transaction=] is running.
+ open when an [=/upgrade transaction=] is running.
The [=upgradeneeded=]
event isn't fired, and thus the
- [=upgrade transaction=] isn't started, until all other
+ [=/upgrade transaction=] isn't started, until all other
[=/connections=] to the same [=/database=] are closed. This ensures
that all previous transactions are [=transaction/finished=]. As long
- as an [=upgrade transaction=] is running, attempts to open more
+ as an [=/upgrade 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 by calling {{IDBDatabase/transaction()}} will throw an
- exception. Thus [=upgrade transactions=] not only ensure that no
+ exception. Thus [=/upgrade transactions=] not only ensure that no
other transactions are running concurrently, but also ensure that no
new transactions are queued against the same [=/database=] as long
as the transaction is running.
- This ensures that once an [=upgrade transaction=] is complete, the
+ This ensures that once an [=/upgrade transaction=] is complete, the
set of [=/object stores=] and [=/indexes=] in a [=/database=] remain
constant for the lifetime of all subsequent [=/connections=] and
[=/transactions=].
@@ -1268,7 +1271,7 @@ A [=request=]'s [=get the parent=] algorithm returns the request's
Requests are not typically re-used, but there are exceptions. When a
[=cursor=] is iterated, the success of the iteration is reported
on the same [=request=] object used to open the cursor. And when
- an [=upgrade transaction=] is necessary, the same [=open
+ an [=/upgrade transaction=] is necessary, the same [=open
request=] is used for both the [=upgradeneeded=]
event and final result of the open operation itself. In both cases,
the request's [=request/done flag=] will be unset then set again, and the
@@ -2031,7 +2034,7 @@ enum IDBRequestReadyState {
Returns the {{IDBTransaction}} the request was made within.
If this as an [=open request=], then it returns an
- [=upgrade transaction=] while it is running, or null otherwise.
+ [=/upgrade transaction=] while it is running, or null otherwise.
request . {{IDBRequest/readyState}}
@@ -2262,9 +2265,9 @@ when invoked, must run these steps:
2. Otherwise, set the [=request/result=] of |request|
to |result| and [=fire an event=] named
success
at |request|. If the steps
- above resulted in an [=upgrade transaction=] being run,
+ above resulted in an [=/upgrade transaction=] being run,
then firing the "success
" event must be done
- after the [=upgrade transaction=] completes.
+ after the [=/upgrade transaction=] completes.
The last requirement is to ensure that in case another
@@ -2448,7 +2451,7 @@ must return this [=/connection=]'s
As long as the [=/connection=] is open, this is the same as the
connected [=database=]'s [=database/version=]. But once the
[=/connection=] has [=connection/closed=], this attribute will not
- reflect changes made with a later [=upgrade transaction=].
+ reflect changes made with a later [=/upgrade transaction=].
@@ -2467,7 +2470,7 @@ must return this [=/connection=]'s
and returns a new {{IDBObjectStore}}.
Throws a "{{InvalidStateError}}" {{DOMException}} if not called within an
- [=upgrade transaction=].
+ [=/upgrade transaction=].
connection .
@@ -2476,7 +2479,7 @@ must return this [=/connection=]'s
Deletes the [=/object store=] with the given |name|.
Throws a "{{InvalidStateError}}" {{DOMException}} if not called within an
- [=upgrade transaction=].
+ [=/upgrade transaction=].
@@ -2493,7 +2496,7 @@ the [=/object stores=] in this [=/connection=]'s [=object store set=].
As long as the [=/connection=] is open, this is the same as the
connected [=database=]'s [=/object store=] [=object-store/names=].
But once the [=/connection=] has [=connection/closed=], this attribute
- will not reflect changes made with a later [=upgrade transaction=].
+ will not reflect changes made with a later [=/upgrade transaction=].
@@ -2505,10 +2508,9 @@ The createObjectStore(|name|,
1. Let |database| be the [=database=] associated with this
[=/connection=].
-2. Let |transaction| be the [=upgrade transaction=] associated with
- |database|. If one does not exist or it is
- [=transaction/finished=], [=throw=] an "{{InvalidStateError}}"
- {{DOMException}}.
+2. Let |transaction| be |database|'s [=database/upgrade transaction=]
+ if it is not null, or [=throw=] an "{{InvalidStateError}}"
+ {{DOMException}} otherwise.
3. If |transaction| is not [=transaction/active=], [=throw=] a
"{{TransactionInactiveError}}" {{DOMException}}.
@@ -2545,7 +2547,7 @@ The createObjectStore(|name|,
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 an [=upgrade transaction=].
+only be called from within an [=/upgrade transaction=].
This method synchronously modifies the
{{IDBDatabase/objectStoreNames}} property on the {{IDBDatabase}}
@@ -2574,10 +2576,9 @@ method, when invoked, must run these steps:
1. Let |database| be the [=database=] associated with this
[=/connection=].
-2. Let |transaction| be the [=upgrade transaction=] associated with
- |database|. If one does not exist or it is
- [=transaction/finished=], [=throw=] an "{{InvalidStateError}}"
- {{DOMException}}.
+2. Let |transaction| be |database|'s [=database/upgrade transaction=]
+ if it is not null, or [=throw=] an "{{InvalidStateError}}"
+ {{DOMException}} otherwise.
3. If |transaction| is not [=transaction/active=], [=throw=] a
"{{TransactionInactiveError}}" {{DOMException}}.
@@ -2599,7 +2600,7 @@ method, when invoked, must run these steps:
This method destroys the [=/object store=] with the given name in the
[=connected=] [=database=]. Note that this method must only be called
-from within an [=upgrade transaction=].
+from within an [=/upgrade transaction=].
This method synchronously modifies the
{{IDBDatabase/objectStoreNames}} property on the {{IDBDatabase}}
@@ -2632,7 +2633,7 @@ instance on which it was called.
The transaction(|storeNames|,
|mode|) method, when invoked, must run these steps:
-1. If a running [=upgrade transaction=] is associated with the [=/connection=],
+1. If a running [=/upgrade transaction=] is associated with the [=/connection=],
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
2. If the [=/connection=]'s
@@ -2757,7 +2758,7 @@ dictionary IDBIndexParameters {
Updates the [=object-store/name=] of the store to |newName|.
- Throws "{{InvalidStateError}}" {{DOMException}} if not called within an [=upgrade
+ Throws "{{InvalidStateError}}" {{DOMException}} if not called within an [=/upgrade
transaction=].
store . {{IDBObjectStore/keyPath}}
@@ -2792,7 +2793,7 @@ must return this [=/object store handle=]'s
this is the same as the associated [=/object store=]'s
[=object-store/name=]. But once the [=/transaction=] has
[=transaction/finished=], this attribute will not reflect changes made with a
- later [=upgrade transaction=].
+ later [=/upgrade transaction=].
@@ -2811,7 +2812,7 @@ The {{IDBObjectStore/name}} attribute's setter must run these steps:
4. If |store| has been deleted,
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
-5. If |transaction| is not an [=upgrade transaction=],
+5. If |transaction| is not an [=/upgrade transaction=],
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
6. If |transaction| is not [=transaction/active=],
@@ -2867,7 +2868,7 @@ of [=/indexes=] in this [=/object store handle=]'s
this is the same as the associated [=/object store=]'s list
of [=/index=] [=index/names=]. But once the
[=/transaction=] has [=transaction/finished=], this attribute will not
- reflect changes made with a later [=upgrade transaction=].
+ reflect changes made with a later [=/upgrade transaction=].
@@ -3590,11 +3591,11 @@ or not given, an [=unbounded key range=] is used.
Creates a new [=/index=] in |store| with the given |name|,
|keyPath| and |options| and returns a new {{IDBIndex}}. If the
|keyPath| and |options| define constraints that cannot be
- satisfied with the data already in |store| the [=upgrade
+ satisfied with the data already in |store| the [=/upgrade
transaction=] will [=transaction/abort=] with
a "{{ConstraintError}}" {{DOMException}}.
- Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=upgrade
+ Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=/upgrade
transaction=].
@@ -3604,7 +3605,7 @@ or not given, an [=unbounded key range=] is used.
Deletes the [=/index=] in |store| with the given |name|.
- Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=upgrade
+ Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=/upgrade
transaction=].
@@ -3622,7 +3623,7 @@ The createIndex(|name|, |keyPath|,
2. Let |store| be this [=/object store handle=]'s
[=object-store-handle/object store=].
-3. If |transaction| is not an [=upgrade transaction=],
+3. If |transaction| is not an [=/upgrade transaction=],
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
4. If |store| has been deleted, [=throw=] an
@@ -3664,7 +3665,7 @@ The createIndex(|name|, |keyPath|,
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 an [=upgrade transaction=].
+must only be called from within an [=/upgrade transaction=].
The index that is requested to be created can contain constraints on
the data allowed in the index's [=referenced=] object store, such
@@ -3674,14 +3675,14 @@ which violates these constraints, this must not cause the
implementation of {{IDBObjectStore/createIndex()}} to throw an
exception or affect what it returns. The implementation must still
create and return an {{IDBIndex}} object, and the implementation must
-[=queue a task=] to abort the [=upgrade transaction=] which was
+[=queue a task=] to abort the [=/upgrade transaction=] which was
used for the {{IDBObjectStore/createIndex()}} call.
This method synchronously modifies the {{IDBObjectStore/indexNames}}
property on the {{IDBObjectStore}} instance on which it was called.
Although this method does not return an {{IDBRequest}} object, the
index creation itself is processed as an asynchronous request within
-the [=upgrade transaction=].
+the [=/upgrade transaction=].
In some implementations it is possible for the implementation to
asynchronously run into problems creating the index after the
@@ -3770,7 +3771,7 @@ when invoked, must run these steps:
2. Let |store| be this [=/object store handle=]'s
[=object-store-handle/object store=].
-3. If |transaction| is not an [=upgrade transaction=],
+3. If |transaction| is not an [=/upgrade transaction=],
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
4. If |store| has been deleted, [=throw=] an
@@ -3792,13 +3793,13 @@ when invoked, must run these steps:
This method destroys the [=/index=] with the given name in the
[=/object store=]. Note that this method must only be called from
-within an [=upgrade transaction=].
+within an [=/upgrade transaction=].
This method synchronously modifies the {{IDBObjectStore/indexNames}}
property on the {{IDBObjectStore}} instance on which it was called.
Although this method does not return an {{IDBRequest}} object, the
index destruction itself is processed as an asynchronous request
-within the [=upgrade transaction=].
+within the [=/upgrade transaction=].
@@ -3842,7 +3843,7 @@ interface IDBIndex {
Updates the [=index/name=] of the store to |newName|.
- Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=upgrade
+ Throws an "{{InvalidStateError}}" {{DOMException}} if not called within an [=/upgrade
transaction=].
index . {{IDBIndex/objectStore}}
@@ -3875,7 +3876,7 @@ return this [=index handle=]'s [=index/name=].
this is the same as the associated [=/index=]'s
[=index/name=]. But once the [=/transaction=] has
[=transaction/finished=], this attribute will not reflect changes made with a
- later [=upgrade transaction=].
+ later [=/upgrade transaction=].
@@ -3891,7 +3892,7 @@ The {{IDBIndex/name}} attribute's setter must run these steps:
3. Let |index| be this [=index handle=]'s
[=index-handle/index=].
-4. If |transaction| is not an [=upgrade transaction=],
+4. If |transaction| is not an [=/upgrade transaction=],
[=throw=] an "{{InvalidStateError}}" {{DOMException}}.
5. If |transaction| is not [=transaction/active=], [=throw=] a
@@ -5066,14 +5067,14 @@ enum IDBTransactionMode {
transaction . {{IDBTransaction/objectStoreNames}}
Returns a list of the names of [=/object stores=] in the
- transaction's [=transaction/scope=]. For an [=upgrade transaction=]
+ transaction's [=transaction/scope=]. For an [=/upgrade transaction=]
this is all object stores in the [=database=].
transaction . {{IDBTransaction/mode}}
Returns the [=transaction/mode=] the transaction was created with
({{"readonly"}} or {{"readwrite"}}), or {{"versionchange"}} for
- an [=upgrade transaction=].
+ an [=/upgrade transaction=].
transaction . {{IDBTransaction/db}}
@@ -5093,7 +5094,7 @@ enum IDBTransactionMode {
The objectStoreNames
attribute's getter must run these steps:
-1. If this [=/transaction=] is an [=upgrade transaction=],
+1. If this [=/transaction=] is an [=/upgrade transaction=],
return a {{DOMStringList}} associated with a [=sorted name list=] of the [=object-store/names=]
of the [=/object stores=] in this
[=/transaction=]'s [=/connection=]'s [=object store
@@ -5114,7 +5115,7 @@ attribute's getter must run these steps:
The contents of each list returned by this attribute does not
- change, but subsequent calls to this attribute during an [=upgrade
+ change, but subsequent calls to this attribute during an [=/upgrade
transaction=] can return lists with different contents as
[=/object stores=] are created and deleted.
@@ -5294,7 +5295,7 @@ database |name|, a database |version|, and a |request|.
return a newly created
"{{AbortError}}" {{DOMException}} and abort these steps.
- 8. If the [=upgrade transaction=] was aborted, run the steps
+ 8. If the [=/upgrade transaction=] was aborted, run the steps
to [=close a database connection=] with |connection|,
create and return a newly created
"{{AbortError}}" {{DOMException}} and abort these steps.
@@ -5434,7 +5435,10 @@ This algorithm takes one argument, the |transaction| to commit.
3. [=Queue a task=] to run these steps:
- 1. [=Fire an event=] named complete
at |transaction|.
+ 1. If |transaction| is an [=/upgrade transaction=], set the
+ [=database=]'s [=database/upgrade transaction=] to null.
+
+ 2. [=Fire an event=] named complete
at |transaction|.
Even if an exception is thrown from one of the event handlers of
@@ -5444,7 +5448,7 @@ This algorithm takes one argument, the |transaction| to commit.
"complete
" event fired.
- 2. If |transaction| is an [=upgrade transaction=], then
+ 3. If |transaction| is an [=/upgrade transaction=], then
let |request| be the [=request=] associated with |transaction|
and set |request|'s [=request/transaction=] to null.
@@ -5462,13 +5466,13 @@ This algorithm
takes two arguments: the |transaction| to abort, and |error|.
1. All the changes made to the [=database=] by the [=/transaction=]
- are reverted. For [=upgrade transactions=] this includes changes
+ are reverted. For [=/upgrade transactions=] this includes changes
to the set of [=/object stores=] and [=/indexes=], as well as the
change to the [=database/version=]. Any [=/object stores=] and
[=/indexes=] which were created during the transaction are now
considered deleted for the purposes of other algorithms.
-2. If |transaction| is an [=upgrade transaction=], run the steps
+2. If |transaction| is an [=/upgrade transaction=], run the steps
to [=abort an upgrade transaction=] with |transaction|.
@@ -5502,10 +5506,13 @@ takes two arguments: the |transaction| to abort, and |error|.
5. [=Queue a task=] to run these steps:
- 1. [=Fire an event=] named abort
at |transaction|
+ 1. If |transaction| is an [=/upgrade transaction=], set the
+ [=database=]'s [=database/upgrade transaction=] to null.
+
+ 2. [=Fire an event=] named abort
at |transaction|
with its {{Event/bubbles}} attribute initialized to true.
- 2. If |transaction| is an [=upgrade transaction=], then
+ 3. If |transaction| is an [=/upgrade transaction=], then
let |request| be the [=request=] associated with |transaction|
and set |request|'s [=request/transaction=] to null.
@@ -5586,14 +5593,16 @@ for the [=database=], and a |request|.
1. Let |db| be |connection|'s [=database=].
-2. Let |transaction| be a new [=upgrade transaction=] with
+2. Let |transaction| be a new [=/upgrade transaction=] with
|connection| used as [=/connection=]. The [=transaction/scope=] of
|transaction| includes every [=/object store=] in
|connection|.
-3. Unset |transaction|'s [=transaction/active flag=].
+3. Set |database|'s [=database/upgrade transaction=] to |transaction|.
-4. Start |transaction|.
+4. Unset |transaction|'s [=transaction/active flag=].
+
+5. Start |transaction|.
Note that until this [=/transaction=] is finished, no
@@ -5601,13 +5610,13 @@ for the [=database=], and a |request|.
[=database=].
-5. Let |old version| be |db|'s [=database/version=].
+6. Let |old version| be |db|'s [=database/version=].
-6. Set the version of |db| to |version|. This change is
+7. Set the version of |db| to |version|. This change is
considered part of the [=/transaction=], and so if the
transaction is [=transaction/aborted=], this change is reverted.
-7. [=Queue a task=] to run these steps:
+8. [=Queue a task=] to run these steps:
1. Set |request|'s [=request/result=] to |connection|.
2. Set |request|'s [=request/transaction=] to |transaction|.
@@ -5622,13 +5631,13 @@ for the [=database=], and a |request|.
transaction=] with the |error| property set to a newly
created "{{AbortError}}" {{DOMException}}.
-8. Wait for |transaction| to [=transaction/finish=].
+9. Wait for |transaction| to [=transaction/finish=].
Some of the algorithms invoked during the [=/transaction=]'s
[=transaction/lifetime=], such as the steps to [=commit a
transaction=] and the steps to [=abort a transaction=],
- include steps specific to [=upgrade transactions=].
+ include steps specific to [=/upgrade transactions=].
@@ -5725,7 +5734,7 @@ are as follows.
The {{IDBDatabase/name}} property of the {{IDBDatabase}} instance is
- not modified, even if the aborted [=upgrade transaction=] was
+ not modified, even if the aborted [=/upgrade transaction=] was
creating a new [=database=].
@@ -7159,6 +7168,11 @@ document's Revision History.
(issue #197 ,
issue #152 )
+* Define [=database=]'s associated [=database/upgrade transaction=] to
+ align exceptions thrown from {{IDBDatabase/createObjectStore()}} and
+ {{IDBDatabase/deleteObjectStore()}} with tests and implementations.
+ (issue #192 )
+
Acknowledgements
diff --git a/index.html b/index.html
index 09aad2f..fee58bd 100644
--- a/index.html
+++ b/index.html
@@ -1459,7 +1459,7 @@
Indexed Database API 2.0
-
Editor’s Draft, 9 May 2017
+
Editor’s Draft, 11 May 2017
This version:
@@ -1888,23 +1888,25 @@ 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 an upgrade transaction .
+ A database has at most one associated upgrade transaction ,
+which is either null or an upgrade transaction , and is initially null.
2.1.1. Database Connection
-
Script does not interact with databases directly. Instead,
+
Script does not interact with databases directly. Instead,
script has indirect access via a connection .
A connection object can be used to manipulate the objects of
-that database . It is also the only way to obtain a transaction for that database .
-
The act of opening a database creates a connection .
-There may be multiple connections to a given database at
+that database . It is also the only way to obtain a transaction for that database .
+
The act of opening a database creates a connection .
+There may be multiple connections to a given database at
any given time.
-
A connection can only access databases associated with the origin of the global scope from which the connection is
+
A connection can only access databases associated with the origin of the global scope from which the connection is
opened.
2.2. Object Store
An object store is the primary storage mechanism for
-storing data in a database .
+storing data in a
database .
Each database has a set of object stores . The set of object
-stores can be changed, but only using an upgrade transaction ,
+stores can be changed, but only using an upgrade transaction ,
i.e. in response to an upgradeneeded
event. When a
new database is created it doesn’t contain any object stores .
An object store has a list of records which hold the
@@ -1946,7 +1948,7 @@
An object store has a name , which is a name .
At any one time, the name is unique
-within the database to which it belongs.
+within the database to which it belongs.
An object store optionally has a 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 .
@@ -1972,9 +1974,9 @@ An object store handle has an index set , which is
initialized to the set of indexes that reference the associated object store when the object store handle is created. The contents of the set will remain constant except when
-an upgrade transaction is running.
+an upgrade transaction is running.
An object store handle has a name , which is
-initialized to the name of the associated object store when the object store handle is created. The name will remain constant except when an upgrade
+initialized to the name of the associated object store when the object store handle is created. The name will remain constant except when an upgrade
transaction is running.
2.3. Values
@@ -2268,11 +2270,11 @@
index handle associated with a
particular index within a transaction .
An index handle has a name , which is initialized to the name of the associated index when the index handle is created. The name will remain constant except when
-an upgrade transaction is running.
+an upgrade transaction is running.
2.7. Transactions
A Transaction is used to interact
-with the data in a database . Whenever data is read or written
+with the data in a database . Whenever data is read or written
to the database it is done by using a transaction .
Transactions offer some protection from application and system
@@ -2363,7 +2365,7 @@
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
+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 .
@@ -2379,7 +2381,7 @@ database made by requests placed against the transaction. That
+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,
@@ -2417,7 +2419,7 @@ object stores in the read/write transaction ’s scope . The implementation
must also ensure that if the read/write transaction completes successfully, the changes written to object
-stores using the transaction can be committed to the database without merge conflicts. An implementation must
+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 read/write transactions are attempting to access
@@ -2462,31 +2464,31 @@
transaction.
2.7.2. Upgrade Transactions
An upgrade transaction is a transaction with mode "versionchange"
.
- An upgrade transaction is automatically created when running the
-steps to run an upgrade transaction after a connection is opened to a database , if a version greater than
+
An upgrade transaction is automatically created when running the
+steps to run an upgrade transaction after a connection is opened to a database , if a version greater than
the current version is specified. This transaction will be active inside the upgradeneeded
event
handler.
- An upgrade transaction enables the creation, renaming, and
- deletion of object stores and indexes in a database .
- An upgrade transaction is exclusive. The steps to open a
+ An upgrade transaction enables the creation, renaming, and
+ deletion of object stores and indexes in a database .
+
An upgrade transaction is exclusive. The steps to open a
database ensure that only one connection to the database is
- open when an upgrade transaction is running.
- The upgradeneeded
event isn’t fired, and thus the upgrade transaction isn’t started, until all other connections to the same database are closed. This ensures
+ open when an upgrade transaction is running.
+ The upgradeneeded
event isn’t fired, and thus the upgrade transaction isn’t started, until all other connections to the same database are closed. This ensures
that all previous transactions are finished . As long
- as an upgrade transaction is running, attempts to open more connections to the same database are delayed, and any
+ as an upgrade 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 by calling transaction()
will throw an
- exception. Thus upgrade transactions not only ensure that no
+ exception. Thus upgrade transactions not only ensure that no
other transactions are running concurrently, but also ensure that no
- new transactions are queued against the same database as long
+ new transactions are queued against the same database as long
as the transaction is running.
- This ensures that once an upgrade transaction is complete, the
- set of object stores and indexes in a database remain
+
This ensures that once an upgrade transaction is complete, the
+ set of object stores and indexes in a database remain
constant for the lifetime of all subsequent connections and transactions .
2.8. Requests
- Each asynchronous operation on a database is done using a request . Every request represents one
+
Each asynchronous operation on a database is done using a request . Every request represents one
operation.
A request has a done flag which is initially unset.
@@ -2504,12 +2506,12 @@
A request 's get the parent algorithm returns the request’s transaction .
2.8.1. Open Requests
An open request is a special type of request used
-when opening a connection or deleting a database .
+when opening a connection or deleting a database .
In addition to success
and error
events, blocked
and upgradeneeded
may be fired at an open
request to indicate progress.
The source of an open request is always null.
@@ -2978,13 +2980,13 @@ 4.
access task source .
The IDBRequest
interface provides the means to access results of
-asynchronous requests to databases and database objects using event handler IDL attributes [HTML] .
+asynchronous requests to databases and database objects using event handler IDL attributes [HTML] .
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.
+requests can be active on any database at a time.
- In the following example, we open a database asynchronously.
+
In the following example, we open a database asynchronously.
Various event handlers are registered for responding to various
situations.
var request = indexedDB. open( 'AddressBook' , 15 ) ;
@@ -3024,7 +3026,7 @@ transaction
Returns the IDBTransaction
the request was made within.
- If this as an open request , then it returns an upgrade transaction while it is running, or null otherwise.
+ If this as an open request , then it returns an upgrade transaction while it is running, or null otherwise.
request . readyState
Returns "pending"
until a request is complete,
then returns "done"
.
@@ -3102,7 +3104,7 @@ 4.2
- Database objects are accessed through methods on the IDBFactory
interface. A single object implementing this
+
Database objects are accessed through methods on the IDBFactory
interface. A single object implementing this
interface is present in the global scope of environments that support
Indexed DB operations.
partial interface WindowOrWorkerGlobalScope {
@@ -3123,17 +3125,17 @@
request = indexedDB . open
(name )
- Attempts to open a connection to the named database with the current version, or 1 if it does not already exist.
+ Attempts to open a connection to the named database with the current version, or 1 if it does not already exist.
If the request is successful request ’s result
will be the connection .
request = indexedDB . open
(name , version )
- Attempts to open a connection to the named database with the specified version. If the database already exists
+ Attempts to open a connection to the named database with the specified version. If the database already exists
with a lower version and there are open connections that don’t close in response to a versionchange
event, the request will be blocked until all they close, then an upgrade
will occur. If the database already exists with a higher
version the request will fail. If the request is
successful request ’s result
will
be the connection .
request = indexedDB . deleteDatabase
(name )
- Attempts to delete the named database . If the
+ Attempts to delete the named database . If the
database already exists and there are open connections that don’t close in response to a versionchange
event, the request will be blocked until all they close. If the request
is successful request ’s result
will be null.
@@ -3160,9 +3162,9 @@ request.
What happens if version is not given?
- If version is not given and a database with that name already exists, a connection will be opened
- without changing the version . If version is not given and no database with
- that name exists, a new database will be created with version equal to 1.
+ If version is not given and a database with that name already exists, a connection will be opened
+ without changing the version . If version is not given and no database with
+ that name exists, a new database will be created with version equal to 1.
Queue a task to run these steps:
@@ -3171,9 +3173,9 @@ If result is an error, set the error of request to result and fire an event named error
at request with its bubbles
and cancelable
attributes initialized to true.
Otherwise, set the result of request to result and fire an event named success
at request . If the steps
-above resulted in an upgrade transaction being run,
+above resulted in an upgrade transaction being run,
then firing the "success
" event must be done
-after the upgrade transaction completes.
+after the upgrade transaction completes.
The 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 script gets a
@@ -3259,7 +3261,7 @@
- The IDBDatabase
interface represents a connection to a database .
+ The IDBDatabase
interface represents a connection to a database .
An IDBDatabase
object must not be garbage collected if its
associated connection 's close pending flag is unset and it
has one or more event listeners registers whose type is one of abort
, error
, or versionchange
.
@@ -3299,16 +3301,16 @@
The name attribute’s getter must
-return the name of the connected database . The attribute must return this name even if the close pending flag is set on the connection . In
+return the name of the connected database . The attribute must return this name even if the close pending flag is set on the connection . In
other words, the value of this attribute stays constant for the
lifetime of the IDBDatabase
instance.
The version attribute’s getter
must return this connection 's version .
- Is this the same as the database 's version ?
+ Is this the same as the database 's version ?
As long as the connection is open, this is the same as the
- connected database 's version . But once the connection has closed , this attribute will not
- reflect changes made with a later upgrade transaction .
+ connected database 's version . But once the connection has closed , this attribute will not
+ reflect changes made with a later upgrade transaction .
The objectStoreNames attribute’s
getter must return a DOMStringList
associated with a sorted name list of the names of
the object stores in this connection 's object store set .
- Is this the same as the database 's object store names ?
+ Is this the same as the database 's object store names ?
As long as the connection is open, this is the same as the
- connected database 's object store names .
+ connected database 's object store names .
But once the connection has closed , this attribute
- will not reflect changes made with a later upgrade transaction .
+ will not reflect changes made with a later upgrade transaction .
This method creates and returns a new object store with the given
-name in the connected database . Note that this method must
+name in the connected database . Note that this method must
only be called from within an upgrade transaction .
This method synchronously modifies the objectStoreNames
property on the IDBDatabase
instance on which it was called.
In some implementations it is possible for the implementation to run
@@ -3385,9 +3387,9 @@
The deleteObjectStore(name ) method, when invoked, must run these steps:
- Let database be the database associated with this connection .
+ Let database be the database associated with this connection .
- Let transaction be the upgrade transaction associated with database . If one does not exist or it is finished , throw an "InvalidStateError
" DOMException
.
+ Let transaction be database ’s upgrade transaction if it is not null, or throw an "InvalidStateError
" DOMException
otherwise.
If transaction is not active , throw a
"TransactionInactiveError
" DOMException
.
@@ -3403,8 +3405,8 @@ Destroy store .
- This method destroys the object store with the given name in the connected database . Note that this method must only be called
-from within an upgrade transaction .
+ This method destroys the object store with the given name in the connected database . Note that this method must only be called
+from within an upgrade transaction .
This method synchronously modifies the objectStoreNames
property on the IDBDatabase
instance on which it was called.
This method destroys the index with the given name in the object store . Note that this method must only be called from
-within an upgrade transaction .
+within an upgrade transaction .
This method synchronously modifies the indexNames
property on the IDBObjectStore
instance on which it was called.
Although this method does not return an IDBRequest
object, the
index destruction itself is processed as an asynchronous request
-within the upgrade transaction .
+within the upgrade transaction .
4.6. The IDBIndex
interface
The IDBIndex
interface represents an index handle .
[Exposed =(Window ,Worker )]
@@ -4253,7 +4255,7 @@ name = newName
Updates the name of the store to newName .
- Throws an "InvalidStateError
" DOMException
if not called within an upgrade
+ Throws an "InvalidStateError
" DOMException
if not called within an upgrade
transaction .
index . objectStore
Returns the IDBObjectStore
the index belongs to.
@@ -4269,9 +4271,9 @@ index handle 's name .
Is this the same as the index 's name ?
- As long as the transaction has not finished ,
- this is the same as the associated index 's name . But once the transaction has finished , this attribute will not reflect changes made with a
- later upgrade transaction .
+ As long as the transaction has not finished ,
+ this is the same as the associated index 's name . But once the transaction has finished , this attribute will not reflect changes made with a
+ later upgrade transaction .
The name
attribute’s setter must run these steps:
@@ -4283,7 +4285,7 @@
Let index be this index handle 's index .
- If transaction is not an upgrade transaction , throw an "InvalidStateError
" DOMException
.
+ If transaction is not an upgrade transaction , throw an "InvalidStateError
" DOMException
.
If transaction is not active , throw a
"TransactionInactiveError
" DOMException
.
@@ -5083,11 +5085,11 @@
transaction . objectStoreNames
Returns a list of the names of object stores in the
- transaction’s scope . For an upgrade transaction this is all object stores in the database .
+ transaction’s scope . For an upgrade transaction this is all object stores in the database .
transaction . mode
Returns the mode the transaction was created with
("readonly"
or "readwrite"
), or "versionchange"
for
- an upgrade transaction .
+ an upgrade transaction .
transaction . db
Returns the transaction’s connection .
transaction . error
@@ -5099,7 +5101,7 @@ objectStoreNames attribute’s getter must run these steps:
- If this transaction is an upgrade transaction ,
+
If this transaction is an upgrade transaction ,
return a DOMStringList
associated with a sorted name list of the names of the object stores in this transaction 's connection 's object store
set .
@@ -5112,12 +5114,12 @@ The contents of each list returned by this attribute does not
- change, but subsequent calls to this attribute during an upgrade
+ change, but subsequent calls to this attribute during an upgrade
transaction can return lists with different contents as object stores are created and deleted.
The mode attribute’s getter
must return the mode of the transaction .
The db attribute’s getter must
-return the database connection of which this transaction is a part.
+return the database connection of which this transaction is a part.
The error attribute’s getter
must return this transaction 's error , or null if
none.
@@ -5142,7 +5144,7 @@
- If transaction has finished , throw an
+
If transaction has finished , throw an
"InvalidStateError
" DOMException
.
Let store be the object store named name in this transaction 's scope , or throw a
@@ -5160,7 +5162,7 @@
- If this transaction is finished , throw an "InvalidStateError
" DOMException
.
+ If this transaction is finished , throw an "InvalidStateError
" DOMException
.
Unset the transaction 's active flag and run the
steps to abort a transaction with null as error .
@@ -5181,7 +5183,7 @@ 5.
The steps to open a database are as follows.
The algorithm in these steps takes four arguments:
-the origin which requested the database to be opened, a
+the origin which requested the database to be opened, a
database name , a database version , and a request .
@@ -5191,11 +5193,11 @@ 5.
Wait until all previous requests in queue have been processed.
- Let db be the database named name in origin , or null otherwise.
+ Let db be the database named name in origin , or null otherwise.
If version is undefined, let version be 1 if db is null, or db ’s version otherwise.
- If db is null, let db be a new database with name name , version 0 (zero), and with
+
If db is null, let db be a new database with name name , version 0 (zero), and with
no object stores . If this fails for any reason, return an
appropriate error (e.g. a "QuotaExceededError
" or
"UnknownError
" DOMException
).
@@ -5232,7 +5234,7 @@ 5.
If connection was closed , create and
return a newly created "AbortError
" DOMException
and abort these steps.
- If the upgrade transaction was aborted, run the steps
+
If the upgrade transaction was aborted, run the steps
to close a database connection with connection ,
create and return a newly created "AbortError
" DOMException
and abort these steps.
@@ -5270,12 +5272,12 @@
created using connection . All methods that create transactions first check the close pending flag first and throw an exception if it is set.
+ a given database to be closed before continuing.
5.3. Deleting a database
The steps to delete 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 .
+requested the
database to be deleted, a database
name , and a
request .
Let queue be the connection queue for origin and name .
@@ -5284,7 +5286,7 @@
Wait until all previous requests in queue have been processed.
- Let db be the database named name in origin , if one exists. Otherwise, return 0 (zero).
+ Let db be the database named name in origin , if one exists. Otherwise, return 0 (zero).
Let openConnections be the set of all connections associated with db .
@@ -5315,16 +5317,18 @@ transaction to commit.
- All the changes made to the database by transaction are
-written to the database .
+ All the changes made to the database by transaction are
+written to the database .
- If an error occurs while writing the changes to the database , abort the transaction by following the steps
+
If an error occurs while writing the changes to the database , abort the transaction by following the steps
to abort a transaction with transaction and an
appropriate for the error, for example "QuotaExceededError
" or
"UnknownError
" DOMException
.
Queue a task to run these steps:
+
+ If transaction is an upgrade transaction , set the database 's upgrade transaction to null.
Fire an event named complete
at transaction .
Even if an exception is thrown from one of the event handlers of
@@ -5345,7 +5349,7 @@ transaction to abort, and error .
- All the changes made to the database by the transaction are reverted. For upgrade transactions this includes changes
+
All the changes made to the database by the transaction are reverted. For upgrade transactions this includes changes
to the set of object stores and indexes , as well as the
change to the version . Any object stores and indexes which were created during the transaction are now
considered deleted for the purposes of other algorithms.
@@ -5377,10 +5381,12 @@
Queue a task to run these steps:
+
+ If transaction is an upgrade transaction , set the database 's upgrade transaction to null.
Fire an event named abort
at transaction with its bubbles
attribute initialized to true.
- If transaction is an upgrade transaction , then
+
If transaction is an upgrade transaction , then
let request be the request associated with transaction and set request ’s transaction to null.
@@ -5448,19 +5454,21 @@
The steps to run an upgrade 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 .
+which is used to update the database , a new version to be set
+for the database , and a request .
- Let db be connection ’s database .
+ Let db be connection ’s database .
+
+ Let transaction be a new upgrade transaction with connection used as connection . The scope of transaction includes every object store in connection .
- Let transaction be a new upgrade transaction with connection used as connection . The scope of transaction includes every object store in connection .
+ Set database ’s upgrade transaction to transaction .
Unset transaction ’s active flag .
Start transaction .
+ other connections can be opened to the same database .
Let old version be db ’s version .
@@ -5488,24 +5496,24 @@ with the error property set to a newly created "AbortError
" DOMException
.
- Wait for transaction to finish .
+ Wait for transaction to finish .
+ include steps specific to upgrade transactions .
5.8. Aborting an upgrade transaction
The steps to abort an upgrade transaction with transaction are as follows.
Let connection be transaction ’s connection .
- Let database be connection ’s database .
+ Let database be connection ’s database .
Set connection ’s version to database ’s version if database previously existed, or 0 (zero)
if database was newly created.
@@ -5551,8 +5559,8 @@
+ not modified, even if the aborted upgrade transaction was
+ creating a new database .
5.9. Firing a success event
To fire a success event at a request ,
@@ -5625,7 +5633,7 @@
6. Database operations
- This section describes various operations done on the data in object stores and indexes in a database .
+
This section describes various operations done on the data in object stores and indexes in a database .
These operations are run by the steps to asynchronously execute
a request .
Invocations of StructuredDeserialize () in the operation
@@ -6687,8 +6695,9 @@ asynchronously execute a request steps.
(issue #192 )
- Use [HTML] 's StructuredSerializeForStorage hook.
-(issue #197 , issue #152 )
+ Define database 's associated upgrade transaction to
+align exceptions thrown from createObjectStore()
and deleteObjectStore()
with tests and implementations.
+(issue #192 )
11. Acknowledgements
Special thanks to Nikunj Mehta, the original author of the first
@@ -7229,7 +7238,12 @@
unique flag, in §2.6
update(value) , in §4.8
upgradeneeded , in §2.8.1
- upgrade transaction , in §2.7.2
+
+ upgrade transaction
+
upper , in §4.7
upper bound , in §2.9
upperBound(upper) , in §4.7
@@ -7634,27 +7648,28 @@ I
+
@@ -8315,24 +8339,24 @@ I