1. 序論
~UAは、 ~web~appの~off-line~data要件を満たすため,多数の~objを局所に格納する必要がある。 `WEBSTORAGE$r は、[ ~key, それに対応する値 ]が成す~pairたちを格納するために有用ではあるが、[ ~keyたちを順序どおりに検索取得する/ 多数の値にわたり効率的に探索する/ 同じ~keyに値を重複して格納する ]方法は供さない。 ◎ 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.
この仕様は、[ 大多数の洗練された~query処理器の心臓部である,高度な { ~key: 値 } ~data管理 ]を遂行する~APIを供する — ~txに基づく~dbを利用して,一連の[ ~key, それに対応する(~keyごとに一つ以上の)値 ]を格納し,各~keyを決定的~順序で辿る手段を供することにより。 これは、 持続的な~B-tree~data構造を利用して実装されることが多い — それは、 挿入と削除に加えて,大量の~data~recordを順序どおりに辿るときにも効率的であると考えられているので。 ◎ 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.
次の例は、 ~APIを利用して,`書庫^l ~dbに~accessする。 この~dbは、 名前 `書棚^l の`保管庫$を有する。 この書棚には、 `isbn^l ~propを首keyに用いて,一群の`~record$ (すなわち, “本” )が格納される。 ◎ The following example uses the API to access a "library" database. It has a "books" object store that holds books records stored by their "isbn" property as the primary key.
各 本には、 `書名^l ~propもある。 この例では、 書名が【書棚~内で】一意になることを,人為的に要求する。 この~codeは、[ `unique@#dom-idbindexparameters-unique$m ~optionが ~T に設定された,名前 `書名索引^l の`索引$を作成する ]ことにより,これを施行する。 この索引は、 各 本を書名で検索するために利用され,書名が一意でない本を追加するのも防止することになる。 ◎ Book records have a "title" property. This example artificially requires that book titles are unique. The code enforces this by creating an index named "by_title" with the unique option set. This index is used to look up books by title, and will prevent adding books with non-unique titles.
各 本には、 `著者名^l ~propもあり,一意になることは要求されない。 この~codeは、 名前 `著者名索引^l の`索引$も作成して,この~propによる検索を許容する。 ◎ Book records also have an "author" property, which is not required to be unique. The code creates another index named "by_author" to allow look-ups by this property.
この~codeは、 まず,~dbへの接続を~openする。 `upgradeneeded$et ~event~handlerの~codeが,必要なら保管庫と(それに`専属する$)索引たちを作成する。 `success$et ~event~handlerの~codeは、 ~openした接続を後の利用-用に保存する。 ◎ The code first opens a connection to the database. The upgradeneeded event handler code creates the object store and indexes, if needed. The success event handler code saves the opened connection for use in later examples.
const %request = `indexedDB$m.open(`書庫^l); let %書庫; %request.onupgradeneeded = function() { /* 書庫~dbはまだ存在しないので,保管庫と索引を作成する。 ◎ The database did not previously exist, so create object stores and indexes. */ const %書庫 = %request.result; const %書棚 = %書庫.createObjectStore(`書棚^l, {keyPath: `isbn^l}); const %書名索引 = %書棚.createIndex(`書名索引^l, `書名^l, {unique: true}); const %著者名索引 = %書棚.createIndex(`著者名索引^l, `著者名^l); /* 初期~dataで保管庫を拡充する (索引は自動的に拡充される)。 ◎ Populate with initial data. */ %書棚.put({書名: `Quarry Memories^l, 著者名: `Fred^l, isbn: `123456^lt}); %書棚.put({書名: `Water Buffaloes^l, 著者名: `Fred^l, isbn: `234567^lt}); %書棚.put({書名: `Bedrock Nights^l, 著者名: `Barney^l, isbn: `345678^lt}); }; %request.onsuccess = function() { %書庫 = %request.result; };
次の例は、 ~txを利用して~dbを拡充する。 ◎ The following example populates the database using a transaction.
const %tx = %書庫.transaction(`書棚^l, `readwrite$l);
const %書棚 = %tx.objectStore(`書棚^l);
%書棚.put({書名: `Quarry Memories^l, 著者名: `Fred^l, isbn: `123456^lt});
%書棚.put({書名: `Water Buffaloes^l, 著者名: `Fred^l, isbn: `234567^lt});
%書棚.put({書名: `Bedrock Nights^l, 著者名: `Barney^l, isbn: `345678^lt});
%tx.oncomplete = function() {
/*
すべての要請は成功し,~txは~commitされた。
◎
All requests have succeeded and the transaction has committed.
*/
};
次の例は、 索引を利用して,~db内の単独の本を書名で検索する: ◎ The following example looks up a single book in the database by title using an index.
const %tx = %書庫.transaction(`書棚^l, `readonly$l); const %書棚 = %tx.objectStore(`書棚^l); const %書名索引 = %書棚.index(`書名索引^l); const %request = %書名索引.get(`Bedrock Nights^l); %request.onsuccess = function() { const %matching = %request.result; if (%matching !== undefined) { /* 合致するものが見出された。 ◎ A match was found. */ report(%matching.isbn, %matching.書名, %matching.著者名); } else { /* 合致するものは見出されなかった。 ◎ No match was found. */ report(null); } };
次の例は、 索引と~cursorを利用して,~db内のすべての本から,著者名が合致するものを検索する: ◎ The following example looks up all books in the database by author using an index and a cursor.
const %tx = %書庫.transaction(`書棚^l, `readonly$l); const %書棚 = %tx.objectStore(`書棚^l); const %著者名索引 = %書棚.index(`著者名索引^l); const %request = %著者名索引.openCursor(IDBKeyRange.only(`Fred^l)); %request.onsuccess = function() { const %cursor = %request.result; if (%cursor) { /* 合致する各~recordごとに~callされる。 ◎ Called for each matching record. */ report(%cursor.value.isbn, %cursor.value.書名, %cursor.value.著者名); %cursor.continue(); } else { /* 合致する~recordはもうない。 ◎ No more matching records. */ report(null); } };
要請が失敗したとき~errorを取扱う仕方の一つを、 次の例に示す: ◎ The following example shows one way to handle errors when a request fails.
const %tx = %書庫.transaction(`書棚^l, `readwrite$l); const %書棚 = %tx.objectStore(`書棚^l); const %request = %書棚.put({書名: `Water Buffaloes^l, 著者名: `Slate^l, isbn: `987654^lt}); %request.onerror = function(%event) { /* 索引 `書名索引^l に対する一意性の拘束は失敗した。 ◎ The uniqueness constraint of the "by_title" index failed. */ report(%request.error); /* ~txを中止させたくなければ, %event の `preventDefault()$m を~callすることもできる。 ◎ Could call event.preventDefault() to prevent the transaction from aborting. */ }; %tx.onabort = function() { /* 他の場合、 失敗した要請に因り,~txは自動的に中止されることになる。 ◎ Otherwise the transaction will automatically abort due the failed request. */ report(%tx.error); };
必要なくなったなら、 ~db接続は~closeできる。 ◎ The database connection can be closed when it is no longer needed.
%書庫.close();
~dbは,未来に他の保管庫/索引を包含するように成長させれる。 より古い~versionから移行するときに取扱う仕方の一例を次に示す。 ◎ In the future, the database might have grown to contain other object stores and indexes. The following example shows one way to handle migrating from an older version.
const %request = `indexedDB$m.open(`書庫^l, `3^lt); /* ~version 3 を要請する。 ◎ Request version 3. */ let %書庫; %request.onupgradeneeded = function(%event) { const %書庫 = %request.result; if (%event.oldVersion < `1^lt) { /* ~version 1 が~dbの最初の~version。 ◎ Version 1 is the first version of the database. */ const %書棚 = %書庫.createObjectStore(`書棚^l, {keyPath: `isbn^l}); const %書名索引 = %書棚.createIndex(`書名索引^l, `書名^l, {unique: true}); const %著者名索引 = %書棚.createIndex(`著者名索引^l, `著者名^l); } if (%event.oldVersion < `2^lt) { /* ~version 2 は、 `出版年^l で本を検索できるようにする,新たな索引を導入する。 ◎ Version 2 introduces a new index of books by year. */ const %書棚 = %request.transaction.objectStore(`書棚^l); const %出版年索引 = %書棚.createIndex(`出版年索引^l, `出版年^l); } if (%event.oldVersion < `3^lt) { /* ~version 3 は、 `定期刊行物^l )用に 2 つの索引を伴う新たな保管庫を導入する。 ◎ Version 3 introduces a new object store for magazines with two indexes. */ const %定期刊行物 = %書庫.createObjectStore(`定期刊行物^l); const %出版元索引 = %定期刊行物.createIndex(`出版元索引^l, `出版元^l); const %刊行頻度索引 = %定期刊行物.createIndex(`刊行頻度索引^l, `刊行頻度^l); } }; %request.onsuccess = function() { %書庫 = %request.result; /* %書庫.`version^m は 3 になる。 ◎ db.version will be 3. */ };
複数の~client(~pageと~worker)が、 同じ~dbを同時に利用できる — 互いの読取り/書込みが衝突しないことは、 ~txにより確保される。 新たな~clientが( `upgradeneeded$et ~eventを介して)当の~dbを昇格したいと求めた場合、 他のすべての~clientが その~dbの現在の~versionへの接続を~closeするまでは,それを行えない。 ◎ A single database can be used by multiple clients (pages and workers) simultaneously — transactions ensure they don’t clash while reading and writing. If a new client wants to upgrade the database (via the upgradeneeded event), it cannot do so until all other clients close their connection to the current version of the database.
`versionchange$et ~eventを~listenすれば、 ~clientは,新たな~clientが昇格-時に阻まれるのを避けれる。 これは、 別の~clientが当の~dbを昇格したいと求めているときに発火される。 その昇格を継続できるようにするためには、 `versionchange$et ~eventに対し,この~clientによる~dbへの`接続$が最終的に~closeされるような何かを行って反応する。 ◎ To avoid blocking a new client from upgrading, clients can listen for the versionchange event. This fires when another client is wanting to upgrade the database. To allow this to continue, react to the versionchange event by doing something that ultimately closes this client’s connection to the database.
これを行う仕方の一つは、 ~pageを読込直すことである: ◎ One way of doing this is to reload the page:
%db.onversionchange = function() { /* 先ず、 保存-済みでない~dataを保存する: ◎ First, save any unsaved data: */ saveUnsavedData().then(function() { /* ~pageが利用者からヤリトリされてない場合、 読込直す方が適切になろう。 ◎ If the document isn't being actively used, it could be appropriate to reload the page without the user's interaction. */ if (!document.hasFocus()) { location.reload(); /* 読込直すことで、 ~dbは~closeされ,新たな~JSと~db定義が読込直されることになる。 ◎ Reloading will close the database, and also reload with the new JavaScript and database definitions. */ } else { /* 文書が~focusを得ている場合、 ~pageを読込直すと利用者の妨げになり得るので,手動でそうしてもらうよう利用者に依頼する: ◎ If the document has focus, it can be too disruptive to reload the page. Maybe ask the user to do it manually: */ displayMessage("最新~versionに昇格するため、 この~pageを読込直してください。"); } }); }; function saveUnsavedData() { /* これをどう行うかは、 ~appに依存する。 ◎ How you do this depends on your app. */ } function displayMessage() { /* 利用者に非~modal~messageを示す。 ◎ Show a non-modal message to the user. */ }
もう一つの仕方は、 `接続$の `close()$m ~methodを~callすることである。 しかしながら,当の~dbに~accessしようとする後続な試みは失敗することになるので、 ~appがそれを自覚できるようにしておく必要がある。 ◎ Another way is to call the connection's close() method. However, you need to make sure your app is aware of this, as subsequent attempts to access the database will fail.
%db.onversionchange = function() {
saveUnsavedData().then(function() {
%db.close();
stopUsingTheDatabase();
});
};
function stopUsingTheDatabase() {
/*
~appをそれ以上~dbを利用しない状態に置く。
◎
Put the app into a state where it no longer uses the database.
*/
}
(昇格を試みている)新たな~clientは、 `blocked$et ~eventを利用して,他の~clientが昇格を防止しているかどうか検出できる。 この~eventは、 `versionchange$et ~eventが発火された後も,他の~clientが 依然として~dbへの接続を保持しているときに発火される。 ◎ The new client (the one attempting the upgrade) can use the blocked event to detect if other clients are preventing the upgrade from happening. The blocked event fires if other clients still hold a connection to the database after their versionchange events have fired.
const %request = indexedDB.open("library", 4); /* ~version 4 を要請する。 ◎ Request version 4. */ let %blockedTimeout; %request.onblocked = function() { /* 他の~clientに,~dataを非同期に保存する時間を与える。 ◎ Give the other clients time to save data asynchronously. */ %blockedTimeout = setTimeout(function() { displayMessage("昇格が阻まれています。この~siteを表示している他の~UItabを閉じてください。"); }, 1000); }; %request.onupgradeneeded = function(%event) { clearTimeout(%blockedTimeout); hideMessage(); // ... }; function hideMessage() { /* 以前に表示した~messageを隠す。 ◎ Hide a previously displayed message. */ }
利用者は、 別の~clientが~dbを切断するのに失敗した場合に限り,上の~messageを見ることになる。 利用者がこれを見ることは決してないのが理想的だが。 ◎ The user will only see the above message if another client fails to disconnect from the database. Ideally the user will never see this.
【この訳に特有な表記規約】
( この節の表記規約は、 この仕様が~UAに~~課す要件(〜するモノトスル)を集約するものでもある。 )
◎表記記号この仕様の~APIが定義する各種~interfaceの各~instanceは、 それが表現する抽象-~objと常に一対一に対応するので,同一視される (例: `IDBDatabase$I ~objと,それが表現する`接続$ )。
加えて、 次の記法も用いる:
- %演算( %引数 )?
- ~algoの中で %演算 を呼出す所の末尾に付与される記号 ? は、 その %演算 から例外が投出され得ることを表す (一種の ~Assert )。
- %O↗ ( %O の `~access先@ )
- ~APIに公開される一部の型の~objは、 ある型の抽象-~objへの~accessを間接的に供するものとして定義される (具体的には、 次項 “`専属する$” の図式に示される)。 %O がそのような型の~instanceであるとき、 %O を通して~accessされる抽象-~objは, %O↗ とも記される。 %O から %O↗ への対応関係は、 一般に多対一になることに注意。 また、 %O に対する %O↗ が別の~instanceに変わることは,決してない。
- %O は、 ある時点を過ぎて以降, %O↗ に~accessできなくなることもある — %O↗ が %O よりも先に破壊された / %O↗ への~accessが “~closeされた” ときなど。 そうなったとしても、 %O↗ が有する~propを反映するような, %O が有する~IDL属性には、 その `値を保持し続ける@ とされるものもある。 そのような属性は、[ %O↗ を~access先とする別の~objを通して %O↗ に変更が加えられた ]としても,元の属性~値を保つ。
- `専属する@
-
一部の型の~obj間には、 “専属する” という語で,その結び付けの関係が表記される。 ある型 %A の~instance %a が,別の型 %B の~instance %b に`専属する$という関係には、 一般に,次が含意される:
- %a は、 自身が存在し続ける限り, %b 以外の型 %B の~instanceには`専属しない$。
- %a が存在し続ける限り, %b も存在し続ける ( %b が破壊される時点で, %a も破壊される)。 【! ( %a は %b への強い参照を有する) 】
ある~instanceに`専属する$ような~instanceは,一般に複数 存在し得る。
- この専属するという関係は,同じ型の~instance間で定義されたり, 循環することは決してないので、 推移的に拡張して利用される。 例えば %b が また別の型 %C の~instance %c に`専属する$とき、 “%a が`専属する$ %C ~obj” という記述は、 %c を指すことになる。
-
次の図式に、 この関係がある, および 上述の~accessを供する関係があるような,各種~objを要約する:
- 上向き矢印 “↑” を挟んだ下の~objが,上の~objに`専属する$。
- 斜め矢印 “↗” を挟んだ右の~objが,左の~objを通して~accessされる。
【! JS Realm? 】 【! ↗ 】 `~storage~key$ 【! ↑ 】 ↑ `接続$( `IDBDatabase$I ) ↗ `~db$ ↑ `~tx$( `IDBTransaction$I ) ↑ ↑ `保管庫~handle$( `IDBObjectStore$I ) ↗ `保管庫$ ↑ ↑ `索引~handle$( `IDBIndex$I ) ↗ `索引$ -
これらの型の~obj~instanceたちは、 常に,次の可換性と一意性の要件を満たすモノトスル:
- `可換性@
-
上の図式は`可換@https://ja.wikipedia.org/wiki/%E5%8F%AF%E6%8F%9B%E5%9B%B3%E5%BC%8F$になる。 すなわち:
- どの`保管庫~handle$ %H に対しても ⇒ ( %H が`専属する$`接続$ ) ↗ ~EQ ( %H↗ が`専属する$`~db$ )
- どの`索引~handle$ %H に対しても ⇒ ( %H が`専属する$`保管庫~handle$ ) ↗ ~EQ ( %H↗ が`専属する$`保管庫$ )
- `一意性@
- 2 つの`保管庫~handle$(または 2 つの`索引~handle$) %H1, %H2 が与えられたとき ⇒ [ %H1↗, %H2↗ は,同じ~instanceに`専属する$ ]~AND[ %H1↗ ~EQ %H2↗ ]ならば, %H1 ~EQ %H2 になる。
この要件の目的においては、 %H↗, %H1↗, %H2↗ は、 破壊されて以降も,他と区別できる個としては(何ら~accessできる実体はないが)存在し続けるとする。
- 所与の型の~obj~instanceが[ 作成される/取得される ]ときに[ どの~instanceに`専属する$, あるいは どの~instanceを`~access先$にする ]ようにされるか,については、 上述の要件を満たすように,当の~objを[ 作成する/取得する ]~APIの記述にて定義される。
- ε
- 存在しないことを表現する特別な定数 (`詳細@index.html#epsilon$)。 ~API~methodに渡された引数がとる値 ε は、 その~methodの呼出時に,引数が省略されたことを表す (`詳細@index.html#missing-arg$)。
2. 各種~構成子
`名前@ は、 `DOMString$I に等価な `String$jT【!string】 である。 すなわち、 空~文字列も含め,任意の長さの任意の~16-bit符号単位~列になり得る。 `名前$は常に不透明な~16-bit符号単位~列として比較される。 ◎ A name is a string equivalent to a DOMString; that is, an arbitrary sequence of 16-bit code units of any length, including the empty string. Names are always compared as opaque sequences of 16-bit code units.
注記: その~~結果,`名前$の比較では、 文字大小のみならず,~Unicode~textにおける他の小さな差異 — 正規化形, 制御文字の有無, その他 — も区別される。 `Charmod-Norm$r ◎ NOTE: As a result, name comparison is sensitive to variations in case as well as other minor variations such as normalization form, the inclusion or omission of controls, and other variations in Unicode text. [Charmod-Norm]
利用する~storageの仕組みの下では~supportされない名前に対しては、 実装は,~escapingに類する仕組みを利用して 格納できる名前に対応付けれる。 ◎ If an implementation uses a storage mechanism which does not support arbitrary strings, the implementation can use an escaping mechanism or something similar to map the provided name to a string that it can store.
`~sort済み名前~listを作成する@ ときは、 所与の ( `~list$ %名前~群 ) に対し: ◎ To create a sorted name list from a list names, run these steps:
- %~sort済み ~LET `~listを昇順に~sortする$( %名前~群, ~LT`符号単位$sub ) ◎ Let sorted be names sorted in ascending order with the code unit less than algorithm.
- ~RET %~sort済み が結付けられた新たな `DOMStringList$I ~obj ◎ Return a new DOMStringList associated with sorted.
注記: 【! details 】 これは、 `String$jT たちが成す `Array$jT ~objの `sort()@~TC39M/indexed-collections.html#sec-array.prototype.sort$c ~methodに合致する。 この順序付けは、 各~文字列~内の~16-bit符号単位どうしを比較するための[ 高効率で, 一貫した, 決定的な,~sort順序 ]を与える。 この~sortは、 ~alphabet順その他 どの字句的~順序にも — 特に,代用対で表現される符号位置に対しては — 合致しない。 ◎ Details ◎ This matches the sort() method on an Array of String. This ordering compares the 16-bit code units in each string, producing a highly efficient, consistent, and deterministic sort order. The resulting list will not match any particular alphabet or lexicographical order, particularly for code points represented by a surrogate pair.
2.1. ~db
各 `~storage~key$には、 0 個~以上の`~db$が結付けられる — `~db$は,その`~storage~key$に`専属する$。
【 過去にどの~dbを作成したか調べたいときは、 `IDBFactory$I の `databases()^m ~methodを利用できる。 】
各 `~db@ は,自身に格納される~dataを保持する, 0 個~以上の`保管庫$からなる。 各`~db$ %~db は、 次に挙げるものを有する:
◎ Each storage key has an associated set of databases. A database has zero or more object stores which hold the data stored in the database.- `名前@db ◎ A database has a name\
- 特定の`~storage~key$の中で, %~db を一意に識別する`名前$であり、 %~db が存続する間 変化しない。 ◎ which identifies it within a specific storage key. The name is a name, and stays constant for the lifetime of the database.
- `~version@db ◎ A database has a version.\
- %~db の~versionを表現する負でない整数。 %~db 作成-時の`~version$dbは, 0 である。 ◎ When a database is first created, its version is 0 (zero).
- 【 %~db の作成-時には,自動的に`昇格~tx$が生じるので、 実質的には 1 (以上)として公開される(そのときに~errorが生じない限り)。 】
- 注記: `~db$が同時に有し得る~versionは一つだけである — 同時に複数の~versionを有する~dbは存在し得ない。 ~versionは、 `昇格~tx$を通してのみ変更し得る。 ◎ NOTE: 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.
- `昇格~tx@db ◎ A database has at most one associated upgrade transaction,\
- `昇格~tx$または ε (存在しない) — 初期~時は ε とする。 ◎ which is either null or an upgrade transaction, and is initially null.
- 【 所与の時点で`~db$に生じている`昇格~tx$を指す。 そのような~txは,あっても一つに限られ、 この`~db$を`~access先$とする,ある`接続$に`専属する$。 】
2.1.1. ~db接続
~scriptが`~db$と直にヤリトリすることはない。 代わりに `接続@ ( `connection^en )を介して間接的に~accessする。 `接続$を利用すれば,`~db$の~objたちを操作できる。 それはまた、 その`~db$用の`~tx$を得する唯一の仕方である ◎ 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.
【 この訳では、 `接続$ %接続 の`~access先$の`~db$を %接続↗ とも記す。 】
`接続$は,`~db$を~openすることにより作成される。 所与の`~db$を`~access先$とする,複数の`接続$が同時にあってもヨイ。 ◎ The act of opening a database creates a connection. There may be multiple connections to a given database at any given time.
`接続$が~accessできる`~db$は、 その接続を~openした大域~scopeの`~storage~key$に`専属する$ものに限られる。 ◎ A connection can only access databases associated with the storage key of the global scope from which the connection is opened.
注記: これは、 `Document$I の `domain$m が変更されても影響されない。 ◎ NOTE: This is not affected by changes to the Document's domain.
各 `接続$ %接続 には、 次に挙げるものが結付けられる (括弧内は、 `接続$を表現する `IDBDatabase!I ~interfaceの,対応する~member): ◎ ↓
- `~version@Cn ( `version$m ) ◎ A connection has a version,\
- 作成-時に設定され、 それ以降,変化しない。 ただし,`昇格~txが中止-$された場合、 %接続↗ である`~db$は,その元の~versionに戻される。 %接続 が`~close$されて以降は変化しない。 ◎ which is set when the connection is created. It remains constant for the lifetime of the connection unless an upgrade is aborted, in which case it is set to the previous version of the database. Once the connection is closed the version does not change.
- 【 より詳細には、 %接続↗ の`昇格~tx$dbが`完遂-$して以降は変化しない。 】
- `状態@Cn ◎ Each connection has a close pending flag\
- %接続 の`状態$Cnは[ `~open中@i → `~close待ち@i → `~close済み@i ]の順に推移する。 後戻りすることはない。 ◎ which is initially false.
- 【 この “状態” は,原文では “`close pending flag^en(~close待ちか)” という(上の `~open中$i と `~close待ち$i を区別する)真偽値で表現されているが、 原文の語 “`open^en”, “`close pending^en”, “`closed^en” と状態遷移との対応関係を明瞭にするため,この訳では上のような定義に代えている ( “後戻りしない” もこの訳による補完)。 】
-
状態が `~close済み$i になった %接続 は ~closeされた ともいう (そのようにする試みを~closeするという)。 %接続 は、 次のときに,`~close$され得る/させれる: ◎ When a connection is initially created it is in an opened state. The connection can be closed through several means.\
- %接続 は、 それを作成した実行~文脈が破壊された場合には (例えば、 利用者が別~pageへ~~移動したことに因り), `~close$される。 ◎ If the execution context where the connection was created is destroyed (for example due to the user navigating away from that page), the connection is closed.\
- `~db接続を~closeする$手続きを利用すれば、 %接続 を明示的に`~close$させれる。 ◎ The connection can also be closed explicitly using the steps to close a database connection. When the connection is closed its close pending flag is always set to true if it hasn’t already been.
- %接続 は、 例外的な状況下でも~UAにより~closeされてよい/され得る — 例えば、 ~file~systemへの~accessを失ったか, ~access許可が変更されたとき,あるいは当の`~storage~key$に対する~storageが~clearされたことに因り。 これが生じた場合、 ~UAは次を走らすモノトスル ⇒ `~db接続を~closeする$( %接続, `強制する^i ) ◎ A connection may be closed by a user agent in exceptional circumstances, for example due to loss of access to the file system, a permission change, or clearing of the storage key's storage. If this occurs the user agent must run close a database connection with the connection and with the forced flag set to true.
- `保管庫~集合@Cn ( `objectStoreNames$m ) ◎ A connection has an object store set,\
- %接続 の作成-時に, %接続↗ に`専属する$`保管庫$たちが成す集合に初期化される。 この集合の内容は、 %接続↗ の`昇格~tx$dbが`生きて$いる間を除いて,一定であり続ける。 ◎ 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 live.
`接続$の`親~targetを取得する$~algoは、 ~NULL を返す。 ◎ A connection's get the parent algorithm returns null.
`versionchange@et ~eventは、 `~db$を昇格する/削除するよう試みたとき,その~dbを~openしている各 `接続$ (それを試みている当の`接続$は除く) に向けて発火される。 これは、 昇格/削除-を続行できるようにするために,`接続$を~closeする機会を与える。 ◎ An event with type versionchange will be fired at an open connection if an attempt is made to upgrade or delete the database. This gives the connection the opportunity to close to allow the upgrade or delete to proceed.
`close@et ~eventは、 `接続$が異常に~closeされたとき,当の接続に向けて発火される。 ◎ An event with type close will be fired at a connection if the connection is closed abnormally.
2.2. 保管庫
`保管庫@ ( `object store^en )が、 `~db$に~dataを格納するための,首な~storageの仕組みである。 ◎ An object store is the primary storage mechanism for storing data in a database.
どの`保管庫$も,ある`~db$に`専属する$。 `~db$に専属する`保管庫$たちが成す集合は、 `昇格~tx$を利用することを通して — すなわち,`upgradeneeded$et ~eventに呼応して — のみ変更できる。 新たな~dbが作成された時点では,それに`専属する$`保管庫$はない。 ◎ Each database has a set of object stores. The set of object 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.
各 `保管庫$ %保管庫 は、 次に挙げるものを有する (括弧内は、 保管庫を`~access先$とする `IDBObjectStore!I ~objの対応する~member): ◎ ↓
- `~record~list@Os ◎ An object store has a list of records\
- %保管庫 内に格納される`~record$たちが成す~listを保持する。 ~list内の`~record$どうしは、 それらの`~key$の`昇順$に~sortされる。 同じ保管庫~内で,複数の~recordの`~key$が`等しく$なることは、 決してない。 ◎ 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.
- `名前@Os ( `name$m ) ◎ An object store has a name,\
- `名前$。 この名前は、 どの時点においても, %保管庫 が`専属する$`~db$に`専属する$`保管庫$たちにわたって一意になる。 ◎ which is a name. At any one time, the name is unique within the database to which it belongs.
- `~key~path@Os ( `keyPath$m ) ◎ An object store optionally has a key path.\
- `妥当な~key~path$, または ε 。 %保管庫 の作成-時に設定され、 それ以降( ε かどうかも含め),変化しない。 ◎ ↓
- `~key~path$Osが[ 非 ε / ε ]であることは、 `~record$の`~key$として,`~record$の`値$の[ 内にある/外から与えられた ]それを利用すること ( `use in-line keys^en† / `use out-of-line keys^en† ) を意味する。 ◎ 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.
- 【† この訳では、 これらの用語は利用せず,単に[ 非 ε / ε ]で区別する。 】
- 【 索引の`~key~path$Ixと違って、 `保管庫$の~key~pathは,空~文字列をとり得ない。 また、 `~key生成器$を有する場合は,文字列たちが成す~listもとり得ない。 】
- 【 `~key~path$Os %P ~NEQ ε の場合、 %保管庫 の`~record~list$Osは,それを成すどの`~record$ %R も[ %R の`~key$ ~EQ~cmpkey `値から~keyを抽出する$( %R の`値$, %P ) ]を満たすように拘束される。 】
- `~key生成器$ ◎ An object store optionally has a key generator.
- %保管庫 が~key生成器を有するかどうか( `autoIncrement$m )は、 %保管庫 の作成-時に設定され,それ以降は変化しない。 ◎ ↓
`保管庫$を成す~recordの`~key$は、 次に挙げるいずれかの~sourceから導出され得る。 ◎ An object store can derive a key for a record from one of three sources:
【 すなわち,`~record~list$Osは、 外部から与えられる一連の値から,一連の[ ~record{ 導出された~key : 値 } ]で拡充される。 】
- ~keyが必要になる度に,単調に増加する番号による~keyを`~key生成器$から自動的に生成する。 ◎ A key generator. A key generator generates a monotonically increasing numbers every time a key is needed.
- 所与の値から,`~key~path$Osを用いて`~keyを抽出-$する。 ◎ Keys can be derived via a key path.
- 保管庫に値を格納するときに,明示的に 【すなわち,格納-用の~API~methodの引数にて】 ~keyを指定する。 ◎ Keys can also be explicitly specified when a value is stored in the object store.
2.2.1. 保管庫~handle
~scriptが`保管庫$と直にヤリトリすることはない。 代わりに,ある`~tx$の中で `保管庫~handle@ を介して間接的に~accessする。 ◎ Script does not interact with object stores directly. Instead, within a transaction, script has indirect access via an object store handle.
各 `保管庫~handle$ %H には、 次に挙げるものが結付けられる (括弧内は、 対応する `IDBObjectStore!I ~interface~member): ◎ ↓
- `保管庫@OsH ◎ An object store handle has an associated object store\
- %H の`~access先$とされる`保管庫$。 【この訳では、もっぱら %H↗ と記す。】 ◎ ↑↑
- `~tx@OsH ( `transaction$m ) ◎ and an associated transaction.\
- %H が`専属する$`~tx$。 【この訳では、この用語は利用せず,単にこのように記す。】 ◎ ↑↑
- %H の[ 取得-時/作成-時 ]に,`可換性$と`一意性$の要件が満たされるように設定される。 ◎ Multiple handles may be associated with the same object store in different transactions, but there must be only one object store handle associated with a particular object store within a transaction.
- `索引~集合@OsH ( `indexNames$m ) ◎ An object store handle has an index set,\
- %H の作成-時に,[ %H↗ に`専属する$`索引$たちからなる集合 ]に初期化される。 ◎ which is initialized to the set of indexes that reference the associated object store when the object store handle is created.\
- この集合の内容は、 %H が`専属する$~txが[ `昇格~tx$であって, `生きて$いる間 ]を除いて,一定であり続ける。 ◎ The contents of the set will remain constant except when an upgrade transaction is live.
- `名前@OsH ( `name$m ) ◎ An object store handle has a name,\
- %H の作成-時に %H↗ の`名前$Osに初期化される。 ◎ which is initialized to the name of the associated object store when the object store handle is created.\
- この名前は、 %H が`専属する$~txが[ `昇格~tx$であって, `生きて$いる間 ]を除いて,一定であり続ける。 ◎ The name will remain constant except when an upgrade transaction is live.
2.X. ~record
[ `保管庫$の`~record~list$Os / `索引$の`~record~list$Ix ]内に格納される各 `~record@ は、 以下の節に述べる[ `~key$, および`値$ ]からなる。
所与の ( %~key, %値 ) を ( `~key$, `値$ ) とする`~record$は、 { %~key : %値 } とも表記される。
【 この用語は,原文では保管庫のそれと索引のそれとで区別して定義されているが、 それらの総称を表す箇所も多いため,この訳では総称として定義する。 】
2.3. 値
各`~record$には `値@ が結付けられる。 ~UAは、 `直列化-可能$な どの~objも~supportするモノトスル†。 これには、 少なくとも次に挙げるものが含まれる ⇒# `String$jT などの単純~型の~primitive値, `Date$jT, `Object$jT, `Array$jT, `File$I, `Blob$I, `ImageData$I, 等々 ◎ Each record is associated with a value. User agents must support any serializable object. 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$に限られる。 `索引$内の`~record$の`値$は、 常に その`参照先~record$の`~key$として与えられるので。 】
~recordの`値$は、 参照~渡しではなく,値~渡しにより[ 格納される/検索取得される ]。 [ 格納-時に渡した/検索取得して得られた ]値が後で変更されても、 ~db内に格納されている~recordには影響しない。 ◎ 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.
~recordの`値$は、 `StructuredSerializeForStorage$jA 演算から出力される`~Record$である。 ◎ Record values are Records output by the StructuredSerializeForStorage operation.
2.4. ~key
索引付き~db内に格納されている`~record$たちを効率的に検索取得するため、 `~record$たちは,各自の `~key@ に則って組織化される。 ◎ In order to efficiently retrieve records stored in an indexed database, each record is organized according to its key.
各 `~key$には、 次に挙げるものが結付けられる ◎ ↓
- `型@key ◎ A key has an associated type\
- `number@i / `date@i / `string@i / `binary@i / `array@i ◎ which is one of: number, date, string, binary, or array.
- `値@key ◎ A key also has an associated value,\
-
~keyの`型$keyに応じて,次に挙げる型の値をとる:
- `number$i / `date$i ⇒ `unrestricted double$I
- `string$i ⇒ `DOMString$I
- `binary$i ⇒ `~byte列$
- `array$i ⇒ 0 個以上の他の`~key$( `array$i 型も含む)たちが成す`~list$
~ES `ECMA-262$r 値は、 `値を~keyに変換する$手続きに従って`~key$に変換される。 ◎ An ECMAScript [ECMA-262] value can be converted to a key by following the steps to convert a value to a key.
次に挙げる~ES型が,~keyとして妥当になる: ◎ NOTE: The following ECMAScript types are valid keys:
- `NaN^jv 以外の `Number$jT ~primitive値。 `Infinity^jv, `-Infinity^jv も含まれる。 ◎ Number primitive values, except NaN. This includes Infinity and -Infinity.
- `Date$jT ~objであって,その `DateValue^sl 内部~slotは `NaN^jv でないもの。 ◎ Date objects, except where the [[DateValue]] internal slot is NaN.
- `String$jT ~primitive値。 ◎ String primitive values.
- 各種`~buffer~source型$の~obj ( `ArrayBuffer$I, あるいは `Uint8Array$I などの~buffer~view)。 ◎ ArrayBuffer objects (or views on buffers such as Uint8Array).
- `Array$jT ~objであって、[ 配列~内の どの~itemも定義されていて,~keyとして妥当である ], かつ[ (直接的にも間接的にも)自身を包含していない ]もの。 特に,空な配列は妥当である。 配列は,他の配列を包含し得る。 ◎ Array objects, where every item is defined, is itself a valid key, and does not directly or indirectly contain itself. This includes empty arrays. Arrays can contain other arrays.
他の~ES値を`~key$に変換しようと試みても失敗することになる。 ◎ Attempting to convert other ECMAScript values to a key will fail.
`array$i `型$keyの`~key$を特に `配列~key@ という。 `配列~key$の`値$keyを成す各`~item$を `下位key@ という。 ◎ An array key is a key with type array. The subkeys of an array key are the items of the array key's value.
2 つの`~key$ %a, %b を比較する関数 `Compare@( %a, %b ) は、 次で定義される: ◎ To compare two keys a and b, run these steps:
-
`~key$の`型$keyどうしの大小関係を[ `number$i ~LT `date$i ~LT `string$i ~LT `binary$i ~LT `array$i ]と定義する下で:
- ~IF [ %a の`型$key ~GT %b の`型$key ] ⇒ ~RET 1
- ~IF [ %a の`型$key ~LT %b の`型$key ] ⇒ ~RET −1
- %va ~LET %a の`値$key ◎ Let va be the value of a.
- %vb ~LET %b の`値$key ◎ Let vb be the value of b.
-
%a の`型$keyに応じて: ◎ Switch on ta:
- `number$i
- `date$i
-
- ~IF[ %va ~GT %vb ] ⇒ ~RET 1 ◎ If va is greater than vb, then return 1.
- ~IF[ %va ~LT %vb ] ⇒ ~RET −1 ◎ If va is less than vb, then return -1.
- ~RET 0 ◎ Return 0.
- `string$i
-
- ~IF[ %va は %vb `未満の符号単位~列$である ] ⇒ ~RET −1 ◎ If va is code unit less than vb, then return -1.
- ~IF[ %vb は %va `未満の符号単位~列$である ] ⇒ ~RET 1 ◎ If vb is code unit less than va, then return 1.
- ~RET 0 ◎ Return 0.
- `binary$i
-
- ~IF[ %va は %vb `未満の~byte列$である ] ⇒ ~RET −1 ◎ If va is byte less than vb, then return -1.
- ~IF[ %vb は %va `未満の~byte列$である ] ⇒ ~RET 1 ◎ If vb is byte less than va, then return 1.
- ~RET 0 ◎ Return 0.
- `array$i
-
-
~EACH( 整数 %i ~IN { 0 〜 min( %va の`~size$, %vb の`~size$ ) ~MINUS 1 } ) に対し,昇順に ◎ Let length be the lesser of va’s size and vb’s size. ◎ Let i be 0. ◎ While i is less than length, then:
- %c ~LET `Compare$( %va[ %i ], %vb[ %i ] ) ◎ Let c be the result of recursively comparing two keys with va[i] and vb[i].
- ~IF[ %c ~NEQ 0 ] ⇒ ~RET %c ◎ If c is not 0, return c. ◎ Increase i by 1.
- ~IF[ %va の`~size$ ~GT %vb の`~size$ ] ⇒ ~RET 1 ◎ If va’s size is greater than vb’s size, then return 1.
- ~IF[ %va の`~size$ ~LT %vb の`~size$ ] ⇒ ~RET −1 ◎ If va’s size is less than vb’s size, then return -1.
- ~RET 0 ◎ Return 0.
-
2 つの`~key$ %a, %b の大小関係は、 `Compare$( %a, %b ) の結果に応じて: ◎ ↓
- 1 ならば ⇒ %a は %b `より大きい@ とされる。 ◎ The key a is greater than the key b if the result of comparing two keys with a and b is 1.
- −1 ならば ⇒ %a は %b `より小さい@ とされる。 ◎ The key a is less than the key b if the result of comparing two keys with a and b is -1.
- 0 ならば ⇒ %a は %b に `等しい@ とされる。 ◎ The key a is equal to the key b if the result of comparing two keys with a and b is 0.
注記: 上の規則の結果として、 `-Infinity^jv が, `~key$がとり得る最小な値になる。 【! Number keys are less than ... ↑】 `~key$がとり得る最大な値は無い — いかなる`配列~key$に対しても、 その末尾に新たな`~key$を付加した結果の配列は,より大きくなるので。 ◎ NOTE: As a result of the above rules, negative infinity is the lowest possible value for a key. Number keys are less than date keys. Date keys are less than string keys. String keys are less than binary keys. Binary keys are less than array keys. There is no highest possible key value. This is because an array of any candidate highest key followed by another key is even higher.
注記: `binary$i 型の`~key$を成す各`~byte$は、 無符号~値(範囲 { 0 〜 255 } )として比較される — 有符号~値(範囲 { −128 〜 127 })ではなく。 ◎ NOTE: Members of binary keys are compared as unsigned byte values (in the range 0 to 255 inclusive) rather than signed byte values (in the range -128 to 127 inclusive).
この訳では、 表記 “%関係記号key” を用いて、 次を表すことにする:
- 2 つの`~key$ %a, %b の比較( `Compare$ )
- 2 つの`~key$~pair %p ~EQ ( %a1, %a2 ), %q ~EQ ( %b1, %b2 ) の比較†
- `~key$ %k が`~key範囲$ %R に`入る$かどうか
- `~key$ %k が`~key$たちが成す集合 %K に含まれるかどうか
表記 | 定義 |
---|---|
%a ~GT~cmpkey %b | %a は %b `より大きい$ |
%a ~LT~cmpkey %b | %a は %b `より小さい$ |
%a ~EQ~cmpkey %b | %a は %b に`等しい$ |
%a ~GTE~cmpkey %b | [ %a ~GT~cmpkey %b ]~OR[ %a ~EQ~cmpkey %b ] |
%a ~LTE~cmpkey %b | [ %a ~LT~cmpkey %b ]~OR[ %a ~EQ~cmpkey %b ] |
%p ~GT~cmpkey %q | [ %a1 ~GT~cmpkey %b1 ]~OR[[ %a1 ~EQ~cmpkey %b1 ]~AND[ %a2 ~GT~cmpkey %b2 ]] |
%p ~LT~cmpkey %q | [ %a1 ~LT~cmpkey %b1 ]~OR[[ %a1 ~EQ~cmpkey %b1 ]~AND[ %a2 ~LT~cmpkey %b2 ]] |
%p ~EQ~cmpkey %q | [ %a1 ~EQ~cmpkey %b1 ]~AND[ %a2 ~EQ~cmpkey %b2 ] |
%p ~GTE~cmpkey %q | [ %p ~GT~cmpkey %q ]~OR[ %p ~EQ~cmpkey %q ] |
%p ~LTE~cmpkey %q | [ %p ~LT~cmpkey %q ]~OR[ %p ~EQ~cmpkey %q ] |
%k ~IN~cmpkey %R | %k は %R に`入る$ |
%k ~NIN~cmpkey %R | %k ~IN~cmpkey %R の否定 |
%k ~IN~cmpkey %K | ある %key ~IN %K に対し, %k ~EQ~cmpkey %key |
%k ~NIN~cmpkey %K | %k ~IN~cmpkey %K の否定 |
† `~key$~pairの比較は、 簡潔に記すための,この訳による追加的な定義であり、 もっぱら,`索引$の~record (または,[ それを意図して, あるいは それとの比較を意図して ]与えられる~key値~pair) を比較するときに用いられる。
2.5. ~key~path
`~key~path@ は文字列,または文字列たちが成す~listであり、 `値$から`~key$を抽出する方法を定義する。 次に挙げるものが `妥当な~key~path@ とされる: ◎ A key path is a string or list of strings that defines how to extract a key from a value. A valid key path is one of:
- 空~文字列 ◎ An empty string.
- `識別子@ — すなわち,~ESの `IdentifierName$jT 生成規則に合致する文字列 ◎ An identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].
- 複数個の`識別子$を `002E^U (`.^l) で分離して~~連結して得られる,文字列 ◎ A string consisting of two or more identifiers separated by periods (U+002E FULL STOP).
- 上の要件に適合する文字列のみを包含するような,空でない~list ◎ A non-empty list containing only strings conforming to the above requirements.
注記: ~key~pathの中では space は許容されない。 ◎ NOTE: Spaces are not allowed within a key path.
`~key~path$で~accessできる部位は、 `StructuredSerializeForStorage$jA により明示的に複製される~propに限られる — 次に挙げる各種~型に特有な~propも含まれる: ◎ Key path values can only be accessed from properties explicitly copied by StructuredSerializeForStorage, as well as the following type-specific properties:
型 ◎ Type | ~prop ◎ Properties |
---|---|
`Blob$I | `size^m, `type^m |
`File$I | `name^m, `lastModified^m |
`Array$jT | `length^js |
`String$jT | `length^js |
【 `File^I に対しては、 `Blob^I を継承するので,上に挙げた `Blob^I の~propも含まれることになる。 】
【補記:】
`~key~path$は、 ~~任意に与えられる値( ~obj )の中のある一定の部位を表現する。 その目的は、 外から与える一連の値で,`保管庫$を`拡充する^emとき — すなわち,値を`保管庫$の`~record~list$Osの中に`~record$の`値$として格納するとき — に、 それらの値の中の[ ~key~pathが指す部位に与えられている~data ]から,自動的に`~key$を導出することである。 あるいは、 `索引$を,それが`専属する$`保管庫$の`~record~list$Osに基づいて拡充するときにも、 同様に利用される。 例えば:
- 文字列による~key~path `a.b^l は、 任意の値 ~varV に対し, `~varV.a.b^jv で~accessされる部位を表す (文字列の中の各 `002E^U (`.^l) が階層を辿る~pathの分離子を表す)。 ~varV ~EQ `{ a: { b: "c" }}^jv であれば、 この~key~pathは,`~key$として `c^l を抽出する。 [ `~varV.a.b^jv に~accessし得ない場合 (例: `~varV.a^jv は~objでない)/ `~varV.a.b^jv の値が~keyとして妥当でない場合 (例: `undefined^jv ) ]、 ~varV からは~keyは抽出されないことになる — これらの事例は、 この仕様では[ 前者は `失敗^i( `failure^en )/ 後者は `妥当でない^i( `invalid^en ) ]という定数で表現されている。
- 空~文字列も~key~pathとして妥当であり、 それが指す部位は,値が何であろうと値~全体になる (この~key~pathは`保管庫$には許容されないが)。 すなわち、 抽出される~keyは,常に値そのものになる。
- 文字列たちが成す~listによる~key~pathが指す部位は、 その中の[ ~key~pathとしての各 文字列が指すが部位 ]からなる配列になる。 例えば~key~path « `a.b^l, `x.y.z^l » は、 値 ~varV から,`配列~key$ `[ ~varV.a.b, ~varV.x.y.z ]^jv を~keyとして抽出する。
2.6. 索引
`~key$以外の手段を通して,`保管庫$内の`~record$たちを検索取得できると有用になることもときどきある。 `索引@ ( `index^en )により、 `保管庫$内の`~record$たちを,それらの`値$の~propを通して検索できるようになる。 ◎ 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.
索引は、 ある~~目的に特化された`~record$たちからなる持続的な~storageであり、 その~dataは,以下に述べるように 索引が`専属する$`保管庫$の~dataに基いて拡充される。 各 索引は、 次に挙げるものを有する (括弧内は、 索引を`~access先$とする `IDBIndex!I ~objの対応する~member ): ◎ 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.
- `参照先の保管庫@ ◎ ↑
- 索引が`専属する$`保管庫$。 【この訳では、この用語は利用せず,単にこのように記す。】 索引の作成-時に設定される。 以下の各項では、 単に %保管庫 と記す。 ◎ ↑↑
- `~record~list@Ix ◎ ↓
-
[ 索引に格納される~dataを保持する`~record$ ]たちが成す~list。 この~listは、 %保管庫 の`~record~list$Os %L から自動的に拡充される:
- 索引の作成-時に, %L に基づいて自動的に拡充される。
- %L [ に~recordが挿入される / から~recordが削除される / の~recordの`値$が更新される ]度に,自動的に拡充される。
%L に変更が加えられる度に, %保管庫 に`専属する$すべての索引は更新されることになる。
【 どのような規則に基づいて更新されるかの詳細は、 `§ 索引の拡充-法@#_populating-an-index$に述べる。 】
◎ ↑↓ - `~key~path@Ix ( `keyPath$m ) ◎ ↓
-
`~key~path$。
索引~内のどの~record %R1 についても:
-
%R1 の`値$は %保管庫 内のある~record %R の`~key$で与えられる。
【 したがって,`保管庫$における`~key$の一意性から、 索引の`~record~list$Ix から %保管庫 の`~record~list$Os %L へは,次の対応関係がある ⇒ %R1 → %R ~EQ [ %R1 の`値$を`~key$とする %L 内の~record ]
この訳では、 この %R を指して %R1 の `参照先~record@ と称する。 】
- %R1 の`~key$は[ %R の`値$の中の,この`~key~path$Ixが指す部位 ]から`抽出される~key$(たちのいずれか)で与えられる。
索引の`~record~list$Ixは,そのように %R から導出される %R1 たちで拡充される。
◎ 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. -
-
例えば, %R ~EQ { `123^c : `{ name: "Alice", title: "CEO" }^c } で,索引の`~key~path$Ixが `name^l ならば、 ~key `Alice^l が抽出され,索引は %R1 ~EQ{ `Alice^l : `123^c } を包含することになる。 ◎ For example, if an index’s referenced object store contains a record with the key 123 and the value { name: "Alice", title: "CEO" }, and the index’s key path is "name" then the index would contain a record with the key "Alice" and the value 123.
上述の %R (すなわち, %R1 の`参照先~record$)の`値$は、 %R1 の `参照先の値@ と呼ばれる。 【この訳では、この用語は利用せず,単に`参照先~record$の値と記す。】 ◎ 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.
先の例の %R1 ~EQ{ `Alice^l : `123^c } の`参照先~record$の値は, `{ name: "Alice", title: "CEO" }^c になる。 ◎ In the preceding example, the record in the index with key "Alice" and value 123 would have a referenced value of { name: "Alice", title: "CEO" }.
注記: 【この段落の内容は、`§ 索引の拡充-法@#_populating-an-index$に移譲。】 ◎ NOTE: 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.
索引~内の`~record$たちは、 常にその~keyに則って~sortされる。 保管庫と違い、 索引は,同じ~keyを伴う複数の~recordを包含し得るので、 それらの~recordは更に,それらの`値$(すなわち,`参照先~record$の~key)に則って~sortされる。 ◎ 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).
- `名前@Ix ( `name$m ) ◎ An index has a name,\
- `名前$。 この名前は、 どの時点においても,同じ`保管庫$に`専属する$索引たちにわたって一意になる。 ◎ which is a name. At any one time, the name is unique within index’s referenced object store.
- `一意か@Ix ( `unique$m ) ◎ An index has a unique flag.\
- 真偽値。 ~T にされた下では、 索引の~record~listは[ 索引~内のどの 2 つの`~record$も同じ~keyを有さない ]条件の下で拡充される。 索引が`専属する$`保管庫$にて[ `~record$を 挿入する/改変する ]ような試みは、[ 索引の`~key~path$Ixを用いて その~recordの値から`抽出される~key$(たちのいずれか) ]が[ 索引~内のある~recordの~key ]と同じになる(`等しい$)ならば,失敗する。 ◎ When 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.
- 【 新たな`索引$を作成する試みも,この条件を満たせないときは同様に失敗する。 この場合の取扱いは `IDBObjectStore.createIndex()$m にて述べられる。 】
- `複-~entryか@Ix ( `multiEntry$m ) ◎ An index has a multiEntry flag.\
-
真偽値。 これは、 索引の`~key~path$Ixが指す( %保管庫 に追加された`~record$の)部位が配列であるとき,索引がどう挙動するかに影響する: ◎ This flag affects how the index behaves when the result of evaluating the index’s key path yields an array key.\
- ~F の場合 ⇒ 索引には,その配列をそのまま`配列~key$とするような,単独の`~record$が追加される。 ◎ If its multiEntry flag is false, then a single record whose key is an array key is added to the index.\
- ~T の場合 ⇒ 索引には,その配列~内の重複を除いた各`~key$ %key ごとに,[ %key を`~key$にするような,`~record$ ]が追加される。 この場合、 `~key~path$Ixは文字列たちが成す~listをとり得ない。 ◎ If its multiEntry flag is true, then one record is added to the index for each of the subkeys.
- 【 この機能により、 各~recordに複数の “タグ” が付与されているような`~record~list$Osに対し,タグで検索するための索引を作成したり、 ある部位においてのみ異なる多数の`~record$を,一つに集約した上で取扱うことが可能になる。 】
【索引の拡充-法】
【 この節は、 原文の記述から導出した,この訳による補完である。 】
所与の`索引$ %索引 に対し,[ %索引 の`~record~list$Ix %L1 ]が[ %索引 が`専属する$`保管庫$の`~record~list$Os %L ]から精確にどう拡充されるかの詳細を、 以下に定式化する (具体的な~algoは、 `§ 各種~db演算@#database-operations$にて定義される)。
まず、 所与の`~record$ %R ~IN %L に対し, `抽出される~key@ たちが成す集合 K( %R ) は,次で定義される:
K( %R ) ~EQ `値から~key集合を抽出する$( %R の`値$ , %索引 の`~key~path$Ix, %索引 の`複-~entryか$Ix )
%L1 は,常に次の拘束が満たされるように拡充される:
-
どの %R ~IN %L に対しても、 各`~key$ %key ~IN K( %R ) に対し, ~AND↓ を満たす~record %R1 が %L1 内に唯一つ~~存在する:
- %R1 の`~key$ ~EQ~cmpkey %key
- %R1 の`値$ ~EQ~cmpkey %R の`~key$
- %L1 は、 前項により導出されるもの以外の`~record$は含まない。
%R が %R1 の`参照先~record$を与える。 [ %索引 の`複-~entryか$Ix ~EQ ~F ]ならば、 集合 K( %R ) は,常に 0 〜 1 個の~keyからなるので、 %L1 から %L への対応関係[ %R1 → %R1 の`参照先~record$ ]は 単射になる。 また、 K( %R ) が常に空でないならば、 この対応関係は全射になる。
したがって、 索引の`~record~list$Ixは,索引が専属する保管庫の`~record~list$Osから一意に定まることになる。 例えば、 保管庫に~recordを追加してから新たな索引を作成した結果と,これを逆順で行った結果は (~errorが生じなければ) 同じになる。 よって、 索引の~record~listを実際に構築しない実装も,原理的には可能になる (処理能 — 例えば~recordの~sortなど — との引き換えになるが) (また,そのように~model化すれば、 この仕様の記述は,もっと簡略化できるであろう)。
2.6.1. 索引~handle
~scriptが`索引$と直にヤリトリすることはない。 代わりに`~tx$の中で `索引~handle@ を介して間接的に~accessする。 ◎ Script does not interact with indexes directly. Instead, within a transaction, script has indirect access via an index handle.
各`索引~handle$ %I には、 次に挙げるものが結付けられる (括弧内は、 対応する `IDBIndex!I ~interface~member ): ◎ ↓
- `索引@IxH ◎ An index handle has an associated index\
- %I の`~access先$とされる`索引$。 【この訳では、もっぱら %I↗ と記す。】 ◎ ↑↑
- `保管庫~handle@IxH ( `objectStore$m ) ◎ and an associated object store handle.\
- %I が`専属する$`保管庫~handle$。 【この訳では、この用語は利用せず,単にこのように記す。】 ◎ ↑↑
- `~tx@IxH ◎ The transaction of an index handle\
- %I (が`専属する$`保管庫~handle$)が`専属する$`~tx$。 【この訳では、この用語は利用せず,単にこのように記す。】 ◎ is the transaction of its associated object store handle.\
- 上に挙げた %I の[ 索引, 保管庫~handle, ~tx ]は、 %I の[ 取得-時/作成-時 ]に,`可換性$と`一意性$の要件が満たされるように設定される。 ◎ Multiple handles may be associated with the same index in different transactions, but there must be only one index handle associated with a particular index within a transaction.
- `名前@IxH ( `name$m ) ◎ An index handle has a name,\
- %I の作成-時に %I↗ の`名前$Ixに初期化される。 この名前は、 %I が`専属する$`~tx$が[ `昇格~tx$であって, `生きて$いる間 ]を除いて,一定であり続ける。 ◎ 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 live.
2.7. ~tx
`~db$内の~dataとヤリトリするとき — すなわち,~dataを読取る/書込むとき — は、 常に `~tx@ ( `transaction^en, “トランス動作” )が利用される。 ◎ 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.
`~tx$は、[ ~app/~system ]の失敗に対する一定の保護を提供する:
- 一度に複数の~data~recordを格納したり,~data~recordを条件付きで改変するために利用できる。
- ~~時間を要する[ ~data~access/~data変異 ]演算からなる,不可分な集合を表現する。
【 すなわち,失敗-時には、 中途半端な状態にならないよう,これらによる変異~すべてが元の状態に復帰される。 】
◎ 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.各 `~tx$には、 次に挙げるものが結付けられる (括弧内は、 対応する `IDBTransaction!I ~interface~member ): ◎ ↓
- `接続@tx ( `db$m ) ◎ ↓
- すべての`~tx$は、 ある`接続$を通して`作成-$される (後述の`存続期間$を見よ)。 ~txは、 その`接続$に`専属する$。 ◎ All transactions are created through a connection, which is the transaction’s connection.
- 【 この訳では、 この接続を指すときは,もっぱら “(~txが)専属する接続” と記す。 】
- `視野@ ( `objectStoreNames$m ) ◎ A transaction has a scope\
- `~tx$がヤリトリし得る`保管庫$たちからなる集合。 ◎ which is a set of object stores that the transaction may interact with.
- 注記: 視野は、 `昇格~tx$でない限り,固定され続ける。 ◎ NOTE: A transaction's scope remains fixed unless the transaction is an upgrade transaction.
- 【 視野は、 `~tx$の作成-時に決定され,内容は変化しない。 `昇格~tx$の視野は、 `常に^em,それが`専属する$`接続$の`保管庫~集合$Cnになる。 】
- 2 つの`~tx$は、 ある`保管庫$が両`~tx$の`視野$に入るならば, `視野が重合して@ いるとされる ◎ Two transactions have overlapping scope if any object store is in both transactions' scope.
- 【 各~txは、 同じ`保管庫$を, 別々な`保管庫~handle$を通して 各自の “視野に入れる” ことに注意。 】
- `~mode@ ( `mode$m ) ◎ A transaction has a mode\
-
`~tx$が,どの型のヤリトリを遂行できるかを決定する。 `~mode$は,~txの作成-時に設定され、 ~txが存続する間,変化しない。 次のいずれか: ◎ 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. A transaction's mode is one of the following:
- `readonly@l
- この型の`~tx$には、 ~dataを読取ることのみが許容され,改変は行えない。 `readonly^l ~txには、 複数のそれらを同時に`開始-$できる優位性がある — 互いの`視野が重合して$いようが (すなわち,同じ保管庫を利用していても)。 この型の~txは、 ~dbが~openされたなら,いつでも作成できる。 【! 手短に言えば、[ 同じ保管庫を視野に入れている,この型の~txたち ]は,その保管庫を排他的に占有する。】 ◎ The transaction is only allowed to read data. No modifications can be done by this type of transaction. This has the advantage that several read-only transactions can be started 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.
- `readwrite@l
- この型の`~tx$には、 既存の保管庫から~dataを読取ることに加えて,~dataを[ 改変する/削除する ]ことも許容される。 しかしながら、 保管庫や索引を[ 追加する, 除去する ]ことはできない。 また、[ 互いの`視野が重合して$いる複数の `readwrite^l `~tx$ ]を同時に`開始-$させることはできない — そうすると,~txの間に互いの~dataを改変し得ることになるので。 この型の~txは、 ~dbが~openされたなら,いつでも作成できる。 ◎ The 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 be started 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.
- 【 手短に言えば、 視野に入れている保管庫たちを排他的に占有する。 】
- `versionchange@l
- この型の`~tx$には、 既存の保管庫から~dataを[ 読取る, 改変する, 削除する ]ことに加えて,保管庫や索引を[ 作成する, 除去する ]こともできる。 それは、 この型の~txのみが行い得る。 この型の~txは、 手動では作成できない — 代わりに `upgradeneeded$et ~eventが発火されるときに自動的に作成される。 ◎ The transaction is allowed to read, modify and delete data from existing object stores, and can also 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 an upgradeneeded event is fired.
- 【 手短に言えば、 接続先~db全体を排他的に占有する。 `昇格~tx$とも呼ばれる。 】
- `耐久能~hint@ ( `durability$m ) ◎ A transaction has a durability hint.\
-
これは、 当の~txを~commitするときに,[ 処理能, 耐久能 ]のどちらを優先するかを~UAに~hintする。 次のいずれかをとる: ◎ This is a hint to the user agent of whether to prioritize performance or durability when committing the transaction. The durability hint is one of the following:
- `strict$l
- ~UAは、[ 未決な変更~すべてが持続的な~storage媒体に成功裡に書込まれたことを検証yした後 ]に限り,`~tx$は成功裡に`~commit$されたものと見なしてヨイ。 ◎ The user agent may consider that the transaction has successfully committed only after verifying that all outstanding changes have been successfully written to a persistent storage medium.
- `relaxed$l
- ~UAは、 未決な変更~すべてが~OSに書込まれ次第 — 後続な検証yは伴わずに — `~tx$は成功裡に`~commit$されたものと見なしてヨイ。 ◎ The user agent may consider that the transaction has successfully committed as soon as all outstanding changes have been written to the operating system, without subsequent verification.
- `default$l
- ~UAは、 自身による既定の[ `~storage~bucket$用の耐久能の挙動 ]を利用するベキである。 これは、 `~tx$用に他が指定されない場合の既定になる。 ◎ The user agent should use its default durability behavior for the storage bucket. This is the default for transactions if not otherwise specified.
-
注記: 代表的な実装においては、 `strict$l は,[ `complete$et ~eventが発火される前に~OSの入出力~bufferを一掃する ]よう~UAに~hintする。 これは、[ 後続な[ ~OS~crash/電力~喪失 ]事例においても,変更は持続化する ]ことになる確度を高めるが、 ~bufferを一掃するのに有意な時間がかかり得るため,携帯~機器の~battery-lifeを消費し得る。 ◎ NOTE: In a typical implementation, "strict" is a hint to the user agent to flush any operating system I/O buffers before a complete event is fired. While this provides greater confidence that the changes will be persisted in case of subsequent operating system crash or power loss, flushing buffers can take significant time and consume battery life on portable devices.
~web~appには、[ ~cacheや~recordが素早く変化するなどの短命な~data用には `relaxed$l / ~data喪失の~riskを抑制することが処理能や電力への影響iに勝る事例においては `strict$l ]を利用することが奨励される。 実装には、 ~appからの耐久能~hintを利用者や機器に対する影響iより重視することが奨励される。 ◎ Web applications are encouraged to use "relaxed" for ephemeral data such as caches or quickly changing records, and "strict" in cases where reducing the risk of data loss outweighs the impact to performance and power. Implementations are encouraged to weigh the durability hint from applications against the impact to users and devices.
- `片付ける~event~loop@ ◎ A transaction optionally has a cleanup event loop\
- `~event~loop$, または ε (初期-時) ◎ which is an event loop.
- `要請~list@ ◎ A transaction has a request list of pending requests\
- ~txに`設置-$された処理待ち`要請$たちからなる, 【設置された順による】~list。 ◎ which have been made against the transaction.
- `~error@tx ( `error$m ) ◎ A transaction has a error\
- 初期時は ε 。 `~tx$が~errorにより`中止-$されたときに設定される。 ◎ which is set if the transaction is aborted.
`~tx$の`親~targetを取得する$~algoは、 ~txが`専属する$`接続$を返す。 ◎ A transaction's get the parent algorithm returns the transaction’s connection.
`~mode$が `readonly$l にされた`~tx$を `~readonly~tx@ という。 ◎ A read-only transaction is a transaction with mode "readonly".
`~mode$が `readwrite$l にされた`~tx$を `~readwrite~tx@ という。 ◎ A read/write transaction is a transaction with mode "readwrite".
2.7.1. ~txの~lifecycle
`~tx$の `状態@tx は、 次のいずれかをとる: ◎ A transaction has a state, which is one of the following:
- `作動中@i ◎ active
- ~txは、 新たに`作成-$されてから,それに`設置-$された`要請$からの~eventが配送される間は、 この状態にある。 ◎ A transaction is in this state when it is first created, and during dispatch of an event from a request associated with the transaction.
- この状態にある~txに対しては、 新たな`要請$を為せる。 ◎ New requests can be made against the transaction when it is in this state.
- `非作動中@i ◎ inactive
- ~txは、 その作成~後[ ~event~loopに制御が返され,~eventが配送されていない間 ]は、 この状態にある。 ◎ A transaction is in this state after control returns to the event loop after its creation, and when events are not being dispatched.
- この状態にある~txに対しては、 `要請$は為せない。 ◎ No requests can be made against the transaction when it is in this state.
- `~commit中@i ◎ committing
- ~txは、 それに設置されたすべての`要請$が完了したとき — `~commit$しようと試みるに伴い — この状態になる。 ◎ Once all requests associated with a transaction have completed, the transaction will enter this state as it attempts to commit.
- この状態にある~txに対しては、 `要請$は為せない。 ◎ No requests can be made against the transaction when it is in this state.
- `完遂d@i ◎ finished
- [ ~commitされた/中止された ]~txは、 それ以降,この状態になる。 ◎ Once a transaction has committed or aborted, it enters this state.
- この状態にある~txに対しては、 `要請$は為せない。 ◎ No requests can be made against the transaction when it is in this state.
`~tx$は~~短命であるものと期待されている。 これは、 下に述べる自動`~commit$の機能性により促される。 ◎ Transactions are expected to be short lived. This is encouraged by the automatic committing functionality described below.
注記: それでも、 作者は,~txを長い間`生かし続け@#transaction-live$れるが、 そのような用法は,利用者~体験を~~悪化させ得るので勧められない。 ◎ NOTE: Authors can still cause transactions to stay alive for a long time; however, this usage pattern is not advised as it can lead to a poor user experience.
`~tx$はその `存続期間@ にわたり、 以下のように変遷する: ◎ The lifetime of a transaction is as follows:
- `~tx$は、 `~mode$と`視野$を伴って `作成-@ される。 その初期~時の`状態$txは、 `作動中$i になる。 ◎ A transaction is created with a scope and a mode. When a transaction is created its state is initially active.
- 実装は、[ `§ ~txの~schedule法@#transaction-scheduling$にて定義される,`~tx$の[ `~mode$と`視野$ ]に定義される拘束 ]を施行-可能になったときは,~txを非同期に `開始-@ する`~taskを~queueする$モノトスル。 ◎ When an implementation is able to enforce the constraints for the transaction’s scope and mode, defined below, the implementation must queue a task to start the transaction asynchronously.
-
`~tx$が`開始-$されたなら、 その~txに設置された各`要請$を実行し始めれるようになる。 それらの要請は、 `設置-$された順序で実行するモノトスル。 同様に,それらの結果も、 同じ順序で返すモノトスル 【返すとは、要請に向けてその完了を報告する~eventを発火することを意味する】 — 異なる~txに`設置-$された要請たちの間では,返される順序は保証されないが。 ◎ Once the transaction has been started the implementation can begin executing the requests placed against the transaction. 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.
注記: ~txの`~mode$は、[ 互いに異なる~txに対し, 2 つの要請の どちらが先に設置された ]としても,[ ~db内に格納される結果の~dataには影響しない ]ことを確保する。 ◎ NOTE: 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.
- ~txに設置された各`要請$は、 `処理-済み$になったとき,[ `success$et / `error$et ]~eventが発火されることになる。 この~eventが`配送-$される間、 当の~txの`状態$txは `作動中$i になり,~txに対して追加的な要請を為せるようになる。 ~event配送-が完了したなら、 ~txの`状態$txは,再び `非作動中$i になる。 ◎ When each request associated with a transaction is processed, a success or error event will be fired. While the event is being dispatched, the transaction state is set to active, allowing additional requests to be made against the transaction. Once the event dispatch is complete, the transaction’s state is set to inactive again.
-
`~tx$は、 `完遂-$する前に,いつでも `中止-@ され得る/できる — ~txが `作動中$i であろうと,まだ`開始-$されていなくても。 ◎ 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.
明示的に `abort()$m を~callすれば、 `中止-$を起動することになる。 中止-は、 失敗した 要請が~scriptにより取扱われなかった場合も,それに後続して起動される。 ◎ An explicit call to abort() will initiate an abort. An abort will also be initiated following a failed request that is not handled by script.
~txが中止されたときは、 実装は,[ その~txの間に`~db$に為されたすべての変更 ]を元に復帰させるモノトスル 【“巻戻し( `roll back^en )” とも称される】。 これには、[ `保管庫$の内容に対する変更 / `保管庫$や`索引$の[ 追加/除去 ]]も含まれる。 ◎ 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.
-
実装は、 ~txが次を満たすならば `~commit@ しようと試みるモノトスル ⇒ [ 設置されたすべての`要請$は完了した ]~AND[ それらの要請が返した結果は取扱われた ]~AND[ 新たな要請は設置されていない ]~AND[ `中止-$されていない ] ◎ The implementation must attempt to commit a transaction when all requests placed against the transaction have completed and their returned results handled, no new requests have been placed against the transaction, and the transaction has not been aborted
明示的に `commit()$m を~callすれば、 要請の結果が~scriptにより取扱われるのを待機することなく`~commit$を起動することになる。 ◎ An explicit call to commit() will initiate a commit without waiting for request results to be handled by script.
~txを~commitするとき、 `状態$txは `~commit中$i になる。 実装は,~txに対し設置された要請により`~db$に為されたすべての変更を,不可分に書込むモノトスル — すなわち、[ すべての変更を書込む ]か[ ~disk書込n~errorなどが生じた場合には、 いかなる変更も~dbに書込まない ]かになるモノトスル。 それに伴い,`~txを中止-$する手続きが後続することになる。 ◎ When committing, the transaction state is set to committing. 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, and the steps to abort a transaction will be followed.
- ~txが[ `~commit$された/`中止-$された ]ときは、 その`状態$txは `完遂d$i になる。 ◎ When a transaction is committed or aborted, its state is set to finished.
実装は、 `作動中$i にある`~tx$に対しては — まだ`開始-$されていなくても — `要請$を`設置-$できるようにするモノトスル。 `開始-$される前に設置された`要請$たちは、 開始されるまでは実行せずに,その順序も込みで保ち続けるモノトスル。 ◎ The implementation must allow requests to be placed against the transaction whenever it is active. 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.
`~tx$は、[ それが`作成-$されたときから,その`状態$txが `完遂d$i に設定されるまで ]の間, `生きて@ いるとされる。 ◎ A transaction is said to be live from when it is created until its state is set to finished.
`索引付き~db~txを片付ける@ ときは、 次を走らす — これは、 片付けられた~txが[ 在れば ~T / 無ければ ~F ]を返す: ◎ To cleanup Indexed Database transactions, run the following steps. They will return true if any transactions were cleaned up, or false otherwise.
- %結果 ~LET ~F ◎ ↓If there are no transactions with cleanup event loop matching the current event loop, return false.
-
`~tx$のうち[ その`片付ける~event~loop$ ~EQ 現在の`~event~loop$ ]を満たす ~EACH( %~tx ) に対し: ◎ For each transaction transaction with cleanup event loop matching the current event loop:
- %結果 ~SET ~T ◎ ↑↓
- %~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
- %~tx の`片付ける~event~loop$ ~SET ε ◎ Clear transaction’s cleanup event loop.
- ~RET %結果 ◎ Return true.
注記: この手続きは、 `HTML$r から呼出される。 それは、 ~scriptから~callされた `transaction()@#dom-idbdatabase-transaction$c により作成された`~tx$は,~scriptが呼出した~taskが完了した時点で作動中でなくなることを確保する。 この手続きが走るのは、 `~tx$ごとに高々 1 回限りになる。 ◎ NOTE: These steps are invoked by [HTML]. They ensure that transactions created by a script call to transaction() are deactivated once the task that invoked the script has completed. The steps are run at most once for each transaction.
`complete@et ~eventは、 成功裡に`~commit$された`~tx$に向けて発火される。 ◎ An event with type complete is fired at a transaction that has successfully committed.
`abort@et ~eventは、 `中止-$された`~tx$に向けて発火される。 ◎ An event with type abort is fired at a transaction that has aborted.
2.7.2. ~txの~schedule法
`~tx$がいつ`開始-$できるかは、 次の拘束により定義される: ◎ The following constraints define when a transaction can be started:
-
`~readonly~tx$ %~tx は、[ ~AND↓ を満たす`~readwrite~tx$は無い ]ならば`開始-$できる: ◎ A read-only transactions tx can start when there are no read/write transactions which:
- %~tx より前に`作成-$された ◎ Were created before tx; and
- %~tx と`視野が重合して$いる ◎ have overlapping scopes with tx; and
- `完遂-$していない ◎ are not finished.
-
`~readwrite~tx$ %~tx は[ ~AND↓ を満たす`~tx$は無い ]ならば`開始-$できる: ◎ A read/write transaction tx can start when there are no transactions which:
- %~tx より前に`作成-$された ◎ Were created before tx; and
- %~tx と`視野が重合して$いる ◎ have overlapping scopes with tx; and
- `完遂-$していない ◎ are not finished.
実装は追加的な拘束を課してもヨイ。 例えば,実装は ⇒# `視野が重合して$いない`~readwrite~tx$を並列的に`開始-$することは要求されない/ 同時に`開始-$される~txの個数に制限sを課してもヨイ ◎ Implementations may impose additional constraints. For example, implementations are not required to start non-overlapping read/write transactions in parallel, or may impose limits on the number of started transactions.
注記: これらの拘束は、 次を含意する: ◎ NOTE: These constraints imply the following:
- `~readonly~tx$は、 同時並行にいくつでも — 互いの`視野が重合して$いようが — `開始-$することが許容される。 ◎ Any number of read-only transactions are allowed to be started concurrently, even if they have overlapping scopes.
- `~readonly~tx$が`生きて$いる間は,[ 実装が その~txにより作成された`要請$を通して返す~data ]は一定であり続ける。 すなわち,同じ~data片を読取る 2 つの要請からは、 ~dataが見出されるかどうかも含め,同じ結果を得られる。 ◎ As long as a read-only transaction is live, the data that the implementation returns through requests created with that transaction remains constant. That is, two requests to read the same piece of data 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.
-
`~readwrite~tx$は、 他の`~tx$を利用して為された`保管庫$への変更からは影響されない。 実装は、 次を確保することになる:
- 別の~txが,`~readwrite~tx$の`視野$に入る`保管庫$の内容を改変しない。
- `~readwrite~tx$が成功裡に完了したなら,その~txを利用して`保管庫$に書込まれた変更を — 併合する際に競合することなく — `~db$に~commitできる。
- 複数の`~readwrite~tx$が同じ保管庫に~accessしようと試みた場合 (すなわち,それらの`視野が重合して$いる)、 先に`作成-$された~txが保管庫への~accessを先に取得する — 当の~txが`完遂-$するまで、 保管庫に~accessできるのは,当の~txに限られる。 ◎ If multiple read/write transactions are attempting to access the same object store (i.e. if they have overlapping scopes), the transaction that was created first is the transaction which gets access to the object store first, and it is the only transaction which has access to the object store until the transaction is finished.
- `~readwrite~tx$ %A の後に`作成-$された,~tx %B は、 %A と`視野が重合して$いる`保管庫$ %O があるならば, %A により書込まれた %O への変更を見ることになる。 これはまた,[ %A が`完遂-$するまでは、 %B は, %A の`視野$に入る どの`保管庫$にも~accessできない ]ことを意味する。 ◎ Any transaction created after a read/write transaction sees the changes written by the read/write transaction. For example, if a read/write transaction A, is created, and later another transaction B, is created, and the two transactions have overlapping scopes, then transaction B sees any changes made to any object stores that are part of that overlapping scope. This also means that transaction B does not have access to any object stores in that overlapping scope until transaction A is finished.
2.7.3. 昇格~tx
`~mode$が `versionchange$l にされた`~tx$を `昇格~tx@ ( `upgrade transaction^en )という。 ◎ An upgrade transaction is a transaction with mode "versionchange".
`昇格~tx$は、 `~db$への`接続$が~openされた後, `~dbを昇格する$手続きの間に、 指定された`~version$dbが現在の`~version$dbより大きい場合に,自動的に作成される†。 この`~tx$は、 `upgradeneeded$et ~event~handlerの内側で `作動中$i になる。 ◎ An upgrade transaction is automatically created when running the steps to upgrade a database 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.
【† このとき以外に,`接続$に`専属する$`昇格~tx$が作成される機会cはない。 したがってそれは、 同じ接続に`専属する$他のどの`~tx$よりも先に`開始-$されることになる。 】
注記: `昇格~tx$は、 `~db$内の[ `保管庫$ / `索引$ ]の[ 作成, 名前の変更, 削除 ]を可能化する。 ◎ NOTE: An upgrade transaction enables the creation, renaming, and deletion of object stores and indexes in a database.
`昇格~tx$は、 排他的である。 `~db接続を~openする$手続きは、[ `昇格~tx$が`生きて$いる間,~dbを~openしている`接続$ ]は,唯一に限られることを確保する。 同じ`~db$への他のすべての`接続$が~closeされるまでは、 `upgradeneeded$et ~eventは発火されず, したがって`昇格~tx$も開始されない。 これは、 以前のすべての~txが`完遂-$されることを確保する。 ◎ An upgrade transaction is exclusive. The steps to open a database connection ensure that only one connection to the database is open when an upgrade transaction is live. 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.
`昇格~tx$が`生きて$いる間は、 同じ`~db$への他の`接続$を~openしようとする試みは遅延され、 同じ`接続$を利用するために `transaction()@#dom-idbdatabase-transaction$c を~callして追加的な~txを開始しようとする試みに対しては, 例外が投出されることになる。 このことは、 次を確保する: ◎ As long as an upgrade transaction is live, 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.\
- `昇格~tx$が`生きて$いる間は、 同じ`~db$に対し, 同時並行に`生きて$いる他の~txは無く, 新たな~txが~queueされることも無い。 ◎ This ensures that no other transactions are live concurrently, and also ensures that no new transactions are queued against the same database as long as the upgrade transaction is live.
- `昇格~tx$が完了したなら,`~db$内の[ `保管庫$, `索引$ ]たちが成す集合は、 後続なすべての[ `接続$, `~tx$ ]の存続期間において,一定であり続ける。 ◎ This further 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.
【 この仕様に現れる, `昇格~txの中@ という句は、[ `upgradeneeded$et ~eventにより呼出される~event~handlerの中 ]を意味する。 “昇格~txの外” という句は、 その否定を意味する。 】
2.8. 要請
`~db$に対する各 非同期の`演算$は、 `要請@ ( `request^en )を利用して行われる。 どの %要請 も,ある一つの`演算$(以下, %演算 と記す)を表現し、 次に挙げるものが結付けられる (括弧内は、 対応する `IDBRequest!I ~interface~member ): ◎ Each asynchronous operation on a database is done using a request. Every request represents one operation.
- `処理-済みか@ ◎ A request has a processed flag\
- 真偽値。 初期~時は ~F とする。 これは、 %演算 が実行されたとき ~T に設定される。 ◎ which is initially false. This flag is set to true when the operation associated with the request has been executed.
- `要請$は、 その`処理-済みか$ ~EQ ~T のとき, `処理-済み@ という。 ◎ A request is said to be processed when its processed flag is true.
- `済んだか@ ( `readyState$m ) ◎ A request has a done flag\
- 真偽値。 初期~時は ~F とする。 %演算 の結果が可用になったとき ~T に設定される。 ◎ which is initially false. This flag is set to true when the result of the operation associated with the request is available.
- `~source@ ( `source$m ) ◎ A request has a source object.
- 【 %演算 の対象 — 次のいずれか:[ `保管庫~handle$/`索引~handle$/`~cursor$/ε ]。 %要請 の作成-時に設定され (設定されない場合は ε )、 それ以降は変化しない。 】
- `結果@ ( `result$m ) ◎ A request has a result\
- `~error@ ( `error$m ) ◎ and an error,\
- `済んだか$ ~EQ ~T になるまでは~accessできない。 ~T の時点で,どうなるかについては、 下記に。 ◎ neither of which are accessible until its done flag is true.
- `設置-先~tx@ ( `transaction$m ) ◎ A request has a transaction\
- 初期~時は ε 。 %要請 は、 %演算 を走らす`要請を非同期に実行する$手続きを利用して,`~tx$に `設置-@ される。 同時に, %要請 は設置-先~txの`要請~list$に追加される。 ◎ which is initially null. This will be set when a request is placed against a transaction using the steps to asynchronously execute a request.
`要請$が為されるときは、 新たな`要請$が その[ `済んだか$ ~SET ~F ]にされた上で返される。 `要請$が表現する `演算@ は、 要請が非同期に実行する手続きの~instance — すなわち, ( 手続き, それに対する入力, その結果 ) が成す組 — である。
`要請$ %要請 がその`演算$の手続きを終えたときは、 先ず[ %要請 の`済んだか$ ~SET ~T ]にされた上で、 演算から返された %結果 に応じて:
-
~errorでない場合 (演算は成功した):
- %要請 の`結果$は %結果 に設定され、 %要請 の`~error$は ε に設定される。
- %要請 に向けて `success@et ~eventが発火される。
-
~errorである場合 (演算は失敗した):
- %要請 の`結果$は ε に設定され、 %要請 の`~error$は %結果 に設定される。
- %要請 に向けて `error@et ~eventが発火される。
`要請$の`親~targetを取得する$~algoは、 要請の`設置-先~tx$を返す。 ◎ A request's get the parent algorithm returns the request’s transaction.
注記: 要請は概して,再利用されないが、 例外もある。 `~cursor$が反復されるときは、 その~cursorを~openするときに利用した同じ`要請$に向けて,反復の成功が報告される。 また,`昇格~tx$が必要yな場合も、 同じ`~open要請$が[ `upgradeneeded$et ~event, ~open演算~自身の最終~結果 ]の両者に利用される。 事例によっては、 要請の`済んだか$は ~F に設定されてから再び ~T に設定され, `結果$は変化する, あるいは`~error$が設定されることもある。 ◎ NOTE: 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 request is used for both the upgradeneeded event and final result of the open operation itself. In some cases, the request’s done flag will be set to false, then set to true again, and the result can change or error could be set instead.
2.8.1. ~open要請
`~open要請@ は、[ `接続$を~openする, あるいは`~db$を削除する ]ときに利用される,特別な型の`要請$である。 `~open要請$に対しては: ◎ An open request is a special type of request used when opening a connection or deleting a database.\
- [ `success$et, `error$et ]~eventに加え,進捗を指示する[ `blocked@et, `upgradeneeded@et ]~eventも発火され得る。 ◎ In addition to success and error events, blocked and upgradeneeded events may be fired at an open request to indicate progress.
- その`~source$は常に ε である。 ◎ The source of an open request is always null.
- その`設置-先~tx$は、 `upgradeneeded$et ~eventが発火されない限り, ε にされる。 【! その~txが完遂したときも ε に戻される】 ◎ The transaction of an open request is null unless an upgradeneeded event has been fired.
- その`親~targetを取得する$~algoは、 ~NULL を返す。 ◎ An open request's get the parent algorithm returns null.
2.8.2. 接続~queue
`~open要請$は `接続~queue@ にて処理される。 この~queueは、 ( `~storage~key$, `名前$db ) が成す組に結付けられる,すべての`~open要請$を包含する†。 `接続~queue$に追加された各 要請は、 順序どおりに処理され,次の要請が処理される前に完了するモノトスル。 ~open要請は、 【それが~openしようとしている~dbを~openしている】 他の`接続$により阻まれ得る — それらの接続が`~close$されるまで、 その要請は完了せず,更なる要請は処理できないことになる。 ◎ Open requests are processed in a connection queue. The queue contains all open requests associated with an storage key and a name. Requests added to the connection queue processed in order and each request must run to completion before the next request is processed. An open request may be blocked on other connections, requiring those connections to close before the request can complete and allow further requests to be processed.
【† 言い換えれば,接続~queueは、 同じ`~db$ (その`~storage~key$に`専属する$, かつ その名前を有するものとして一意に定まる) に対し, それを`~access先$とする`接続$を~openしようとする`要請$すべてからなる。 】
注記: `接続~queue$は、 `~event~loop$に結付けられる`~task~queue$ではない — 要請は、 すべての`閲覧~文脈$の外側で処理されるので。 それでも、 完了した`~open要請$向けの~eventは,[ 要請を為した文脈~下の`~event~loop$に結付けられた`~task~queue$ ]を通して送達される。 ◎ NOTE: A connection queue is not a task queue associated with an event loop, as the requests are processed outside any specific browsing context. The delivery of events to completed open request still goes through a task queue associated with the event loop of the context where the request was made.
2.9. ~key範囲
`保管庫$や`索引$から一連の`~record$を検索取得するためには、[ 単独の`~key$, または`~key範囲$ ]を利用する。 `~key範囲@ とは、 ~keyに利用される ある~data型にわたる連続的な区間である。 ◎ 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.
各 `~key範囲$には、 次に挙げるものが結付けられる (括弧内は、 対応する `IDBKeyRange!I ~interface~member) 【これらは、作成-時に設定され,それ以降は変化しない】 :
- `下界@ ( `lower$m ) ◎ A key range has an associated lower bound\
- `~key$, または ε 。 ◎ (null or a key).
- `上界@ ( `upper$m ) ◎ A key range has an associated upper bound\
- `~key$, または ε 。 ◎ (null or a key).
- `下界openか@ ( `lowerOpen$m ) ◎ A key range has an associated lower open flag.\
- 真偽値。 他が指定されない限り ~F とする。 ◎ Unless otherwise stated it is false.
- 【 `下界$ ~EQ ε の場合は、 必ず ~T にされる。 】
- `上界openか@ ( `upperOpen$m ) ◎ A key range has an associated upper open flag.\
- 真偽値。 他が指定されない限り ~F とする。 ◎ Unless otherwise stated it is false.
- 【 `上界$ ~EQ ε の場合は、 必ず ~T にされる。 】
[ `下界$ ~GT~cmpkey `上界$ ]にはならないモノトスル。 ◎ A key range may have a lower bound equal to its upper bound. A key range must not have a lower bound greater than its upper bound.
`Only@ ( %key ) と記される,所与の`~key$ %key のみを包含する`~key範囲$は、 次のようにされた`~key範囲$として定義される ⇒# `下界$ ~SET %key, `上界$ ~SET %key, `上界openか$ ~SET ~F, `下界openか$ ~SET ~F ◎ A key range containing only key has both lower bound and upper bound equal to key.
所与の`~key$ %key は、 ~AND↓ を満たすとき,`~key範囲$ %範囲 に `入る@ とされる: ◎ A key is in a key range range if both of the following conditions are fulfilled:
-
~OR↓:
- %範囲 の`下界$ ~EQ ε
- %範囲 の`下界$ ~LT~cmpkey %key
- [ %範囲 の`下界$ ~EQ~cmpkey %key ]~AND[ %範囲 の`下界openか$ ~EQ ~F ]
-
~OR↓:
- %範囲 の`上界$ ~EQ ε
- %範囲 の`上界$ ~GT~cmpkey %key
- [ %範囲 の`上界$ ~EQ~cmpkey %key ]~AND[ %範囲 の`上界openか$ ~EQ ~F ]
注記: [ `下界$ / `上界$ ]は、 `~key範囲$に`入る$とされる`~key$の[ “~~下限” / “~~上限” ]を与える。 [ `下界$ / `上界$ ]に対する ε は[ ~~下限/~~上限 ]が無いことを表す。
`下界$は、[ `下界openか$ ~EQ ~F ]のとき, そのときに限り,`~key範囲$に`入る$。 `上界openか$についても同様になる。
◎ NOTE: • If a key range's lower open flag is false, the lower bound key of the key range is included in the range itself. • If a key range's lower open flag is true, the lower bound key of the key range is excluded from the range itself. • If a key range's upper open flag is false, the upper bound key of the key range is included in the range itself. • If a key range's upper open flag is true, the upper bound key of the key range is excluded from the range itself.`全範囲@ とは、[ `下界$ ~EQ `上界$ ~EQ ε ]なる`~key範囲$である。 任意の`~key$に対し[ `~key$ ~IN `全範囲$ ]は真になる。 ◎ An unbounded key range is a key range that has both lower bound and upper bound equal to null. All keys are in an unbounded key range.
【 `全範囲$は `IDBKeyRange$I ~objとしては~instance化され得ない — ~modelにのみ存在する~objである。 】
`Range@ ( %値, %~NULL不可 (省略時は ε ) ) は、 次を走らす: ◎ To convert a value to a key range with value and optional null disallowed flag, run these steps:
-
%値 に応じて:
- `~key範囲$である
- ~RET %値 ◎ If value is a key range, return value.
- ε
- ~NULL†
-
- ~IF [ %~NULL不可 ~NEQ ε ] ⇒ ~THROW `DataError$E
- ~RET `全範囲$
- その他
- ~RET `Only$( `Key$( %値 ) ) ? ◎ Let key be the result of converting a value to a key with value. Rethrow any exceptions. ◎ If key is invalid, throw a "DataError" DOMException. ◎ Return a key range containing only key.
【† この手続きは、 ~key範囲を期待する引数 (この仕様では,名前 %query の引数として記される) をとる~API~methodから呼び出される。 その引数が省略可能であって, ~NULL が渡された場合、 特別に,引数が省略されたとき( ε )と同じに扱われることになる。 】
2.10. ~cursor
`~cursor@ は、 ある~dbに`専属する$[ `索引$/`保管庫$ ]の中の ある範囲に入る~recordたちを,特定の方向に反復するために利用される。 ◎ A cursor is used to iterate over a range of records in an index or an object store in a specific direction.
`~cursor$ は、 次に挙げるものを有する (括弧内は、 対応する `IDBCursor!I ~interface~member) — これらは、 `~cursorを作成する$ときに設定される:
- `~tx@Cs ◎ A cursor has a transaction,\
- ~cursorの`~source$Csが`専属する$`~tx$。 【この訳では、この用語は利用せず,単にこのように記す。】 ◎ the transaction that was active when the cursor was created.
- `範囲@Cs ◎ A cursor has a range\
- `~key範囲$。 ~cursorは、[ `~source$Cs↗内の`~record$のうち,`~key$がこの範囲に`入る$もの ]を反復対象にする。 ◎ of records in either an index or an object store.
- 【 ~cursorの作成-時に指定されなかった場合、 `全範囲$が指定されたものと見なされる。 】
- `~source@Cs ( `source$m ) ◎ A cursor has a source\
- `保管庫~handle$, または`索引~handle$。 ~cursorは, ~source↗( ~sourceの`~access先$)の~record~listを反復対象にする。 ◎ that indicates which index or an object store is associated with the records over which the cursor is iterating.
- 【 原文における`~source$Csは、[ `保管庫$, または`索引$ ]として定義されているが、 ~modelの記述を簡潔にするため,この訳では 上述のように改めている — ~cursorを利用するどの演算も,保管庫~handle/索引~handleを通した~accessを要しており、 まわりくどい記述になっているので。 】
- `方向@Cs ( `direction$m ) ◎ A cursor has a direction\
-
次の 2 つを指示する:
- 反復-時に~cursorの`位置$Csを移動させる方向 — すなわち,`~record$たちを その`~key$の 昇順, 降順 いずれの順序で反復するか。 ~cursor初期~位置は[ 前者/後者 ]に応じて,`~source$Cs↗の[ 始端/終端 ]側に位置することになる。
- ~keyが重複する~recordがあるとき,最初のもの以外を飛ばすかどうか。
-
~cursorの`方向$Csは、 次の値をとり得る:
- `next@l
- `~cursor$を`~source$Cs↗の始端~側から,`~key$の昇順に反復する。
- `prev@l
- `~cursor$を`~source$Cs↗の終端~側から,~keyの降順に反復する。
- `next$l, `prev$l のいずれも、 反復-時には、 `~key$が`等しい$もの†も含め,`範囲$Csに`入る$すべての~recordを得るべきである††。
- 【† 重複する~keyを伴う~record間の反復-順序については、 `保管庫~位置$Csを見よ。 】【†† “べき” — `位置$Csの記述を見よ。 】
- `nextunique@l
- `~key$が互いに`等しい$~recordたちについては,それらのうち最初の~record以外は飛ばすことを除いて、 `next$l と同じ。
- `prevunique@l
- `~key$が互いに`等しい$~recordたちについては,それらのうち 最初の ~record以外は飛ばすことを除いて、 `prev$l と同じ。
- [ `nextunique$l / `prevunique$l ]に対しては、 `~source$Cs↗が`保管庫$であるか[ `索引$であって,その`一意か$Ix ~EQ ~T ]である場合の挙動は,[ `next$l / `prev$l ]と正確に同じになる。
- `位置@Cs ◎ A cursor has a position\
- `範囲$Csに`入る$どこかを指す†。 ~cursorが反復対象にしている~record~listは、 ~cursorの`範囲$Csが全部的に反復される前に変更されることもある。 これを取扱うため、 ~cursorは自身の`位置$Csを,~indexとしてではなく,前回に返した†~recordの`~key$として保守する。 ~cursorが次の~recordへ反復するよう請われたとき、 `方向$Csが~keyの昇順なら、 前回に反復した~recordの~key`より大きい$~keyを有する~recordのうち,最小な`~key$を有するものを返すことになる††。 `方向$Csが~keyの降順なら、 それとは逆に,前回に反復した~recordの~key`より小さい$~keyを有する~recordのうち,最大な`~key$を有するものを返すことになる。 ◎ within its range. 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.
- 【† 位置は、 初期~時には,反復~順序における仮想の先頭( ε )をとるが、 `~cursorを作成する$要請の結果として,この位置のまま~APIに公開されることはない — `範囲$Csに入る~recordが無い場合、 要請の`結果$は ~NULL になる。 】【 ~cursorがすべてを反復し終えて,次の~recordへの反復が試みられた場合、 ε に設定され,それ以上~反復できなくなる。 】【†† 索引における~keyの重複を無視するならば。 次項を見よ。 】
- `保管庫~位置@Cs ◎ For cursors iterating indexes\
- `索引$においては、 複数の~recordが同じ~keyを有することもあり,`値$によっても~sortされることから、 `索引$を反復する~cursorについては,少しばかり複雑になる。 この場合、 `~cursor$は,前回の反復にて索引~内に見出された`~record$の`値$を指示する,`保管庫~位置^emも有する†。 次の~recordを見出すときには、 `位置$Csに加え,`保管庫~位置$Csも利用される。 ◎ 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.
- 【† すなわち,`参照先~record$の`~key$ — ゆえに “保管庫~位置” と称されている。 】
- `~key@Cs ( `key$m ) ◎ ↓
- ~cursorが最後に反復した`~record$の`~key$を表現する。 ◎ ↓
- 【 これは,実質的に`位置$Csの別名。 】
- `値@Cs ( `IDBCursorWithValue.value$m ) ◎ ↓
- ~cursorが最後に反復した`~record$の`値$†を表現する。 ◎ A cursor has a key and a value which represent the key and the value of the last iterated record.
- 【† `~source$Cs↗が`索引$の場合は`参照先~record$の値。 】
- `値は取得-済みか@Cs ◎ A cursor has a got value flag.\
- 真偽値。 ~T は、[[ ~cursorを利用する`要請$ ]が`非同期に実行する$`演算$ ]が完了し,新たな ( `~key$Cs, `値$Cs ) を得た (新たな ( `位置$Cs, `保管庫~位置$Cs ) に移動した) ことを指示する。 ◎ ↓
- 【 新たな~cursorを取得した時点では、 その前に,`範囲$Csに入る最初の~recordが検索取得されるので、 これも ~T になる。 】
-
したがって, ~F の場合、 次のいずれかを指示する:
- ~cursorを利用する`要請$が`非同期に実行する$`演算$は、 完了していない。
- ~cursorは,その`範囲$Csに入るすべての~recordを反復し終えて,次の~recordへの反復が一回でも試みられた。
【 後者の場合のみ,[ `~key$Cs, `値$Cs ]は ε にされるので、 `key$m を調べれば前者と区別できる。 後者の場合、 それ以上~cursorは利用できなくなる — 例えば `範囲$Csに入る新たな~recordが追加されても, `値は取得-済みか$Csが ~T に戻ることはない (そうしてから もう一回~反復を試みても,例外が投出されることになる)。 】
◎ 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. - `実効~保管庫@Cs ◎ ↓
- ~cursorの`~source$Cs↗が[ `保管庫$ならば それ/ `索引$ならば それが`専属する$`保管庫$ ]。 ◎ ↓
- `実効~key@Cs ( `primaryKey$m ) ◎ ↓
- ~cursorの`~source$Cs↗が[ `保管庫$ならば ~cursorの`位置$Cs / `索引$ならば ~cursorの`保管庫~位置$Cs ]。 ◎ 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.
- `要請@Cs ◎ A cursor has a request,\
- ~cursorを~openするときに利用された`要請$。 ◎ which is the request used to open the cursor.
- `~keyのみか@Cs ◎ A cursor also has a key only flag,\
- ~cursorの`値$Csも~APIに公開されるかどうかを指示する真偽値。 ◎ that indicates whether the cursor’s value is exposed via the API.
- 【 ~F ならば、 値も~APIに公開する — すなわち、 ~cursorは `IDBCursorWithValue$I ~interfaceを実装することになる。 】
2.11. ~key生成器
`保管庫$の作成-時には、 `~key生成器@ を利用するようにも指定できる。 ~key生成器は、 保管庫の中へ挿入される~record用の~keyが指定されていない場合に,それを生成するために利用される。 ◎ When a object store is created it can be specified to use a key generator. A key generator is used to generate keys for records inserted into an object store if not otherwise specified.
`~key生成器$は `現在の番号@ を有する。 `現在の番号$は、 `保管庫$の作成-時には 1 に設定され,常に[[ `最大な番号@ ~EQ ( 2 の 53 乗( 9007199254740992 ) + 1 ) ]以下の整数になる 【実際に利用される~keyは最大な番号~以下になる】 。 `現在の番号$は、 ~keyが生成される度に増分される。 また,明示的な~keyを利用して特定の値に更新できる。 ◎ A key generator has a current number. The current number is always a positive integer less than or equal to 253 (9007199254740992) + 1. The initial value of a key generator's current number is 1, set when the associated object store is created. The current number is incremented as keys are generated, and may be updated to a specific value by using explicit keys.
注記: どの保管庫も,~~自前の`~key生成器$を利用する。 ある保管庫とのヤリトリが,他の保管庫の`~key生成器$に影響することは、 決してない。 ◎ NOTE: Every object store that uses key generators uses a separate generator. That is, interacting with one object store never affects the key generator of any other object store.
`現在の番号$に対する改変は、 ~db演算の一部と見なされる:
- 演算が何であれ、 それが失敗して,それによる変更が復帰された場合、 `現在の番号$も元の値に復帰される。
- `~tx$が中止された場合、 ~txの`視野$に入る各`保管庫$の`~key生成器$の`現在の番号$は,その~txの開始-前の値に復帰される。
`現在の番号$は、 ~db演算の結果が復帰される場合を除き,決して減少しない。 `保管庫$から`~record$を削除しようが, `IDBObjectStore.clear()$m ~methodを利用して全~recordを~clearしようが、 保管庫の`~key生成器$には決して影響しない。 ◎ 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() method, does not affect the current number of the object store’s key generator.
`~record$を格納する~callにて明示的に`~key$が指定されていない場合、 ~keyは生成される。 ◎ When a record is stored and a key is not specified in the call to store the record, a key is generated.
`保管庫~用の~keyを生成する@ ときは、 所与の ( `保管庫$ %保管庫 ) に対し,次を走らす: ◎ To generate a key for an object store store, run these steps:
- %生成器 ~LET %保管庫 の`~key生成器$ ◎ Let generator be store’s key generator.
- %~key ~LET %生成器 の`現在の番号$ ◎ Let key be generator’s current number.
- ~IF[ %~key ~GT `最大な番号$ ] ⇒ ~RET `失敗^i ◎ If key is greater than 253 (9007199254740992), then return failure.
- %生成器 の`現在の番号$ ~INCBY 1 ◎ Increase generator’s current number by 1.
- ~RET %~key ◎ Return key.
`~record$を格納する~callにて`~key$が明示的に指定された場合、 `~key生成器$は更新され得る。 ◎ When a record is stored and a key is specified in the call to store the record, the associated key generator may be updated.
`保管庫~用の~key生成器を可能なら更新する@ ときは、 所与の ( `保管庫$ %保管庫, `~key$ %~key ) に対し,次を走らす: ◎ To possibly update the key generator for an object store store with key, run these steps:
- ~IF[ %~key の`型$key ~NEQ `number$i ] ⇒ ~RET ◎ If the type of key is not number, abort these steps.
- %値 ~LET 次を満たす最大な整数 ⇒ [ %値 ~LTE %~key の`値$key ]~AND[ %値 ~LTE `最大な番号$ ] ◎ Let value be the value of key. ◎ Set value to the minimum of value and 253 (9007199254740992). ◎ Set value to the largest integer not greater than value.
- %生成器 ~LET %保管庫 の`~key生成器$ ◎ Let generator be store’s key generator.
- ~IF[ %値 ~GTE %生成器 の`現在の番号$ ] ⇒ %生成器 の`現在の番号$ ~SET %値 + 1 ◎ If value is greater than or equal to generator’s current number, then set generator’s current number to value + 1.
注記: ~keyは、 次のいずれかにより指定できる:
- `保管庫$の`~key~path$Os ~NEQ ε の場合 ⇒ [ 保管庫に格納する`~record$の`値$ ]の[ ~key~pathが指す部位にある~prop ]に~keyを設定する。
- 他の場合 ⇒ ~recordを格納する~callの引数として,~keyを渡す。
指定された~keyが`現在の番号$に影響するのは、 `number$i `型$keyの場合に限られ, 他の`型$keyの~keyは影響しない ( `string$i 値を `number$i 値に構文解析するなどの暗黙的な変換は行われない)。 1 より小さい `number$i ~keyも,`現在の番号$より常に低いので影響しない。 ◎ Only specified keys of type number can affect the current number of the key generator. Keys of type date, array (regardless of the other keys they contain), binary, or string (regardless of whether they could be parsed as numbers) have no effect on the current number of the key generator. Keys of type number with value less than 1 do not affect the current number since they are always lower than the current number.
`現在の番号$が`最大な番号$を超えた下では、 後続な[ `~key生成器$を利用して新たな`~key$を生成しようとする試み ]に対しては, `ConstraintError$E 例外が投出される。 それでも、 明示的な~keyを指定すれば,`~record$を保管庫に挿入できるが、 `~key生成器$を再び利用するためには,保管庫を削除して新たに作成し直す他にない。 ◎ When the current number of a key generator reaches above the value 253 (9007199254740992) any subsequent attempts to use the key generator to generate a new key will result in a "ConstraintError" DOMException. 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 such records is to delete the object store and create a new one.
注記: この上限は、 `最大な番号$を超える整数は~ES `Number$jT では一意に表現できないことによる。 例えば~ESにおいては、[ `9007199254740992 + 1 === 9007199254740992^c ]になる。 ◎ NOTE: This limit arises because integers greater than 9007199254740992 cannot be uniquely represented as ECMAScript Numbers. As an example, 9007199254740992 + 1 === 9007199254740992 in ECMAScript.
`~key生成器$を普通に利用している限り、 この上限が問題になることはない。 新たな~keyを毎秒 1000 回~生成し続けても,この上限に至るのは 285000 年後である。 ◎ As long as key generators are used in a normal fashion this limit 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.
~~要約すると、 保管庫が`~key生成器$を有する場合:
- 最初に生成される~keyは (他の `number$i ~keyが明示的に挿入されない限り) 常に 1 になる。
- 生成される~keyは、 常に,保管庫~内の最大な `number$i ~keyより大きい,正な整数になる。
- 同じ保管庫に対し,同じ~keyが重ねて生成されることは、 ~txが巻戻されない限り,決してない。
各~保管庫は、 自前の`~key生成器$を取得する: ◎ Each object store gets its own key generator:
%store1 = db.createObjectStore(`store1^l, { autoIncrement: true }); %store1.put(`a^l); // ~key `1^jv があてがわれる %store2 = db.createObjectStore(`store2^l, { autoIncrement: true }); %store2.put(`a^l); // ~key `1^jv があてがわれる %store1.put(`b^l); // ~key `2^jv があてがわれる %store2.put(`b^l); // ~key `2^jv があてがわれる
挿入が,拘束~違反や IO ~errorに因り失敗した場合、 `~key生成器$は更新されない。 ◎ If an insertion fails due to constraint violations or IO error, the key generator is not updated.
%transaction.onerror = function(%e) { %e.preventDefault() }; %store = %db.createObjectStore(`store1^l, { autoIncrement: true }); %index = %store.createIndex(`index1^l, `ix^l, { unique: true }); %store.put({ ix: `a^l}); // ~key `1^jv があてがわれる %store.put({ ix: `a^l}); // 失敗することになる %store.put({ ix: `b^l}); // ~key `2^jv があてがわれる
保管庫から~itemを除去しようが,`~key生成器$には影響しない — `clear()^m が~callされたときも含め。 ◎ Removing items from an objectStore never affects the key generator. Including when clear() is called.
%store = %db.createObjectStore(`store1^l, { autoIncrement: true }); %store.put(`a^l); // ~key `1^jv があてがわれる %store.delete(`1^lt); %store.put(`b^l); // ~key `2^jv があてがわれる %store.clear(); %store.put(`c^l); // ~key `3^jv があてがわれる %store.delete(IDBKeyRange.lowerBound(`0^lt)); %store.put(`d^l); // ~key `4^jv があてがわれる
明示的な~keyを伴わせて~itemを挿入した場合、[ その~keyは `number$i である,かつ 最後に生成された~keyより大きい ]とき,そのときに限り,`~key生成器$に影響する。 ◎ Inserting an item with an explicit key affects the key generator if, and only if, the key is numeric and higher than the last generated key.
%store = %db.createObjectStore(`store1^l, { autoIncrement: true }); %store.put(`a^l); // ~key `1^jv があてがわれる %store.put(`b^l, `3^lt); // ~key `3^jv を利用する %store.put(`c^l); // ~key `4^jv があてがわれる %store.put(`d^l, -`10^lt); // ~key `-10^jv を利用する %store.put(`e^l); // ~key `5^jv があてがわれる %store.put(`f^l, `6.00001^lt); // ~key `6.0001^jv を利用する %store.put(`g^l); // ~key `7^jv があてがわれる %store.put(`f^l, `8.9999^lt); // ~key `8.9999^jv を利用する %store.put(`g^l); // ~key `9^jv があてがわれる %store.put(`h^l, `foo^l); // ~key `foo^l を利用する %store.put(`i^l); // ~key `10^jv があてがわれる %store.put(`j^l, [`1000^lt]); // ~key `[1000]^jv を利用する %store.put(`k^l); // ~key `11^jv があてがわれる /* これらはどれも、 保管庫が~key~pathを利用している下で,~objの中に明示的に~keyを埋め込んで渡したときと,同じに挙動することになる。 ◎ All of these would behave the same if the objectStore used a keyPath and the explicit key was passed inline in the object */
~txが中止された場合、 その間に起きた`~key生成器$に対する増加-は巻戻される。 これにより、 すべての巻戻しは一貫するようになる — ~crashに因る巻戻しは、 増加された~key生成器の`現在の番号$を`~commit$する機会cを得ることは決してないので。 ◎ Aborting a transaction rolls back any increases to the key generator which happened during the transaction. This is to make all rollbacks consistent since rollbacks that happen due to crash never has a chance to commit the increased key generator value.
%db.createObjectStore(`store^l, { autoIncrement: true }); %trans1 = %db.transaction([`store^l], `readwrite$l); %store_t1 = %trans1.objectStore(`store^l); %store_t1.put(`a^l); // ~key `1^jv があてがわれる %store_t1.put(`b^l); // ~key `2^jv があてがわれる %trans1.abort(); %trans2 = %db.transaction([`store^l], `readwrite$l); %store_t2 = trans2.objectStore(`store^l); %store_t2.put(`c^l); // ~key `1^jv があてがわれる %store_t2.put(`d^l); // ~key `2^jv があてがわれる
ある~objを保管庫に保存するときに (例えば `IDBObjectStore.put()$m を用いて),[ `~key~path$Osを利用するとき ]と, [ `~key生成器$を利用するとき ]との挙動の相違を、 以下の例にて~~説明する。 ◎ 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.
以下では:
- 保管庫に保存する ~objを %O と記す。
- %O を保管庫に保存した結果の`~record$を %R と記す。 %O は ( `StructuredSerializeForStorage$jA された上で) %R の`値$として保存される。
- 保管庫は`~key生成器$を有するとする。 この生成器が次回に供する値を、 %生成key と記す。
保管庫の`~key~path$Os ~EQ ε ならば、 %R の`~key$には %生成key があてがわれることになる。 以降、 保管庫の`~key~path$ %keyPath ~NEQ ε とする。
次の様に %O が %keyPath が指す部位に~propを有さないならば:
%keyPath = `foo.bar^l %O = { foo: {} }
%O が保管庫に保存されるときには, %生成key がその~prop (ここでは %O`.foo.bar^c ) の値にあてがわれる:
%R の`値$ = { foo: { bar: %生成key } }
逆に、 %O が %keyPath が指す部位に~propを有する場合:
%O = { foo: { bar: 10 } }
%生成key は利用されず、 %R の~keyには %keyPath が指す部位の値が (この例では 10 ),利用される。
~systemは、 ~prop階層を満たすに必要な分の~propを作成する責を負う。 例えば:
%keyPath = `foo.bar.baz^l %O = {}
であれば、 %O が`保管庫$に保存されるときには,[ `foo^c, `bar^c, `baz^c ]~propが順に入れ~~子にされた上で, %keyPath が指す部位に %生成key があてがわれる:
%R の`値$ = { foo: { bar: { baz: %生成key } } }
~primitive値~上に~propを格納しようと試みられた場合、 失敗して~errorが投出されることになる。 例えば:
%keyPath = `foo^l %O = 4
であれば、 %O は~primitive値なので~propを定義できず,失敗する。 これは、 配列( 例えば %O = `[10]^c )にも該当する。 配列~上にも~propは許容されないので、 ~propを定義しようと試行しても失敗する:
【 原文の記述構成は(少なくとも,そのまま訳すと)解りにくいので、 この例の訳は等価な記述に全面的に構成し直している。 】
If the following conditions are true:
- The object store has a key generator.
- There is no in-line value for the key path property.
Then the value provided by the key generator is used to populate the key value. In the example below the key path for the object store is "foo.bar". The actual object has no value for the bar property, { foo: {} }. When the object is saved in the object store the bar property is assigned a value of 1 because that is the next key generated by the key generator.
const store = db.createObjectStore("store", { keyPath: "foo.bar", autoIncrement: true }); store.put({ foo: {} }).onsuccess = function(e) { const key = e.target.result; console.assert(key === 1); };
If the following conditions are true:
- The object store has a key generator.
- There is a value for the key path property.
Then the value associated with the key path property is used. The auto-generated key is not used. In the example below the key path for the object store is "foo.bar". The actual object has a value of 10 for the bar property, { foo: { bar: 10} }. When the object is saved in the object store the bar property keeps its value of 10, because that is the key value.
const store = db.createObjectStore("store", { keyPath: "foo.bar", autoIncrement: true }); store.put({ foo: { bar: 10 } }).onsuccess = function(e) { const key = e.target.result; console.assert(key === 10); };
The following example illustrates the scenario when the specified in-line key is defined through a key path but there is no property matching it. The value provided by the key generator is then used to populate the key value and the system is responsible for creating as many properties as it requires to suffice the property dependencies on the hierarchy chain. In the example below the key path for the object store is "foo.bar.baz". The actual object has no value for the foo property, { zip: {} }. When the object is saved in the object store the foo, bar, and baz properties are created each as a child of the other until a value for foo.bar.baz can be assigned. The value for foo.bar.baz is the next key generated by the object store.
const store = db.createObjectStore("store", { keyPath: "foo.bar.baz", autoIncrement: true }); store.put({ zip: {} }).onsuccess = function(e) { const key = e.target.result; console.assert(key === 1); store.get(key).onsuccess = function(e) { const value = e.target.result; // value will be: { zip: {}, foo: { bar: { baz: 1 } } } console.assert(value.foo.bar.baz === 1); }; };
Attempting to store a property on a primitive value will fail and throw an error. In the first example below the key path for the object store is "foo". The actual object is a primitive with the value, 4. Trying to define a property on that primitive value fails. The same is true for arrays. Properties are not allowed on an array. In the second example below, the actual object is an array, [10]. Trying to define a property on the array fails.
const store = db.createObjectStore("store", { keyPath: "foo", autoIncrement: true }); // The key generation will attempt to create and store the key path property on this primitive. store.put(4); // will throw DataError // The key generation will attempt to create and store the key path property on this array. store.put([10]); // will throw DataError
3. 例外
この文書が利用する各種 例外は、 特定の名前の `DOMException$I である。 例外の[ 名前, 旧来の~code値 ]などの~propは、 `WEBIDL$r 【`DOMException^I 用の`名前~表t@~WEBIDL#dfn-error-names-table$】 にて定義されている。 ◎ Each of the exceptions used in this document is a DOMException with a specific type. The exception types and properties such as legacy code value are defined in [WEBIDL].
以下の表tに、 この文書が利用する 例外~名, および その用法を述べる: ◎ The table below lists the DOMExceptions used in this document along with a description of the exception type’s usage.
例外~名 | 意味 |
---|---|
`AbortError@E | `要請$は中止された。 ◎ A request was aborted. |
`ConstraintError@E | ~txにおける変異~演算は、 拘束が満たされないため,失敗した。 ◎ A mutation operation in the transaction failed because a constraint was not satisfied. |
`DataCloneError@E | 格納しようと試みた~dataは、 内部~有構造~clone~algoにより~cloneできなかった。 ◎ The data being stored could not be cloned by the internal structured cloning algorithm. |
`DataError@E | 演算に供された~dataは、 要件を満たしていない。 ◎ Data provided to an operation does not meet requirements. |
`InvalidAccessError@E | ~objに対し妥当でない演算が遂行された。 ◎ An invalid operation was performed on an object. |
`InvalidStateError@E | ~objに対する所与の演算は、 許容されない, あるいは許容されない時機に~callされた。 または、 すでに[ 削除された/除去された ]~source~objに対し要請が為された。 ◎ An operation was called on an object on which it is not allowed or at a time when it is not allowed, or if a request is made on a source object that has been deleted or removed. |
`NotFoundError@E | 要請された~db~objを見出せなかったため、 演算は失敗した。 ◎ The operation failed because the requested database object could not be found. |
`NotReadableError@E | 要請された~dataを包含している下層~storageを読取れなかったため、 演算は失敗した。 ◎ The operation failed because the underlying storage containing the requested data could not be read. |
`QuotaExceededError@E | 残りの~storage~~容量が十分でないため、 あるいは,~storage~quotaに達したが,利用者が~dbへの容量追加を辞退しため、 演算は失敗した。 ◎ 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@E | 渡された %keyPath 引数は,`妥当な~key~path$でない。 ◎ The keyPath argument contains an invalid key path. |
`ReadOnlyError@E | `~readonly~tx$において,変異~演算が試みられた。 ◎ The mutating operation was attempted in a read-only transaction. |
`TransactionInactiveError@E | [ 現在は`作動中$i でない/すでに`完遂-$した ]~txに対し,要請が設置された。 ◎ A request was placed against a transaction which is currently not active, or which is finished. |
`UnknownError@E | 演算は、[ ~db自身に無関係な一過な事由/ 他の~errorに該当しない事由 ]で失敗した。 ◎ The operation failed for transient reasons unrelated to the database itself or not covered by any other error. |
`VersionError@E | 既存の~versionより低い~versionで~dbを~openしようと試みられた。 ◎ An attempt was made to open a database using a lower version than the existing version. |
注記: 複数の Indexed DB 演算が,同じ型の~errorを投出したり、 単独の演算であっても,複数の事由に対し同じ型の~errorを投出し得るので、 実装には、 より~~詳細な~messageを供して,~errorを~debugし易くすることが奨励される。 ◎ NOTE: Given that multiple Indexed DB operations can throw the same type of error, and that even a single operation can throw the same type of error for multiple reasons, implementations are encouraged to provide more specific messages to enable developers to identify the cause of errors.
4. ~API
各種~API~methodは、 それを~callした~threadを阻むことなく返す。 すべての非同期的な演算は、 即時に `IDBRequest$I ~instanceを返す。 この~objは、 初期~時には,演算の結果について,いかなる情報も包含しない。 情報が可用になったなら、 要請に向けて~eventが発火され,情報は `IDBRequest$I ~instanceの各種~属性を通して可用になる。 ◎ 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.
`~db~access~task~source@ が、 これらの~taskの`~task~source$である。 ◎ The task source for these tasks is the database access task source.
4.1. `IDBRequest^I ~interface
`IDBRequest$I ~interfaceが、 `~db$や, それに専属する各種~objに対する非同期的な`要請$の結果に~accessする手段を,`~event~handler~IDL属性$ `HTML$r を利用して供する。 ◎ The IDBRequest interface provides the means to access results of asynchronous requests to databases and database objects using event handler IDL attributes [HTML].
~dbに対し`演算$を要請するような どの~methodも,[ ~eventを通して,要請している~appに`結果$を~~返信する ]ような, `IDBRequest$I ~objを返す。 すなわち,`演算$は非同期に実行される。 この設計は、 どの`~db$に対しても,いくつもの要請が同時に作動中になり得ることを意味する。 ◎ 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.
次の例では、 `~db$を非同期に~openする。 種々の状況に応答するために、 種々の~event~handlerが登録される。 ◎ In the following example, we open a database asynchronously. Various event handlers are registered for responding to various situations.
const %request = `indexedDB$m.open('AddressBook', `15^lt); %request.onsuccess = function(%evt) {...}; %request.onerror = function(%evt) {...};
[`Exposed$=(Window,Worker)]
interface `IDBRequest@I : `EventTarget$I {
readonly attribute `any$ `result$m;
readonly attribute `DOMException$I? `error$m;
readonly attribute (`IDBObjectStore$I or `IDBIndex$I or `IDBCursor$I)? `source$m;
readonly attribute `IDBTransaction$I? `transaction$m;
readonly attribute `IDBRequestReadyState$I `readyState$m;
// ~event~handler:
attribute `EventHandler$I `onsuccess$m;
attribute `EventHandler$I `onerror$m;
};
enum `IDBRequestReadyState@I {
`pending$l,
`done$l
};
- %request . `result$m
- %request が完了している場合、 それが[ 成功したならば その`結果$ / 失敗したならば `undefined^jv ]を返す。 完了していない場合、 `InvalidStateError$E を投出する。 ◎ When a request is completed, returns the result, or undefined if the request failed. Throws a "InvalidStateError" DOMException if the request is still pending.
- %request . `error$m
- %request が完了している場合、 それが[ 成功したならば ~NULL / 失敗したならば `~error$ ( `DOMException$I ) ]を返す。 完了していない場合、 `InvalidStateError$E を投出する。 ◎ When a request is completed, returns the error (a DOMException), or null if the request succeeded. Throws a "InvalidStateError" DOMException if the request is still pending.
- %request . `source$m
- %request は`~open要請$である場合、 ~NULL を返す。 他の場合、 %request の`~source$ ( `IDBObjectStore$I / `IDBIndex$I / `IDBCursor$I ) を返す。 ◎ Returns the IDBObjectStore, IDBIndex, or IDBCursor the request was made against, or null if it was an open request.
- %request . `transaction$m
- %request の`設置-先~tx$ ( `IDBTransaction$I ) を返す。 ただし, %request は`~open要請$である場合、 %request により~openされた`~db$の`昇格~tx$dbが[ ε でない, かつ`生きて$いるならば それ / ~ELSE_ ~NULL ]を返す。 ◎ Returns the IDBTransaction the request was made within. If this as an open request, then it returns an upgrade transaction while it is live, or null otherwise.
- %request . `readyState$m
- %request が完了して[ いなければ `pending$l / いれば `done$l ]を返す。 ◎ Returns "pending" until a request is complete, then returns "done".
`result@m 取得子~手続きは: ◎ The result getter steps are:
- ~IF[ コレの`済んだか$ ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's done flag is false, then throw an "InvalidStateError" DOMException.
- ~RET [ コレの`結果$ ~NEQ ε ならば それ / ~ELSE_(すなわちコレの`~error$ ~NEQ ε ) `undefined^jv ] ◎ Otherwise, return this's result, or undefined if the request resulted in an error.
【 結果 ~NEQ ε の場合でも,結果~自身は `undefined^jv にもなり得る ( `IDBObjectStore.get()$m の注記を見よ)。 】
`error@m 取得子~手続きは: ◎ The error getter steps are:
- ~IF[ コレの`済んだか$ ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's done flag is false, then throw an "InvalidStateError" DOMException.
- ~RET[ コレの`~error$ ~NEQ ε ならば それ / ~ELSE_(すなわちコレの`結果$ ~NEQ ε ならば) ~NULL ] ◎ Otherwise, return this's error, or null if no error occurred.
`transaction@m 取得子~手続きは ⇒ ~RET [ コレの`設置-先~tx$ ~NEQ ε ならば それ / ~ELSE_ ~NULL ] ◎ The transaction getter steps are to return this's transaction.
注記: この取得子は、 ある種の要請 — `IDBFactory.open()$m から返される`要請$など — においては ~NULL を返すこともある。 ◎ NOTE: The transaction getter can return null for certain requests, such as for requests returned from open().
`onsuccess@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `success$et である。 ◎ The onsuccess attribute is an event handler IDL attribute whose event handler event type is success.
`onerror@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `error$et である。 ◎ The onerror attribute is an event handler IDL attribute whose event handler event type is error event.
`IDBDatabase$I 上の `~open要請$を返す各種~methodは、[ `blocked$et, `upgradeneeded$et ]~eventを~listenできるように拡張された~interfaceを利用する。 ◎ Methods on IDBDatabase that return a open request use an extended interface to allow listening to the blocked and upgradeneeded events.
[`Exposed$=(Window,Worker)]
interface `IDBOpenDBRequest@I : `IDBRequest$I {
// ~event~handler:
attribute `EventHandler$I `onblocked$m;
attribute `EventHandler$I `onupgradeneeded$m;
};
`onblocked@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `blocked$et である。 ◎ The onblocked attribute is an event handler IDL attribute whose event handler event type is blocked.
`onupgradeneeded@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `upgradeneeded$et である。 ◎ The onupgradeneeded attribute is an event handler IDL attribute whose event handler event type is upgradeneeded.
4.2. ~event~interface
この仕様は、 次の~custom~interfaceによる~eventを発火する: ◎ This specification fires events with the following custom interfaces:
[`Exposed$=(Window,Worker)] interface `IDBVersionChangeEvent@I : `Event$I { `constructor@(`DOMString$ %type, optional `IDBVersionChangeEventInit$I %eventInitDict = {}); readonly attribute `unsigned long long$ `oldVersion$m; readonly attribute `unsigned long long$? `newVersion$m; }; dictionary `IDBVersionChangeEventInit@I : `EventInit$I { `unsigned long long$ `oldVersion@m = 0; `unsigned long long$? `newVersion@m = null; };
~eventは、 `DOM^cite `§ ~eventの構築-法@~DOM4#constructing-events$ に定義されるとおり構築される。 ◎ Events are constructed as defined in DOM § 2.5 Constructing events.
`~version変更~eventを発火する@ ときは、 所与の ( %~target, %~event名, %旧~version, %新~version ) に対し,次を走らす: ◎ To fire a version change event named e at target given oldVersion and newVersion, run these steps:
- %~event ~LET `~eventを作成する$( `IDBVersionChangeEvent$I ) ◎ Let event be the result of creating an event using IDBVersionChangeEvent.
- %~event の各種~属性を次のように初期化する ⇒# `type$m ~SET %~event名, `bubbles$m ~SET ~F, `cancelable$m ~SET ~F, `oldVersion$m ~SET %旧~version, `newVersion$m ~SET %新~version ◎ • Set event’s type attribute to e. • Set event’s bubbles and cancelable attributes to false. • Set event’s oldVersion attribute to oldVersion. • Set event’s newVersion attribute to newVersion.
- ~RET `Dispatch$( %~target, %~event ) ◎ Let legacyOutputDidListenersThrowFlag be false. ◎ Dispatch event at target with legacyOutputDidListenersThrowFlag. ◎ Return legacyOutputDidListenersThrowFlag.
注記: この~algoの結果は利用されないこともある。 ◎ NOTE: The return value of this algorithm is not always used.
【 各種~event型の一覧 】
便宜のため、 この訳では,この仕様が利用する各種~event型を以下に要約する。
これらの~eventは、[ `要請$/`~tx$/`接続$ ] %~target に向けて発火される。 ~eventは、 `親~targetを取得する$~algoを通して,複数の~objに伝播する場合もある。 親~targetは %~target に応じて次になる ⇒# `~open要請$ならば ~NULL / 他の`要請$ならば %~target の`設置-先~tx$ / `~tx$ならば %~target が`専属する$`接続$ / `接続$ならば ~NULL
~event | 発火-時機と~target |
---|---|
`versionchange$et | `~db$を昇格-(または削除-)しようとしたとき、 同じ~dbを~openしている他の各`接続$に向けて発火される。 |
`close$et | `接続$が例外的な状況下で~closeされたとき、 当の接続に向けて発火される。 |
`upgradeneeded$et | `~db$を~openした際に`昇格~tx$が生じたとき、 当の`~open要請$に向けて発火される。 |
`blocked$et | [ 他の`接続$がまだ `~close済み$i でない ]ために[ `~db接続を~openする$ / `~dbを削除する$ ]`要請$が阻まれたとき、 当の`~open要請$に向けて発火される。 |
`success$et | `要請$が成功したとき、 当の要請に向けて発火される。 |
`error$et | 何らかの~errorにより`要請$が失敗したとき、 当の要請に向けて発火される。 |
`complete$et | `~tx$が`~commit$されたとき、 当の~txに向けて発火される。 |
`abort$et | `~tx$が~errorまたは `abort()^m により`中止-$されたとき、 当の~txに向けて発火される。 |
4.3. `IDBFactory^I ~interface
`~db$~objは、 `IDBFactory$I ~interface上の各種~methodを通して~accessされる。 この~interfaceを実装する単独の~objは、 Indexed DB 演算を~supportする環境の大域~scopeに在る。 ◎ 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 mixin `WindowOrWorkerGlobalScope!I { [`SameObject$] readonly attribute `IDBFactory$I `indexedDB$m; };
`indexedDB@m 属性は、 索引付き~dbの能力に~accessするための仕組みを,~appに供する。 ◎ The indexedDB attribute provides applications a mechanism for accessing capabilities of indexed databases.
[`Exposed$=(Window,Worker)] interface `IDBFactory@I { [`NewObject$] `IDBOpenDBRequest$I `open$m( `DOMString$ %name, optional [`EnforceRange$] `unsigned long long$ %version ); [`NewObject$] `IDBOpenDBRequest$I `deleteDatabase$m( `DOMString$ %name ); `Promise$<`sequence$<`IDBDatabaseInfo$I>> `databases$m(); short `cmp$m( `any$ %first, `any$ %second ); }; dictionary `IDBDatabaseInfo@I { `DOMString$ `name@m; `unsigned long long$ `version@m; };
- %request = `indexedDB$m . `open(name)$m
- `名前$db %name の`~db$への`接続$を,該当する`~db$が[ 存在するならば その現在の`~version$db / 存在しないならば`~version$db 1 ]で~openするよう要請する。 成功した場合の %request ( `IDBOpenDBRequest$I )の `result$m は、 その~dbへの`接続$になる。 ◎ 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$m . `open(name, version)$m
-
`名前$db %name の`~db$への`接続$を,指定した~version %version で~openするよう要請する。 該当する~db %db が存在する場合,その`~version$dbが:
- %version より低い場合、[ %db を~openしている, かつ `versionchange$et ~eventに呼応して %db を~closeしていない ]`接続$が他にあるならば、 要請は`阻まれ$,それらすべてが~closeされてから昇格が生じることになる。
- %version より高い場合、 要請は失敗することになる。
成功した場合の %request ( `IDBOpenDBRequest$I )の `result$m は、 当の`接続$になる。
◎ 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 they all 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$m . `deleteDatabase(name)$m
- 名前 %name の`~db$を削除するよう要請する。 該当する~db %db が存在する場合、[ %db を~openしている, かつ `versionchange$et ~eventに呼応して %db を~closeしていない ]`接続$があるならば,要請は`阻まれ$ることになる。 成功した場合の %request の `result$m は、 ~NULL になる。 ◎ 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 they all close. If the request is successful request’s result will be null.
- %result = await `indexedDB$m . `databases$m()
- [ `~storage~key$に専属する各~dbの名前と~versionからなる~obj ]たちが成す[ ~snapshotを与える~list ]に解決される~promiseを返す。 ◎ Returns a promise which resolves to a list of objects giving a snapshot of the names and versions of databases within the storage key.
- この~APIは、 ~dbの利用を~~見直す~web~app用に意図される — 例えば、 ~siteの~codeの早期~versionを片付けるなど。 結果は~snapshotであることに注意 — この文脈や他の文脈により~dbを[ 作成する/昇格する/削除する ]要請との間で[ ~dataの収集-順, 対する応答の送達-順 ]についての保証は無い。 ◎ This API is intended for web applications to introspect the use of databases, for example to clean up from earlier versions of a site’s code. Note that the result is a snapshot; there are no guarantees about the sequencing of the collection of the data or the delivery of the response with respect to requests to create, upgrade, or delete databases by this context or others.
`open(name, version)@m ~method手続きは: ◎ The open(name, version) method steps are:
- ~IF[ %version ~EQ 0 ] ⇒ ~THROW `TypeError$E ◎ If version is 0 (zero), throw a TypeError.
- %~storage~key ~LET `~storage~keyを得する$( コレに`関連な設定群~obj$ ) ◎ Let environment be this's relevant settings object. ◎ Let storageKey be the result of running obtain a storage key given environment.\
- ~IF[ %~storage~key ~EQ `失敗^i ] ⇒ ~THROW `SecurityError$E ◎ If failure is returned, then throw a "SecurityError" DOMException and abort these steps.
- %要請 ~LET 新たな`~open要請$ ◎ Let request be a new open request.
-
この段は、 `並列的$に走らす: ◎ Run these steps in parallel:
-
%結果 ~LET `~db接続を~openする$( %~storage~key, %name, %version, %要請 ) ◎ Let result be the result of opening a database connection, with storageKey, name, version if given and undefined otherwise, and request.
注記: 名前 %name の`~db$が存在しなければ、 新たな`~db$が作成される。 %version が与えられていない場合、 接続は,[ 既存の~dbに対しては その`~version$dbを変更することなく / 新たな~dbに対しては その`~version$dbを 1 にして ]~openすることになる。 【! details 】 ◎ 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.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- %要請 の ⇒# `済んだか$ ~SET ~T, `結果$ ~SET ε, `~error$ ~SET ε ◎ ↓
-
~IF[ %結果 は~errorである ]:
- %要請 の`~error$ ~SET %結果
- `~eventを発火する$( %要請, `error$et ) — 次のように初期化して ⇒# `bubbles$m 属性 ~SET ~T, `cancelable$m 属性 ~SET ~T
-
~ELSE:
- %要請 の`結果$ ~SET %結果
- `~eventを発火する$( %要請, `success$et )
注記: 上の【`~db接続を~openする$】手続きが`昇格~tx$を稼働させた場合、 この段は,それが`完遂-$した後に走ることになる。 これは、 別の~versionへの昇格が起こりつつある場合に,最初に`接続$上に `success$et ~eventを発火して、 ~scriptが[ `versionchange$et ~event用の~listenerを登録する機会c ]を得られることを確保する【?】。 ◎ NOTE: If the steps above resulted in an upgrade transaction being run, these steps will run after that transaction finishes. This ensures that in the case where another version upgrade is about to happen, the success event is fired on the connection first so that the script gets a chance to register a listener for the versionchange event.
注記: ここで,通常の[ `~success~eventを発火する$ / `~error~eventを発火する$ ]手続きを適用しないのは、 要請の`設置-先~tx$がないためである (その手続きは,`設置-先~tx$を配送-前に作動化して配送-後に作動中でなくする)。 【! details 】 ◎ Why aren’t the steps to fire a success event or fire an error event used? ◎ There is no transaction associated with the request (at this point), so those steps — which activate an associated transaction before dispatch and deactivate the transaction after dispatch — do not apply.
-
- ~RET %要請 を表現する,新たな `IDBOpenDBRequest$I ~obj ◎ Return a new IDBOpenDBRequest object for request.
`deleteDatabase(name)@m ~method手続きは: ◎ The deleteDatabase(name) method steps are:
- %~storage~key ~LET `~storage~keyを得する$( コレに`関連な設定群~obj$ ) ◎ Let environment be this's relevant settings object. ◎ Let storageKey be the result of running obtain a storage key given environment.\
- ~IF[ %~storage~key ~EQ `失敗^i ] ⇒ ~THROW `SecurityError$E ◎ If failure is returned, then throw a "SecurityError" DOMException and abort these steps.
- %要請 ~LET 新たな`~open要請$ ◎ Let request be a new open request.
-
この段は、 `並列的$に走らす: ◎ Run these steps in parallel:
- %結果 ~LET `~dbを削除する$( %~storage~key, %name, %要請 ) ◎ Let result be the result of deleting a database, with storageKey, name, and request.
- %要請 の`処理-済みか$ ~SET ~T ◎ Set request’s processed flag to true.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- %要請 の ⇒# `済んだか$ ~SET ~T, `結果$ ~SET ε, `~error$ ~SET ε ◎ ↓
-
~IF[ %結果 は~errorである ]:
- %要請 の`~error$ ~SET %結果
- `~eventを発火する$( %要請, `error$et ) — 次のように初期化して ⇒# `bubbles$m 属性 ~SET ~T, `cancelable$m 属性 ~SET ~T
-
~ELSE:
- %要請 の`結果$ ~SET ε
- `~version変更~eventを発火する$( %要請, `success$et, %結果, ~NULL )
注記: この時点では、 要請の`設置-先~tx$はないので、 通常の[ `~success~eventを発火する$ / `~error~eventを発火する$ ]手続きは (それは,`設置-先~tx$を配送-前に作動化して配送-後に作動中でなくする), 適用できない。 また、 ここでの `success$et ~eventは `IDBVersionChangeEvent$I であり, `oldVersion^m, `newVersion^m も含んでいる。 【! details 】 ◎ Why aren’t the steps to fire a success event or fire an error event used? ◎ There is no transaction associated with the request, so those steps — which activate an associated transaction before dispatch and deactivate the transaction after dispatch — do not apply. ◎ Also, the success event here is a IDBVersionChangeEvent which includes the oldVersion and newVersion details.
- ~RET %要請 を表現する,新たな `IDBOpenDBRequest$I ~obj ◎ Return a new IDBOpenDBRequest object for request.
`databases()@m ~method手続きは: ◎ The databases() method steps are:
- %~storage~key ~LET `~storage~keyを得する$( コレに`関連な設定群~obj$ ) ◎ Let environment be this's relevant settings object. ◎ Let storageKey be the result of running obtain a storage key given environment.\
- ~IF[ %~storage~key ~EQ `失敗^i ] ⇒ ~RET `却下される~promise$( `SecurityError$E 例外 ) ◎ If failure is returned, then return a promise rejected with a "SecurityError" DOMException
- %p ~LET `新たな~promise$ ◎ Let p be a new promise.
-
この段は、 `並列的$に走らす: ◎ Run these steps in parallel:
- %~db群 ~LET %~storage~key に`専属する$`~db$たちからなる`集合$ ⇒ ~IF[ 何らかの理由でこれを決定できない ] ⇒# `~promiseを却下する$( %p, 適切な~error(例: `UnknownError$E 例外)); ~RET ◎ Let databases be the set of databases in storageKey. If this cannot be determined for any reason, then reject p with an appropriate error (e.g. an "UnknownError" DOMException) and terminate these steps.
- %~db~list ~LET 新たな`~list$ ◎ Let result be a new list.
-
%~db群 を成す ~EACH( `~db$ %~db ) に対し: ◎ For each db of databases:
- %info ~LET 新たな `IDBDatabaseInfo$I 辞書 ◎ Let info be a new IDBDatabaseInfo dictionary.
- %info[ "`name^m" ] ~SET %~db の`名前$db, ◎ Set info’s name dictionary member to db’s name.
- %info[ "`version^m" ] ~SET %~db の `~version$db ◎ Set info’s version dictionary member to db’s version.
- %~db~list に %info を`付加する$ ◎ Append info to result.
【 %~db群 の順序は定義されていないので、 結果の順序も定義されないことになる。 】
- `~promiseを解決する$( %p, %~db~list ) ◎ Resolve p with result.
- ~RET %p ◎ Return p.
🚧 これは、 この版による新たな~methodである。 [ Chrome 71, Edge 79, Firefox 126, Safari 14 ]から~supportされている。 🚧 ◎ 🚧 The databases() method is new in this edition. It is supported in Chrome 71, Edge 79, Firefox 126, and Safari 14. 🚧
- %result = `indexedDB$m . `cmp(key1, key2)$m
- 2 個の値を`~key$として比較した結果を,次で与える数として返す ⇒# %key1 と %key2 は`等しい$ならば 0, %key1 は %key2 `より小さい$ならば −1, %key1 は %key2 `より大きい$ならば 1 ◎ Compares two values as keys. Returns -1 if key1 precedes key2, 1 if key2 precedes key1, and 0 if the keys are equal.
- %key1, %key2 のいずれかが`~key$として妥当でない場合、 `DataError$E が投出される。 ◎ Throws a "DataError" DOMException if either input is not a valid key.
`cmp(first, second)@m ~method手続きは: ◎ The cmp(first, second) method steps are:
- %a ~LET `Key$( %first ) ? ◎ Let a be the result of converting a value to a key with first. Rethrow any exceptions. ◎ If a is invalid, throw a "DataError" DOMException.
- %b ~LET `Key$( %second ) ? ◎ Let b be the result of converting a value to a key with second. Rethrow any exceptions. ◎ If b is invalid, throw a "DataError" DOMException.
- ~RET `Compare$( %a, %b ) ◎ Return the results of comparing two keys with a and b.
4.4. `IDBDatabase^I ~interface
【! TODO Add example. Should examples be in a separate section?】`IDBDatabase$I ~interfaceは、 `~db$への`接続$を表現する。 ◎ The IDBDatabase interface represents a connection to a database.
[ ~AND↓ を満たしている`接続$ ]を表現する `IDBDatabase$I ~objは、 ~garbage収集しないモノトスル:
- `状態$Cn ~EQ `~open中$i
- [ `abort$et, `error$et, `versionchange$et ]いずれかの型の~event~listenerが登録されている
`IDBDatabase$I ~objを~garbage収集するときは、 その前に,それが表現する`接続$を`~close$するモノトスル。
◎ An IDBDatabase object must not be garbage collected if its associated connection's close pending flag is false and it has one or more event listeners registers whose type is one of abort, error, or versionchange. If an IDBDatabase object is garbage collected, the associated connection must be closed.
[`Exposed$=(Window,Worker)]
interface `IDBDatabase@I : `EventTarget$I {
readonly attribute `DOMString$ `name$m;
readonly attribute `unsigned long long$ `version$m;
readonly attribute `DOMStringList$I `objectStoreNames$m;
[`NewObject$] `IDBTransaction$I `transaction$m(
(`DOMString$ or `sequence$<`DOMString$>) %storeNames,
optional `IDBTransactionMode$I %mode = `readonly$l
optional `IDBTransactionOptions$I %options = {}
);
`undefined$ `close$m();
[`NewObject$] `IDBObjectStore$I `createObjectStore$m(
`DOMString$ %name,
optional `IDBObjectStoreParameters$I %options = {}
);
`undefined$ `deleteObjectStore$m(
`DOMString$ %name
);
// ~event~handler:
attribute `EventHandler$I `onabort$m;
attribute `EventHandler$I `onclose$m;
attribute `EventHandler$I `onerror$m;
attribute `EventHandler$I `onversionchange$m;
};
enum `IDBTransactionDurability@I { `default@l, `strict@l, `relaxed@l };
dictionary `IDBTransactionOptions@I {
`IDBTransactionDurability$I `durability@mb = `default$l;
};
dictionary `IDBObjectStoreParameters@I {
(`DOMString$ or `sequence$<`DOMString$>)? `keyPath@mb = null;
`boolean$ `autoIncrement@mb = false;
};
- %connection . `name$m
- 接続先~dbの`名前$dbを返す。 ◎ Returns the name of the database.
- %connection . `version$m
- 接続先~dbの`~version$dbを返す。 ◎ Returns the version of the database.
`name@m 取得子~手続きは ⇒ ~RET コレ↗の`名前$db ◎ The name getter steps are to return this's associated database's name.
注記: この属性は、 `値を保持し続ける$。 ◎ NOTE: The name attribute returns this name even if this's close pending flag is true. In other words, the value of this attribute stays constant for the lifetime of the IDBDatabase instance.
`version@m 取得子~手続きは ⇒ ~RET コレの`~version$Cn ◎ The version getter steps are to return this's version.
注記: この属性は、 コレの`状態$Cn ~EQ `~open中$i の間は,コレ↗の`~version$dbと同じ値を返し、 それ以降も同じ`値を保持し続ける$。 【! details 】 ◎ 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.
- %connection . `objectStoreNames$m
- 接続先`~db$に`専属する$各`保管庫$の`名前$Osたちが成す~listを返す。 ◎ Returns a list of the names of object stores in the database.
- %store = %connection . `createObjectStore(name [, options])$m
- 接続先`~db$に`専属する$, かつ,`名前$Os %name の, %options を伴う新たな`保管庫$を作成した上で、 それを`~access先$とする 新たな `IDBObjectStore$I を返す。 ◎ Creates a new object store with the given name and options and returns a new IDBObjectStore.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E を投出する。 ◎ Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
- %connection . `deleteObjectStore(name)$m
- 接続先`~db$に`専属する$,`名前$Os %name の`保管庫$を削除する。 ◎ Deletes the object store with the given name.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E を投出する。 ◎ Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
`objectStoreNames@m 取得子~手続きは: ◎ The objectStoreNames getter steps are:
- %名前~群 ~LET [ コレの`保管庫~集合$Cnを成す各`保管庫$の`名前$Os ]たちが成す`~list$ ◎ Let names be a list of the names of the object stores in this's object store set.
- ~RET `~sort済み名前~listを作成する$( %名前~群 ) ◎ Return the result (a DOMStringList) of creating a sorted name list with names.
注記: この属性は、[ コレの`状態$Cn ~EQ `~open中$i ]の間は,コレ↗に専属する各`保管庫$の`名前$Osたちが成す~listと同じ値を返し、 それ以降も同じ`値を保持し続ける$。 ◎ 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. But once the connection has closed, this attribute will not reflect changes made with a later upgrade transaction.
`createObjectStore(name, options)@m ~method手続きは: ◎ The createObjectStore(name, options) method steps are:
- %~tx ~LET コレ↗の`昇格~tx$db ◎ Let database be this's associated database. ◎ Let transaction be database’s upgrade transaction if it is not null,\
-
~IF[ %~tx ~EQ ε ] ⇒ ~THROW `InvalidStateError$E
【 %~tx がコレ↗に`専属しない$場合も例外を投出するべきでは? 】
◎ or throw an "InvalidStateError" DOMException otherwise. - ~IF[ %~tx の`状態$tx ~NEQ `作動中$i ] ⇒ ~THROW `TransactionInactiveError$E ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %keyPath ~LET %options[ "`keyPath$mb" ] ◎ Let keyPath be options’s keyPath member if it is not undefined or null, or null otherwise.
- ~IF[ %keyPath ~NEQ ~NULL ]~AND[ %keyPath は`妥当な~key~path$でない ] ⇒ ~THROW `SyntaxError$E ◎ If keyPath is not null and is not a valid key path, throw a "SyntaxError" DOMException.
- ~IF[ コレの`保管庫~集合$Cn内に[ `名前$Os ~EQ %name ]なる`保管庫$がある ] ⇒ ~THROW `ConstraintError$E ◎ If an object store named name already exists in database throw a "ConstraintError" DOMException.
- %自動生成か ~LET %options[ "`autoIncrement$mb" ] ◎ Let autoIncrement be options’s autoIncrement member.
- ~IF[ %自動生成か ~EQ ~T ] ⇒ ~IF[ %keyPath ~EQ 空な `DOMString$I 値である ]~OR[ %keyPath は `~SeqDS$ 型である ] ⇒ ~THROW `InvalidAccessError$E ◎ If autoIncrement is true and keyPath is an empty string or any sequence (empty or otherwise), throw an "InvalidAccessError" DOMException.
- %保管庫 ~LET 次のようにされた,新たな`保管庫$ ⇒# コレ↗に`専属する$, `~record~list$Os ~SET 空~list, `名前$Os ~SET %name, `~key生成器$を[ %自動生成か ~EQ ~T ならば有する / ~ELSE_ 有さない ], `~key~path$Os ~SET [ %keyPath ~NEQ ~NULL ならば %keyPath / ~ELSE_ ε ] ◎ Let store be a new object store in database. 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 not null, set the created object store's key path to keyPath.
- コレの`保管庫~集合$Cnに %保管庫 を追加する 【この段は、この訳による補完】
- ~RET 次のようにされた,新たな`保管庫~handle$ %H ⇒# %H↗ ~EQ %保管庫, %H は %~tx に`専属する$ ◎ Return a new object store handle associated with store and transaction.
この~methodは、 新たな`保管庫$を作成した上で,それを`~access先$とする新たな`保管庫~handle$を返す。 この~methodを~callできるのは、 `昇格~txの中$からに限られることに注意。 ◎ 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.
この~methodは,コレ上の `objectStoreNames$m 属性を同期的に改変する。 ◎ This method synchronously modifies the objectStoreNames property on the IDBDatabase instance on which it was called.
実装によっては、[ この~methodが何かを返して,~db内に`保管庫$を作成する演算を~queueした後 ]に,問題になる可能性がある。 例えば、[ 新たに作成された`保管庫$についての~metadataを,~dbに非同期に挿入する所 ],あるいは[ ~quota事由から,利用者に許可を請う必要があり得る所 ]で。 そうなり得る場合でも、 実装は:
- `IDBObjectStore$I ~objを作成して返すモノトスル。
-
加えて,`保管庫$の作成ngに失敗したときは、[ 失敗の事由に適切な~error名† ]を入力に `~txを中止-$する手続きを行って, %~tx を`中止-$するモノトスル。
† 例えば ~quota事由に因り`保管庫$の作成ngに失敗した場合は、 `QuotaExceededError$E を利用するモノトスル。
`deleteObjectStore(name)@m ~method手続きは: ◎ The deleteObjectStore(name) method steps are:
- %~tx ~LET コレ↗の`昇格~tx$db ◎ Let database be this's associated database. ◎ Let transaction be database’s upgrade transaction if it is not null,\
-
~IF[ %~tx ~EQ ε ] ⇒ ~THROW `InvalidStateError$E
【 %~tx がコレ↗に`専属しない$場合も例外を投出するべきでは? 】
◎ or throw an "InvalidStateError" DOMException otherwise. - ~IF[ %~tx の`状態$tx ~NEQ `作動中$i ] ⇒ ~THROW `TransactionInactiveError$E ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %保管庫 ~LET コレの`保管庫~集合$Cn内の[ `名前$Os ~EQ %name ]なる`保管庫$ ◎ Let store be the object store named name in database,\
- ~IF[ %保管庫 ~EQ ε ] ⇒ ~THROW `NotFoundError$E ◎ or throw a "NotFoundError" DOMException if none.
- コレの`保管庫~集合$Cnから %保管庫 を除去する ◎ Remove store from this's object store set.
- ~IF[ %~tx に`専属する$, かつ %保管庫 を`~access先$とする`保管庫~handle$ %H がある ] ⇒ %H の`索引~集合$OsHを空にする ◎ If there is an object store handle associated with store and transaction, remove all entries from its index set.
- コレ↗内の %保管庫 を( %保管庫 に`専属する$`索引$たちも込みで)破壊する ◎ Destroy store.
この~methodは、 この`接続$↗に専属している,名前 %name の`保管庫$を破壊する。 この~methodを~callできるのは、 `昇格~txの中$からに限られることに注意。 ◎ 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.
この~methodは,コレ上の `objectStoreNames$m 属性を同期的に改変する。 ◎ This method synchronously modifies the objectStoreNames property on the IDBDatabase instance on which it was called.
- %transaction = %connection . `transaction(scope [, mode [, options ] ])$m
- %connection に`専属する$新たな`~tx$を返す ⇒# %scope が,その`視野$を与える( 1 個の`名前$Os, または 1 個以上の`名前$Osからなる配列)。 %mode が,その`~mode$を与える( `readonly$l / `readwrite$l )。 %options の `durability$mb が,その`耐久能~hint$を与える( `strict$l / `relaxed$l / `default$l )。 ◎ Returns a new transaction with the given scope (which can be a single object store name or an array of names), mode ("readonly" or "readwrite"), and additional options including durability ("default", "strict" or "relaxed").
- 既定の %mode は `readonly$l であり、 既定の `durability$mb は `default$l である。 ◎ The default mode is "readonly" and the default durability is "default".
- %connection . `close$m()
- %connection を~closeする — ~closeし終えるのは、 %connection に`専属する$すべての`~tx$が完遂された時点になる。 ◎ Closes the connection once all running transactions have finished.
`transaction(storeNames, mode, options)@m ~method手続きは: ◎ The transaction(storeNames, mode, options) method steps are:
- ~IF[ コレ↗の`昇格~tx$db ~NEQ ε ]~AND[ コレ↗の`昇格~tx$dbは`生きて$いる ] ⇒ ~THROW `InvalidStateError$E ◎ If a live upgrade transaction is associated with the connection, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`状態$Cn ~NEQ `~open中$i ] ⇒ ~THROW `InvalidStateError$E ◎ If this's close pending flag is true, then throw an "InvalidStateError" DOMException.
- %視野 ~LET %storeNames の型に応じて ⇒# `~SeqDS$ ならば,その中の一意な文字列たちが成す集合(集合なので,重複するものは一つにする)/ `DOMString$I ならば,その文字列のみからなる集合 ◎ Let scope be the set of unique strings in storeNames if it is a sequence, or a set containing one string equal to storeNames otherwise.
- ~IF[ %視野 内に,コレの`保管庫~集合$Cn内のどの`保管庫$の`名前$Osにも一致しないものがある ] ⇒ ~THROW `NotFoundError$E ◎ If any string in scope is not the name of an object store in the connected database, throw a "NotFoundError" DOMException.
- ~IF[ %視野 は 空である ] ⇒ ~THROW `InvalidAccessError$E ◎ If scope is empty, throw an "InvalidAccessError" DOMException.
- ~IF[ %mode ~NIN { `readonly$l, `readwrite$l } ] ⇒ ~THROW `TypeError$E ◎ If mode is not "readonly" or "readwrite", throw a TypeError.
- %~tx ~LET 新たに`作成-$された`~tx$ — その ⇒# `視野$ ~SET [ コレの`保管庫~集合$Cn内の, %視野 により指示される`保管庫$ ]たちが成す集合, `~mode$ ~SET %mode, `専属する$`接続$ ~SET コレ, `耐久能~hint$ ~SET %options[ "`durability$mb" ] ◎ Let transaction be a newly created transaction with this connection, mode, options’ durability member, and the set of object stores named in scope.
- %~tx の`片付ける~event~loop$ ~SET 現在の`~event~loop$ ◎ Set transaction’s cleanup event loop to the current event loop.
- ~RET %~tx を表現する `IDBTransaction$I ~obj ◎ Return an IDBTransaction object representing transaction.
🚧 `durability$m は、 この版による新たな~optionである。 [ Chrome 82, Edge 82, Firefox 126, Safari 15 ]から~supportされている。 🚧 ◎ 🚧 The durability option is new in this edition. It is supported in Chrome 82, Edge 82, Firefox 126, and Safari 15. 🚧
注記: 作成された~txは、 その`存続期間$の規則に従う。 ◎ NOTE: The created transaction will follow the lifetime rules.
`close()@m ~method手続きは ⇒ `~db接続を~closeする$( コレ ) ◎ The close() method steps are: • Run close a database connection with this connection.
注記: 未決な`~tx$すべてが完了するまでは、 `接続$は実際には`~close$されない。 `close()$m に対する後続な~callには、 効果はない。 ◎ NOTE: The connection will not actually close until all outstanding transactions have completed. Subsequent calls to close() will have no effect.
`onabort@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `abort$et である。 ◎ The onabort attribute is an event handler IDL attribute whose event handler event type is abort.
`onclose@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `close$et である。 ◎ The onclose attribute is an event handler IDL attribute whose event handler event type is close.
`onerror@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `error$et である。 ◎ The onerror attribute is an event handler IDL attribute whose event handler event type is error.
`onversionchange@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `versionchange$et である。 ◎ The onversionchange attribute is an event handler IDL attribute whose event handler event type is versionchange.
4.5. `IDBObjectStore^I ~interface
`IDBObjectStore$I ~interfaceは、 `保管庫~handle$を表現する。 ◎ The IDBObjectStore interface represents an object store handle.
[`Exposed$=(Window,Worker)] interface `IDBObjectStore@I { attribute `DOMString$ `name$m; readonly attribute `any$ `keyPath$m; readonly attribute `DOMStringList$I `indexNames$m; [`SameObject$] readonly attribute `IDBTransaction$I `transaction$m; readonly attribute `boolean$ `autoIncrement$m; [`NewObject$] `IDBRequest$I `put$m( `any$ %value, optional `any$ %key ); [`NewObject$] `IDBRequest$I `add$m( `any$ %value, optional `any$ %key ); [`NewObject$] `IDBRequest$I `delete$m( `any$ %query ); [`NewObject$] `IDBRequest$I `clear$m(); [`NewObject$] `IDBRequest$I `get$m( `any$ %query ); [`NewObject$] `IDBRequest$I `getKey$m( `any$ %query ); [`NewObject$] `IDBRequest$I `getAll$m( optional `any$ %query, optional [`EnforceRange$] `unsigned long$ %count ); [`NewObject$] `IDBRequest$I `getAllKeys$m( optional `any$ %query, optional [`EnforceRange$] `unsigned long$ %count ); [`NewObject$] `IDBRequest$I `count$m( optional `any$ %query ); [`NewObject$] `IDBRequest$I `openCursor$m( optional `any$ %query, optional `IDBCursorDirection$I %direction = "next" ); [`NewObject$] `IDBRequest$I `openKeyCursor$m( optional `any$ %query, optional `IDBCursorDirection$I %direction = "next" ); `IDBIndex$I `index$m( `DOMString$ %name ); [`NewObject$] `IDBIndex$I `createIndex$m( `DOMString$ %name, (`DOMString$ or `sequence$<`DOMString$>) %keyPath, optional `IDBIndexParameters$I %options = {} ); `undefined$ `deleteIndex$m( `DOMString$ %name ); }; dictionary `IDBIndexParameters@I { `boolean$ `unique@mb = false; `boolean$ `multiEntry@mb = false; };
- %store . `name$m
- %store↗ の`名前$Osを返す。 ◎ Returns the name of the store.
- %store . `name$m = %newName
- %store↗ の`名前$Osを %newName に更新する。 ◎ Updates the name of the store to newName.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E が投出される。 ◎ Throws "InvalidStateError" DOMException if not called within an upgrade transaction.
- %store . `keyPath$m
- %store↗ の`~key~path$Os ~NEQ ε ならば それ / ~ELSE_ ~NULL を返す。 ◎ Returns the key path of the store, or null if none.
- %store . `indexNames$m
- %store↗ に`専属する$各`索引$の`名前$Ixたちが成す~listを返す。 ◎ Returns a list of the names of indexes in the store.
- %store . `transaction$m
- %store が`専属する$`~tx$を返す。 ◎ Returns the associated transaction.
- %store . `autoIncrement$m
- %store↗ が`~key生成器$を[ 有するならば ~T / 有さないならば ~F ]を返す。 ◎ Returns true if the store has a key generator, and false otherwise.
`name@m 取得子~手続きは ⇒ ~RET コレの`名前$OsH ◎ The name getter steps are to return this's name.
注記: この属性は、 コレが`専属する$~txが`完遂-$するまでは,コレ↗の`名前$Osと同じ値を返し、 それ以降も同じ`値を保持し続ける$。 【! details 】 ◎ Is this the same as the object store's name? ◎ As long as the transaction has not finished, this is the same as the associated object store's name. But once the transaction has finished, this attribute will not reflect changes made with a later upgrade transaction.
`name$m 設定子~手続きは: ◎ The name setter steps are:
- `状態を検査する$( コレ, `versionchange^l ) ? ◎ Let name be the given value. ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ 変則* If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, throw a "TransactionInactiveError" DOMException.
- %name ~LET `所与の値$ ◎ ↑
- ~IF[ コレの`名前$OsH ~EQ %name ] ⇒ ~RET ◎ If store’s name is equal to name, terminate these steps.
- ~IF[ コレが`専属する$`接続$の`保管庫~集合$Cnに[ `名前$Os ~EQ %name ]なる`保管庫$がある ] ⇒ ~THROW `ConstraintError$E ◎ If an object store named name already exists in store’s database, throw a "ConstraintError" DOMException.
- コレ↗の`名前$Os ~SET %name ◎ Set store’s name to name.
- コレの`名前$OsH ~SET %name ◎ Set this's name to name.
`keyPath@m 取得子~手続きは ⇒ ~RET コレ↗の`~key~path$Os %P に応じて,[ %P ~EQ ε ならば ~NULL / ~ELSE_ %P を `WEBIDL$r に従って,次の型として変換した結果 ] ⇒# %P は文字列であるならば `DOMString$I / %P は文字列たちが成す~listであるならば `~SeqDS$ ◎ The keyPath getter steps are to return this's object store's key path, or null if none. The key path is converted as a DOMString (if a string) or a sequence<DOMString> (if a list of strings), per [WEBIDL].
【この属性は、`値を保持し続ける$。】
注記: 返される値は、 コレの作成-時に利用した~instanceと同じではない。 しかしながら,この属性が~obj(特定的には `Array$jT )を返す場合、 毎回~同じ~instanceを返す。 返された~objの~prop値を変更しても,コレに効果を及ぼすことはない。 ◎ NOTE: 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.
`indexNames@m 取得子~手続きは: ◎ The indexNames getter steps are:
- %名前~群 ~LET [ コレの`索引~集合$OsHを成す各`索引$の`名前$Ix ]たちが成す`~list$ ◎ Let names be a list of the names of the indexes in this's index set.
- ~RET `~sort済み名前~listを作成する$( %名前~群 ) ◎ Return the result (a DOMStringList) of creating a sorted name list with names.
注記: この属性は、 コレが`専属する$~txが`完遂-$するまでは,コレ↗に専属する各`索引$の名前たちが成す~listと同じ値を返し、 それ以降も同じ`値を保持し続ける$。 【! deitails 】 ◎ Is this the same as object store's list of index names? ◎ As long as the transaction has not finished, this is the same as the associated object store's list of index names. But once the transaction has finished, this attribute will not reflect changes made with a later upgrade transaction.
`transaction@m 取得子~手続きは ⇒ ~RET コレが`専属する$~tx ◎ The transaction getter steps are to return this's transaction.
`autoIncrement@m 取得子~手続きは ⇒ ~RET ~IS[ コレ↗の`~key生成器$ ~NEQ ε ] ◎ The autoIncrement getter steps are to return true if this's object store has a key generator, and false otherwise.
【この属性は、`値を保持し続ける$。】
注記: 以下に挙げる~methodは、[ `~readonly~tx$の中で~callされた場合は `ReadOnlyError$E / `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E ]を投出する。 ◎ The following methods throw a "ReadOnlyError" DOMException if called within a read-only transaction, and a "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %store . `put(value [, key])$m
- %request = %store . `add(value [, key])$m
- %store↗ 内に新たな`~record$ { %key : %value } を追加する/更新するよう要請する。 ◎ Adds or updates a record in store with the given value and key.
- %store↗ の`~key~path$Os ~NEQ ε の場合、 %key は省略する必要がある — さもなければ `DataError$E が投出される。 【この場合の~keyは, %value から`~key~path$Osを用いて抽出される】 ◎ If the store uses in-line keys and key is specified a "DataError" DOMException will be thrown.
-
%store↗ 内に`~key$ %key を有する`~record$がすでに存在する場合:
- `put()$m に対しては、 新たな~recordで置換されることになる (すなわち,~recordの値が更新される)。
- `add()$m に対しては、 要請は失敗し, %request の 【! * 】`IDBRequest.error$m は `ConstraintError$E 例外に設定されることになる。
- 成功した場合の %request の `result$m は、 追加した(置換した)`~record$の`~key$になる。 ◎ If successful, request’s result will be the record's key.
- %request = %store . `delete(query)$m
- %store↗ の`~record~list$Osから[ %query が`表現する~key範囲$に入る~recordたち ]を削除するよう要請する。 ◎ Deletes records in store with the given key or in the given key range in query.
- 成功した場合の %request の `result$m は、 `undefined^jv になる。 ◎ If successful, request’s result will be undefined.
- %request = %store . `clear$m()
- %store↗ の`~record~list$Osを空にするよう要請する。 ◎ Deletes all records in store.
- 成功した場合の %request の `result$m は、 `undefined^jv になる。 ◎ If successful, request’s result will be undefined.
`addするかputする@ ときは、 所与の ( %~handle, %value, %key, %上書不可か ) に対し,次を走らす: ◎ To add or put with handle, value, key, and no-overwrite flag, run these steps:
- `状態を検査する$( %~handle, `readwrite^l ) ? ◎ Let transaction be handle’s transaction. ◎ Let store be handle’s object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException.
- %keyPath ~LET %~handle の`~key~path$Os ◎ ↓
- %生成器 ~LET %~handle の`~key生成器$ ◎ ↓
- ~IF[ %keyPath ~NEQ ε ]~AND[ %key ~NEQ ε ] ⇒ ~THROW `DataError$E ◎ If store uses in-line keys and key was given, throw a "DataError" DOMException.
- ~IF[ %keyPath ~EQ ε ]~AND[ %key ~EQ ε ]~AND[ %生成器 ~EQ ε ] ⇒ ~THROW `DataError$E ◎ If store uses out-of-line keys and has no key generator and key was not given, throw a "DataError" DOMException.
- ~IF[ %key ~NEQ ε ] ⇒ %key ~LET `Key$( %key ) ? ◎ If key was given, then: • Let r be the result of converting a value to a key with key. Rethrow any exceptions. • If r is invalid, throw a "DataError" DOMException. • Let key be r.
- %clone ~LET `~txの間に値を~cloneする$( %value, %~handle が`専属する$`~tx$ ) ? ◎ Let targetRealm be a user-agent defined Realm. ◎ Let clone be a clone of value in targetRealm during transaction. Rethrow any exceptions. ◎ Why create a copy of the value? ◎ The value is serialized when stored. Treating it as a copy here allows other algorithms in this specification to treat it as an ECMAScript value, but implementations can optimize this if the difference in behavior is not observable.
-
~IF[ %keyPath ~NEQ ε ]:
- %抽出d~key ~LET `Extract$( %clone, %keyPath, %生成器 ) ?
- ~IF[ %抽出d~key ~NEQ ε ] ⇒ %key ~SET %抽出d~key
- ~ELIF[ `~keyを値の中へ注入できるか検査する$( %clone, %keyPath ) の結果 ~EQ ~F ] ⇒ ~THROW `DataError$E
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( %~handle ) ⇒ `保管庫に~recordを格納する$( %~handle↗, %clone, %key, %上書不可か ) ◎ Let operation be an algorithm to run store a record into an object store with store, clone, key, and no-overwrite flag. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with handle and operation.
`delete(query)@m ~method手続きは: ◎ The delete(query) method steps are:
- `状態を検査する$( コレ, `readwrite^l ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException.
- %範囲 ~LET `Range$( %query, `~NULL不可^i ) ? ◎ Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `保管庫から~recordを削除する$( コレ↗, %範囲 ) ◎ Let operation be an algorithm to run delete records from an object store with store and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちが削除される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the records to be deleted.
注記: 他の~methodと違って、 この~methodの %query 引数は, 省略可能でなく, ~NULL 値も許容されない (すなわち,`全範囲$は指定できない)。 これは、 小さな~bugにより,保管庫の中を全~clearする~riskを抑制するためである。 ◎ NOTE: Unlike other methods which take keys or key ranges, this method does not allow null to be given as key. This is to reduce the risk that a small bug would clear a whole object store.
`clear()@m ~method手続きは: ◎ The clear() method steps are:
- `状態を検査する$( コレ, `readwrite^l ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `保管庫を~clearする$( コレ↗ ) ◎ Let operation be an algorithm to run clear an object store with store. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: 以下に挙げる~methodは、 `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E を投出する。 ◎ The following methods throw a "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %store . `get(query)$m
- %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初の~recordの`値$を検索取得するよう要請する。 ◎ Retrieves the value of the first record matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 該当する~recordが[ 在るならば その`値$/ 無いならば `undefined^jv ]になる。 ◎ If successful, request’s result will be the value, or undefined if there was no matching record.
- %request = %store . `getKey(query)$m
- %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初の~recordの`~key$を検索取得するよう要請する。 ◎ Retrieves the key of the first record matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 該当する~recordが[ 在るならば その`~key$/ 無いならば `undefined^jv ]になる。 ◎ If successful, request’s result will be the key, or undefined if there was no matching record.
- %request = %store . `getAll(query [, count])$m
- %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初から %count 個までの~recordの`値$たちを検索取得するよう要請する。 ◎ Retrieves the values of the records matching the given key or key range in query (up to count if given).
- 成功した場合の %request の `result$m は、 `値$たちが成す `Array$jT になる。 ◎ If successful, request’s result will be an Array of the values.
- %request = %store . `getAllKeys(query [, count])$m
- %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初から %count 個までの~recordの`~key$たちを検索取得するよう要請する。 ◎ Retrieves the keys of records matching the given key or key range in query (up to count if given).
- 成功した場合の %request の `result$m は、 `~key$たちが成す `Array$jT になる。 ◎ If successful, request’s result will be an Array of the keys.
- %request = %store . `count(query)$m
- %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$に入る~recordたち ]の総数を得るよう要請する。 ◎ Retrieves the number of records matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 得られた総数になる。 ◎ If successful, request’s result will be the count.
`get(query)@m ~method手続きは: ◎ The get(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
-
%範囲 ~LET `Range$( %query, `~NULL不可^i ) ? ◎ Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る最初の~entryを検索取得する$( コレ↗, %範囲, `値^i ) ◎ Let operation be an algorithm to run retrieve a value from an object store with the current Realm record, store, and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$ (範囲が指定された場合、 範囲に入る最初の既存の~record) の`値$が検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record value to be retrieved. If a range is specified, the method retrieves the first existing value in that range.
注記: この~methodによる要請の`結果$は、 所与の~keyを伴う~recordが存在しない場合も, `値$が `undefined^jv の~recordが存在する場合も, `undefined^jv 値になる。 両者を区別する必要があるときは、 同じ~keyで `openCursor()$m を利用できる — その`結果$は、 ~recordが存在しなければ ~NULL になる一方で,存在するときは[ `値$Cs ~SET `undefined^jv† ]にされた`~cursor$になる。 【† この訳では、内部処理~modelにおいては,値 ε により,そのような~recordが存在する場合とを区別している。】 ◎ NOTE: This method 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 use openCursor() with the same key. This will return a cursor with undefined as value if a record exists, or no cursor if no such record exists.
`getKey(query)@m ~method手続きは: ◎ The getKey(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query, `~NULL不可^i ) ? ◎ Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る最初の~entryを検索取得する$( コレ↗, %範囲, `~key^i ) ◎ Let operation be an algorithm to run retrieve a key from an object store with store and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$ (範囲が指定された場合、 範囲に入る最初の既存の~record) の`~key$が検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record key to be retrieved. If a range is specified, the method retrieves the first existing key in that range.
`getAll(query, count)@m ~method手続きは: ◎ The getAll(query, count) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
-
%範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~entryたちを検索取得する$( コレ↗, %範囲, %count, `値^i ) ◎ Let operation be an algorithm to run retrieve multiple values from an object store with the current Realm record, store, range, and count if given. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちの`値$が検索取得される。 ~NULL または省略時には,`全範囲$が利用される。 %count が指定されていて,範囲に入る~record数がそれを超える場合、 最初から %count 個までが検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record values to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count records in range, only the first count will be retrieved.
`getAllKeys(query, count)@m ~method手続きは: ◎ The getAllKeys(query, count) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
-
%範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~entryたちを検索取得する$( コレ↗, %範囲, %count, `~key^i ) ◎ Let operation be an algorithm to run retrieve multiple keys from an object store with store, range, and count if given. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちの`~key$が検索取得される。 ~NULL または省略時には,`全範囲$が利用される。 %count が指定されていて,範囲に入る~key数がそれを超える場合、 最初から %count 個までが検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record keys to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count keys in range, only the first count will be retrieved.
`count(query)@m ~method手続きは: ◎ The count(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~recordを数える$( コレ↗, %範囲 ) ◎ Let operation be an algorithm to run count the records in a range with store and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちが数えられる。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the records to be counted. If null or not given, an unbounded key range is used.
注記: 以下に挙げる~methodは、 `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E を投出する。 ◎ The following methods throw a "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %store . `openCursor([query [, direction = "next"]])$m
- [ %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$( %query が~NULL ならば`全範囲$)に入る~recordたち ]を,`方向$Cs %direction で反復する`~cursor$ ]を作成するよう要請する。 ◎ Opens a cursor over the records matching query, ordered by direction. If query is null, all records in store are matched.
- 成功した場合の %request の `result$m は、 範囲に入る~recordが[ 在るならば 反復-順で最初の~recordを指している `IDBCursorWithValue$I / 無いならば ~NULL ]になる。 ◎ If successful, request’s result will be an IDBCursorWithValue pointing at the first matching record, or null if there were no matching records.
- %request = %store . `openKeyCursor([query [, direction = "next"]])$m
- [ %store↗ の`~record~list$Os内の[ %query が`表現する~key範囲$( %query が~NULL ならば`全範囲$)に入る~recordたち ]を,`方向$Cs %direction で反復する`~cursor$ ]を作成するよう要請する。 作成される`~cursor$の`~keyのみか$Csは ~T に設定される (~cursorは、 ~recordの~keyのみを取得する)。 ◎ Opens a cursor with key only flag set to true over the records matching query, ordered by direction. If query is null, all records in store are matched.
- 成功した場合の %request の `result$m は、 範囲に入る~recordが[ 在るならば 反復-順で最初の~recordを指している `IDBCursor$I / 無いならば ~NULL ]になる。 ◎ If successful, request’s result will be an IDBCursor pointing at the first matching record, or null if there were no matching records.
`openCursor(query, direction)@m ~method手続きは: ◎ The openCursor(query, direction) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- %要請 ~LET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `~cursorを作成する$( コレ, `現在の~realm$, %direction, %範囲 ) ◎ Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to store, range set to range, and key only flag set to false. ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record and cursor. ◎ Let request be the result of running asynchronously execute a request with this and operation.
- コレの`要請$Cs ~SET %要請 ◎ Set cursor’s request to request.
- ~RET %要請 ◎ Return request.
注記: %query ~parameterは、 `~cursor$の`範囲$Csとして利用する[ `~key$/`~key範囲$ ]をとり得る。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) to use as the cursor's range. If null or not given, an unbounded key range is used.
`openKeyCursor(query, direction)@m ~method手続きは: ◎ The openKeyCursor(query, direction) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- %要請 ~LET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `~cursorを作成する$( コレ, `現在の~realm$, %direction, %範囲, `~keyのみ^i ) ◎ Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to store, range set to range, and key only flag set to true. ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record and cursor. ◎ Let request be the result of running asynchronously execute a request with this and operation.
- コレの`要請$Cs ~SET %要請 ◎ Set cursor’s request to request.
- ~RET %要請 ◎ Return request.
注記: %query ~parameterは、 `~cursor$の`範囲$Csとして利用する[ `~key$/`~key範囲$ ]をとり得る。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) to use as the cursor's range. If null or not given, an unbounded key range is used.
- %index = %store . `index(name)$m
- [ %store↗ に`専属する$,`名前$Ix %name の`索引$ ]を`~access先$とする,`索引~handle$( `IDBIndex$I )を返す。 ◎ Returns an IDBIndex for the index named name in store.
- %index = %store . `createIndex(name, keyPath [, options])$m
- %store↗ に`専属する$新たな`索引$を,所与の[ %name, %keyPath, %options ]を伴うように作成した上で、 それを`~access先$とする新たな `IDBIndex$I を返す。 [ %keyPath, %options ]が %store 内にすでにある~dataから `索引を拡充-@#_populating-an-index$できない拘束を定義する場合、 当の`昇格~tx$は `ConstraintError$E で`中止-$されることになる。 ◎ 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 transaction will abort with a "ConstraintError" DOMException.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E が投出される。 ◎ Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
- %store . `deleteIndex(name)$m
- %store↗ に`専属する$,`名前$Ix %name の`索引$を削除する。 ◎ Deletes the index in store with the given name.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E が投出される。 ◎ Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
`createIndex(name, keyPath, options)@m ~method手続きは: ◎ The createIndex(name, keyPath, options) method steps are:
- `状態を検査する$( コレ, `versionchange^l ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- ~IF[ コレの`索引~集合$OsHに[ `名前$Ix ~EQ %name ]なる`索引$がある ] ⇒ ~THROW `ConstraintError$E ◎ If an index named name already exists in store, throw a "ConstraintError" DOMException.
- ~IF[ %keyPath は`妥当な~key~path$でない ] ⇒ ~THROW `SyntaxError$E ◎ If keyPath is not a valid key path, throw a "SyntaxError" DOMException.
- %一意か ~LET %options[ "`unique$mb" ] ◎ Let unique be options’s unique member.
- %複-~entryか ~LET %options[ "`multiEntry$mb" ] ◎ Let multiEntry be options’s multiEntry member.
- ~IF[ %keyPath は`~SeqDS$ 型である ]~AND[ %複-~entryか ~EQ ~T ] ⇒ ~THROW `InvalidAccessError$E ◎ If keyPath is a sequence and multiEntry is true, throw an "InvalidAccessError" DOMException.
- %索引 ~LET 新たな`索引$† — その ⇒# コレ↗に`専属する$, `名前$Ix ~SET %name, `~key~path$Ix ~SET %keyPath, `一意か$Ix ~SET %一意か, `複-~entryか$Ix ~SET %複-~entryか ◎ Let index be a new index in store. Set index’s name to name, key path to keyPath, unique flag to unique, and multiEntry flag to multiEntry.
- %索引 をコレの`索引~集合$OsHに追加する ◎ Add index to this's index set.
- ~RET 次のようにされた,新たな`索引~handle$ %H ⇒# %H↗ ~EQ %索引, %H はコレに`専属する$, `名前$IxH ~SET %name ◎ Return a new index handle associated with index and this.
【† 索引の`~record~list$Ixは、 自動的にコレの`~record~list$Osにより拡充されることになる。 】
この~methodは、 コレに`専属する$, 名前 %name の新たな`索引$を作成した上で、 それを`~access先$とする 新たな`索引~handle$を返す。 この~methodを~callできるのは、 `昇格~txの中$からに限られることに注意。 ◎ 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.
作成するよう要請された索引は、[ 自身が`専属する$`保管庫$に許容される~data ]についての拘束を伴うこともある — 索引の[ `一意か$Ix ~EQ ~T ]により,索引の`~key~path$Ixが指す部位の値(`参照先~record$の値)の一意性が要求されるなど。 その保管庫が,この拘束に違反する~dataをすでに包含している場合でも、 実装は,[ この~methodにて例外を投出したり,それが返すものに影響させる ]ことなく, `IDBIndex^I ~objを作成して返すモノトスル。 代わりに実装は、[ この~methodの~callに利用された,`昇格~tx$ ]を中止する`~taskを~queueする$モノトスル。 ◎ 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 key path. 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, and the implementation must queue a task to abort the upgrade transaction which was used for the createIndex() call.
この~methodは、 コレ上の `indexNames$m ~propを同期的に改変する。 この~methodは `IDBRequest$I ~objを返さないが、 索引の作成~自体は,`昇格~tx$の中の非同期的な要請として,処理される。 ◎ 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 creation itself is processed as an asynchronous request within the upgrade transaction.
実装によっては、 この~methodが`索引~handle$( `IDBIndex^I ~obj)を返した後,`索引$を非同期に作成するときに,問題になる可能性がある。 例えば、[ 新たに作成された索引の~metadataを~dbに挿入する~taskを~queueする所 ],あるいは[ ~quota事由から,利用者に許可を請う必要があり得る所 ]で。 そのような場合でも,実装は: ◎ In some implementations it is possible for the implementation to asynchronously run into problems creating the index after the createIndex method 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\
- `索引~handle$を作成して返すモノトスル。 ◎ must still create and return an IDBIndex object,\
-
加えて,`索引$の作成ngに失敗したときは、 次を走らすモノトスル ⇒ `~txを中止する$( コレ, 失敗の事由に適切な~error名† ) ◎ and once the implementation determines that creating the index has failed, it must run the steps to abort a transaction using an appropriate error.\
† 例えば、[ ~quota事由に因り`索引$の作成ngに失敗した場合は `QuotaExceededError$E / [ `一意か$Ix ~EQ ~T ]の拘束に因り索引を作成できない場合は `ConstraintError$E ]を利用するモノトスル。 ◎ For example if creating the index failed due to quota reasons, a "QuotaExceededError" DOMException must be used as error and if the index can’t be created due to unique flag constraints, a "ConstraintError" DOMException must be used as error.
索引の非同期的な作成は、 次の例のように観測できる: ◎ The asynchronous creation of indexes is observable in the following example:
const %request1 = objectStore.put({name: `betty^l}, `1^lt); const %request2 = objectStore.put({name: `betty^l}, `2^lt); const %index = objectStore.createIndex(`by_name^l, `name^l, {unique: true});
`createIndex()^m が~callされた時点では,いずれの`要請$もまだ実行されていない。 2 番目の要請が実行されるとき,同じ `name^js ~propを`値$に有する`~record$が重複して作成される。 索引の作成は非同期的な`要請$と見なされ、 索引の[ `一意か$Ix ~EQ ~T ]による拘束は, 2 番目の`要請$を失敗させないので。 代わりに,`~tx$は、 索引の作成-時に,拘束を満たせないため`中止-$されることになる。 ◎ At the point where createIndex() called, neither of the requests have executed. When the second request executes, a duplicate name is created. Since the index creation is considered an asynchronous request, the index’s uniqueness constraint does not cause the second request to fail. Instead, the transaction will be aborted when the index is created and the constraint fails.
`index(name)@m ~method手続きは: ◎ The index(name) method steps are:
- ~IF[ コレ↗は削除されている ] ⇒ ~THROW `InvalidStateError$E ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF コレが`専属する$`~tx$の`状態$tx ~EQ `完遂d$i ⇒ ~THROW `InvalidStateError$E ◎ If transaction’s state is finished, then throw an "InvalidStateError" DOMException.
- %索引 ~LET コレの`索引~集合$OsH 内の`索引$のうち,次を満たすもの ⇒ `名前$Ix ~EQ %name ◎ Let index be the index named name in this's index set if one exists,\
- ~IF[ %索引 ~EQ ε ] ⇒ ~THROW `NotFoundError$E ◎ or throw a "NotFoundError" DOMException otherwise.
- ~RET 次を満たすような`索引~handle$ %H ⇒# %H↗ ~EQ %索引, %H はコレに`専属する$, `一意性$の要件を満たす ◎終 (`可換性$の要件は、`索引~集合$OsHの構成から自動的に満たされる) ◎ Return an index handle associated with index and this.
注記: `一意性$の要件から,返される~instanceは一意に定まる 【~instanceがその前のどの時点で作成されるかは,実装の詳細~になる】 。 よって、 `昇格~tx$の間を除き、 同じ `IDBObjectStore$I ~instance上で,同じ %name をこの~methodに渡して返される `IDBIndex$I ~instanceは、 常に同じになる。 ◎ NOTE: Each call to this method on the same IDBObjectStore instance with the same name returns the same IDBIndex instance.
注記: %H はコレに`専属する$ので、 他の `IDBObjectStore$I ~instanceに対し同じ %name で この~methodを呼出しても, %H と異なる `IDBIndex$I ~instanceが返される。 ◎ NOTE: The returned IDBIndex instance is specific to this IDBObjectStore instance. If this method is called on a different IDBObjectStore instance with the same name, a different IDBIndex instance is returned.
`deleteIndex(name)@m ~method手続きは: ◎ The deleteIndex(name) method steps are:
- `状態を検査する$( コレ, `versionchange^l ) ? ◎ Let transaction be this's transaction. ◎ Let store be this's object store. ◎ If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException. ◎ If store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %索引 ~LET コレ↗に`専属する$`索引$のうち,次を満たすもの ⇒ `名前$Ix ~EQ %name ◎ Let index be the index named name in store if one exists,\
- ~IF[ %索引 ~EQ ε ] ⇒ ~THROW `NotFoundError$E ◎ or throw a "NotFoundError" DOMException otherwise.
- コレの`索引~集合$OsHから %索引 を除去する ◎ Remove index from this's index set.
- %索引 を破壊する ◎ Destroy index.
この~methodは、 コレ↗に専属する,名前 %name の`索引$を破壊する。 この~methodを~callできるのは、 `昇格~txの中$からに限られることに注意。 ◎ 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.
この~methodは、 コレ上の `indexNames$m 属性を同期的に改変する。 この~methodは `IDBRequest$I ~objを返さないが、 索引の破壊~自体は,`昇格~tx$の中で非同期的な要請として処理される。 ◎ 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.
4.6. `IDBIndex^I ~interface
【! TODO Add example. Should examples be in a separate section?】`IDBIndex$I ~interfaceは、 `索引~handle$を表現する。 ◎ The IDBIndex interface represents an index handle.
[`Exposed$=(Window,Worker)] interface `IDBIndex@I { attribute `DOMString$ `name$m; [`SameObject$] readonly attribute `IDBObjectStore$I `objectStore$m; readonly attribute `any$ `keyPath$m; readonly attribute `boolean$ `multiEntry$m; readonly attribute `boolean$ `unique$m; [`NewObject$] `IDBRequest$I `get$m( `any$ %query ); [`NewObject$] `IDBRequest$I `getKey$m( `any$ %query ); [`NewObject$] `IDBRequest$I `getAll$m( optional `any$ %query, optional [`EnforceRange$] `unsigned long$ %count ); [`NewObject$] `IDBRequest$I `getAllKeys$m( optional `any$ %query, optional [`EnforceRange$] `unsigned long$ %count ); [`NewObject$] `IDBRequest$I `count$m( optional `any$ %query ); [`NewObject$] `IDBRequest$I `openCursor$m( optional `any$ %query, optional `IDBCursorDirection$I %direction = "next" ); [`NewObject$] `IDBRequest$I `openKeyCursor$m( optional `any$ %query, optional `IDBCursorDirection$I %direction = "next" ); };
- %index . `name$m
- %index↗ の`名前$Ixを返す。 ◎ Returns the name of the index.
- %index . `name$m = %newName
- %index↗ の`名前$Ixを %newName に更新する。 ◎ Updates the name of the store to newName.
- `昇格~txの外$で~callされた場合、 `InvalidStateError$E が投出される。 ◎ Throws an "InvalidStateError" DOMException if not called within an upgrade transaction.
- %index . `objectStore$m
- %index が`専属する$`保管庫~handle$( `IDBObjectStore$I )を返す。 ◎ Returns the IDBObjectStore the index belongs to.
- %index . `keyPath$m
- %index↗ の`~key~path$Ixを返す。 ◎ Returns the key path of the index.
- %index . `multiEntry$m
- %index↗ の`複-~entryか$Ixを返す。 ◎ Returns true if the index’s multiEntry flag is true.
- %index . `unique$m
- %index↗ の`一意か$Ixを返す。 ◎ Returns true if the index’s unique flag is true.
`name@m 取得子~手続きは ⇒ ~RET コレの`名前$IxH ◎ The name getter steps are to return this's name.
注記: コレが`専属する$~txが`完遂-$していない限り、 返される値はコレ↗の`名前$Ixと同じになり、 それ以降も同じ`値を保持し続ける$。 【! deitails 】 ◎ 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.
`name$m 設定子~手続きは: ◎ The name setter steps are:
- `状態を検査する$( コレ, `versionchange^l ) ? ◎ Let name be the given value. ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ 変則* If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException.
- %name ~LET `所与の値$ ◎ ↑
- ~IF[ コレの`名前$IxH ~EQ %name ] ⇒ ~RET ◎ If index’s name is equal to name, terminate these steps.
- ~IF[[ コレが`専属する$`保管庫~handle$ ]の`索引~集合$OsHに[ `名前$IxH ~EQ %name ]なる`索引$がある ] ⇒ ~THROW `ConstraintError$E ◎ If an index named name already exists in index’s object store, throw a "ConstraintError" DOMException.
- コレ↗の`名前$Ix ~SET %name ◎ Set index’s name to name.
- コレの`名前$IxH ~SET %name ◎ Set this's name to name.
`keyPath@m 取得子~手続きは ⇒ ~RET コレ↗の`~key~path$Ix %P を `WEBIDL$r に従って,次の型として変換した結果 ⇒# %P は文字列であるならば `DOMString$I / %P は文字列たちが成す~listであるならば `~SeqDS$ ◎ The keyPath getter steps are to return this's index's key path. The key path is converted as a DOMString (if a string) or a sequence<DOMString> (if a list of strings), per [WEBIDL].
【この属性は、`値を保持し続ける$。】
注記: 返される値は、 コレの作成-時に利用した~instanceと同じではない。 しかしながら,この属性が~obj(特定的には `Array$jT )を返す場合、 毎回~同じ~instanceを返す。 返された~objの~prop値を変更しても,コレに効果を及ぼすことはない。 ◎ NOTE: 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@m 取得子~手続きは ⇒ ~RET コレ↗の`複-~entryか$Ix ◎ The multiEntry getter steps are to return this's index's multiEntry flag.
【この属性は、`値を保持し続ける$。】
`unique@m 取得子~手続きは ⇒ ~RET コレ↗の`一意か$Ix ◎ The unique getter steps are to return this's index's unique flag.
【この属性は、`値を保持し続ける$。】
注記: 以下に挙げる~methodは、 `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E を投出する。 ◎ The following methods throw an "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %index . `get(query)$m
- %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初の~recordの`参照先~record$の`値$を検索取得するよう要請する。 ◎ Retrieves the value of the first record matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 該当する~recordが[ 在るならば 得られた値/ 無いならば `undefined^jv ]になる。 ◎ If successful, request’s result will be the value, or undefined if there was no matching record.
- %request = %index . `getKey(query)$m
- %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初の~recordの値 — すなわち,`参照先~record$の`~key$ — を検索取得するよう要請する。 ◎ Retrieves the key of the first record matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 該当する~recordが[ 在るならば 得られた`~key$ / 無いならば `undefined^jv ]になる。 ◎ If successful, request’s result will be the key, or undefined if there was no matching record.
- %request = %index . `getAll(query [, count])$m
- %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初から %count 個までの~recordの`参照先~record$の値たちを検索取得するよう要請する。 ◎ Retrieves the values of the records matching the given key or key range in query (up to count if given).
- 成功した場合の %request の `result$m は、 `値$たちが成す `Array$jT になる。 ◎ If successful, request’s result will be an Array of the values.
- %request = %index . `getAllKeys(query [, count])$m
- %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$に入る~recordたち ]のうち,最初から %count 個までの~recordの値 — すなわち,`参照先~record$の`~key$ — たちを検索取得するよう要請する。 ◎ Retrieves the keys of records matching the given key or key range in query (up to count if given).
- 成功した場合の %request の `result$m は、 `~key$たちが成す `Array$jT になる。 ◎ If successful, request’s result will be an Array of the keys.
- %request = %index . `count(query)$m
- %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$に入る~recordたち ]の総数を得るよう要請する。 ◎ Retrieves the number of records matching the given key or key range in query.
- 成功した場合の %request の `result$m は、 得られた総数になる。 ◎ If successful, request’s result will be the count.
`get(query)@m ~method手続きは: ◎ The get(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query, `~NULL不可^i ) ? ◎ Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る最初の~entryを検索取得する$( コレ↗, %範囲, `値^i ) ◎ Let operation be an algorithm to run retrieve a referenced value from an index with the current Realm record, index, and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$ (範囲が指定された場合、 範囲に入る最初の既存の~record) の`値$が検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the referenced value to be retrieved. If a range is specified, the method retrieves the first existing record in that range.
注記: `IDBObjectStore.get()$m の注記にて述べたことが,この~methodにも該当する。 ◎ NOTE: This method 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 use openCursor() with the same key. This will return a cursor with undefined as value if a record exists, or no cursor if no such record exists.
`getKey(query)@m ~method手続きは: ◎ The getKey(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query, `~NULL不可^i ) ? ◎ Let range be the result of converting a value to a key range with query and true. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る最初の~entryを検索取得する$( コレ↗, %範囲, `~key^i ) ◎ Let operation be an algorithm to run retrieve a value from an index with index and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$ (範囲が指定された場合、 範囲に入る最初の既存の~record) の`~key$が検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record key to be retrieved. If a range is specified, the method retrieves the first existing key in that range.
`getAll(query, count)@m ~method手続きは: ◎ The getAll(query, count) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~entryたちを検索取得する$( コレ↗, %範囲, %count, `値^i ) ◎ Let operation be an algorithm to run retrieve multiple referenced values from an index with the current Realm record, index, range, and count if given. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちの`参照先~record$の`値$が検索取得される。 ~NULL または省略時には,`全範囲$が利用される。 %count が指定されていて,範囲に入る~record数がそれを超える場合、 最初から %count 個までが検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the referenced values to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count records in range, only the first count will be retrieved.
`getAllKeys(query, count)@m ~method手続きは: ◎ The getAllKeys(query, count) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~entryたちを検索取得する$( コレ↗, %範囲, %count, `~key^i ) ◎ Let operation be an algorithm to run retrieve multiple values from an index with index, range, and count if given. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たち【の`参照先~record$】の`~key$が検索取得される。 ~NULL または省略時には,`全範囲$が利用される。 %count が指定されていて,範囲に入る~key数がそれを超える場合、 最初から %count 個までが検索取得される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the record keys to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count keys in range, only the first count will be retrieved.
`count(query)@m ~method手続きは: ◎ The count(query) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `範囲に入る~recordを数える$( コレ↗, %範囲 ) ◎ Let operation be an algorithm to run count the records in a range with index and range. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: %query ~parameterは、[ `~key$/`~key範囲$ ]をとり得る — それにより識別される`~record$たちが数えられる。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) identifying the records to be counted. If null or not given, an unbounded key range is used.
注記: 以下に挙げる~methodは、 `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E を投出する。 ◎ The following methods throw an "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %index . `openCursor([query [, direction = "next"]])$m
- [ %index↗ の`~record~list$Os内の[ %query が`表現する~key範囲$( %query が~NULL ならば`全範囲$)に入る~recordたち ]を,`方向$Cs %direction で反復する`~cursor$ ]を作成するよう要請する。 ◎ Opens a cursor over the records matching query, ordered by direction. If query is null, all records in index are matched.
- 成功した場合の %request の `result$m は、 範囲に入る~recordが[ 在るならば 反復-順で最初の~recordを指している `IDBCursorWithValue$I / 無いならば ~NULL ]になる。 ◎ If successful, request’s result will be an IDBCursorWithValue, or null if there were no matching records.
- %request = %index . `openKeyCursor([query [, direction = "next"]])$m
- [ %index↗ の`~record~list$Ix内の[ %query が`表現する~key範囲$( %query が~NULL ならば`全範囲$)に入る~recordたち ]を,`方向$Cs %direction で反復する`~cursor$ ]を作成するよう要請する。 作成される`~cursor$の`~keyのみか$Csは ~T になる (~cursorは、 ~recordの~keyのみを取得する)。 ◎ Opens a cursor with key only flag set to true over the records matching query, ordered by direction. If query is null, all records in index are matched.
- 成功した場合の %request の `result$m は、 範囲に入る~recordが[ 在るならば 反復-順で最初の~recordを指している `IDBCursor$I / 無いならば ~NULL ]になる。 ◎ If successful, request’s result will be an IDBCursor, or null if there were no matching records.
`openCursor(query, direction)@m ~method手続きは: ◎ The openCursor(query, direction) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- %要請 ~LET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `~cursorを作成する$( コレ, `現在の~realm$, %direction, %範囲 ) ◎ Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to index, range set to range, and key only flag set to false. ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record and cursor. ◎ Let request be the result of running asynchronously execute a request with this and operation.
- コレの`要請$Cs ~SET %要請 ◎ Set cursor’s request to request.
- ~RET %要請 ◎ Return request.
注記: %query ~parameterは、 `~cursor$の`範囲$Csとして利用する[ `~key$/`~key範囲$ ]をとり得る。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) to use as the cursor's range. If null or not given, an unbounded key range is used.
`openKeyCursor(query, direction)@m ~method手続きは: ◎ The openKeyCursor(query, direction) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ Let index be this's index. ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- %範囲 ~LET `Range$( %query ) ? ◎ Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
- %要請 ~LET 次の`演算$を走らす`要請を非同期に実行する$( コレ ) ⇒ `~cursorを作成する$( コレ, `現在の~realm$, %direction, %範囲, `~keyのみ^i ) ◎ Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to index, range set to range, and key only flag set to true. ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record and cursor. ◎ Let request be the result of running asynchronously execute a request with this and operation.
- コレの`要請$Cs ~SET %要請 ◎ Set cursor’s request to request.
- ~RET %要請 ◎ Return request.
注記: %query ~parameterは、 `~cursor$の`範囲$Csとして利用する[ `~key$/`~key範囲$ ]をとり得る。 ~NULL または省略時には,`全範囲$が利用される。 ◎ NOTE: The query parameter can be a key or key range (an IDBKeyRange) to use as the cursor's range. If null or not given, an unbounded key range is used.
4.7. `IDBKeyRange^I ~interface
`IDBKeyRange$I ~interfaceは、 `~key範囲$を表現する。 ◎ The IDBKeyRange interface represents a key range.
[`Exposed$=(Window,Worker)]
interface `IDBKeyRange@I {
readonly attribute `any$ `lower$m;
readonly attribute `any$ `upper$m;
readonly attribute `boolean$ `lowerOpen$m;
readonly attribute `boolean$ `upperOpen$m;
// 静的~構築~method:
[`NewObject$] static `IDBKeyRange$I `only$m(
`any$ %value
);
[`NewObject$] static `IDBKeyRange$I `lowerBound$m(
`any$ %lower,
optional `boolean$ %open = false
);
[`NewObject$] static `IDBKeyRange$I `upperBound$m(
`any$ %upper,
optional `boolean$ %open = false
);
[`NewObject$] static `IDBKeyRange$I `bound$m(
`any$ %lower,
`any$ %upper,
optional `boolean$ %lowerOpen = false,
optional `boolean$ %upperOpen = false
);
`boolean$ `includes$m(`any$ %key);
};
- %range . `lower$m
- この範囲の`下界$が[ あれば それ / なければ `undefined^jv ]を返す。 ◎ Returns the range’s lower bound, or undefined if none.
- %range . `upper$m
- この範囲の`上界$が[ あれば それ / なければ `undefined^jv ]を返す。 ◎ Returns the range’s upper bound, or undefined if none.
- %range . `lowerOpen$m
- この範囲の`下界openか$を返す。 ◎ Returns the range’s lower open flag.
- %range . `upperOpen$m
- この範囲の`上界openか$を返す。 ◎ Returns the range’s upper open flag.
- %range = `IDBKeyRange$I . `only(key)$m
- %value のみを含む,新たな `IDBKeyRange$I ( `~key範囲$ )を返す。 ◎ Returns a new IDBKeyRange spanning only key.
- %range = `IDBKeyRange$I . `lowerBound(lower [, open = false])$m
- `下界$ %lower から開始され, `上界$のない,新たな `IDBKeyRange$I を返す。 %open が ~T の場合、 %lower はこの範囲に含まれない。 ◎ Returns a new IDBKeyRange starting at key with no upper bound. If open is true, key is not included in the range.
- %range = `IDBKeyRange$I . `upperBound(upper [, open = false])$m
- `下界$のない, `上界$ %upper で終端する,新たな `IDBKeyRange$I を返す。 %open が ~T の場合、 %upper はこの範囲に含まれない。 ◎ Returns a new IDBKeyRange with no lower bound and ending at key. If open is true, key is not included in the range.
- %range = `IDBKeyRange$I . `bound(lower, upper [, lowerOpen = false [, upperOpen = false]])$m
- `下界$ %lower から `上界$ %upper までにわたる,新たな `IDBKeyRange$I を返す。 %lowerOpen が ~T の場合、 %lower はこの範囲に含まれない。 %upperOpen が ~T の場合、 %upper はこの範囲に含まれない。 ◎ Returns a new IDBKeyRange spanning from lower to upper. If lowerOpen is true, lower is not included in the range. If upperOpen is true, upper is not included in the range.
- 【
[
%lower / %upper
]に対する `undefined^jv は、
許容されない
(省略可能でないので)。
したがって,[
`下界$ /`上界$
]のない`~key範囲$を作成するためには、
他の~methodを利用する必要がある。
`全範囲$を表現する `IDBKeyRange^I ~objは 作成できないが、
`lowerBound$m(`-Infinity^jv)
により,実質的に等価なものは作成できる。 また、 他の各種~API~methodの引数のうち,`~key範囲$を期待するもの (この仕様の~IDLで %query と記される引数)は、 (省略可能ならば)省略した場合には`全範囲$に解釈される。 】
`lowerBound(lower, open)@m ~method手続きは: ◎ The lowerBound(lower, lowerOpen) method steps are:
- %lowerKey ~LET `Key$( %lower ) ? ◎ Let lowerKey be the result of converting a value to a key with lower. Rethrow any exceptions. ◎ If lowerKey is invalid, throw a "DataError" DOMException.
- ~RET 新たな`~key範囲$ — その ⇒# `下界$ ~SET %lowerKey, `下界openか$ ~SET %open, `上界$ ~SET ε, `上界openか$ ~SET ~T ◎ Create and return a new key range with lower bound set to lowerKey, lower open flag set to open, upper bound set to null, and upper open flag set to true.
`upperBound(upper, open)@m ~method手続きは: ◎ The upperBound(upper, open) method steps are:
- %upperKey ~LET `Key$( %upper ) ? ◎ Let upperKey be the result of converting a value to a key with upper. Rethrow any exceptions. ◎ If upperKey is invalid, throw a "DataError" DOMException.
- ~RET 新たな`~key範囲$ — その ⇒# `下界$ ~SET ε, `下界openか$ ~SET ~T, `上界$ ~SET %upperKey, `上界openか$ ~SET %open ◎ Create and return a new key range with lower bound set to null, lower open flag set to true, upper bound set to upperKey, and upper open flag set to open.
`bound(lower, upper, lowerOpen, upperOpen)@m ~method手続きは: ◎ The bound(lower, upper, lowerOpen, upperOpen) method steps are:
- %lowerKey ~LET `Key$( %lower ) ? ◎ Let lowerKey be the result of converting a value to a key with lower. Rethrow any exceptions. ◎ If lowerKey is invalid, throw a "DataError" DOMException.
- %upperKey ~LET `Key$( %upper ) ? ◎ Let upperKey be the result of converting a value to a key with upper. Rethrow any exceptions. ◎ If upperKey is invalid, throw a "DataError" DOMException.
- ~IF[ %lower ~GT~cmpkey %upper ] ⇒ ~THROW `DataError$E ◎ If lowerKey is greater than upperKey, throw a "DataError" DOMException.
- ~RET 新たな`~key範囲$ — その ⇒# `下界$ ~SET %lowerKey, `下界openか$ ~SET %lowerOpen, `上界$ ~SET %upperKey, `上界openか$ ~SET %upperOpen ◎ Create and return a new key range with lower bound set to lowerKey, lower open flag set to lowerOpen, upper bound set to upperKey and upper open flag set to upperOpen.
- %range . `includes(key)$m
- [ %key が %range に`入る$ならば ~T / ~ELSE_ ~F ]を返す。 ◎ Returns true if key is included in the range, and false otherwise.
`includes(key)@m ~method手続きは: ◎ The includes(key) method steps are:
- %key ~LET `Key$( %key ) ? ◎ Let k be the result of converting a value to a key with key. Rethrow any exceptions. ◎ If k is invalid, throw a "DataError" DOMException.
- ~IF [ %key ~IN~cmpkey コレ ] ⇒ ~RET ~T ◎ Return true if k is in this range, and\
- ~RET ~F ◎ false otherwise.
4.8. `IDBCursor^I ~interface
【! TODO Add example. Should examples be in a separate section?】`~cursor$~objは、 `IDBCursor$I ~interfaceを実装する。 所与の`~cursor$を表現するような `IDBCursor$I ~instanceは,唯一つに限られるが、 同時に利用できる~cursorの~~総数に上限はない。 ◎ Cursor objects implement the IDBCursor interface. There is only ever one IDBCursor instance representing a given cursor. There is no limit on how many cursors can be used at the same time.
[`Exposed$=(Window,Worker)] interface `IDBCursor@I { readonly attribute (`IDBObjectStore$I or `IDBIndex$I) `source$m; readonly attribute `IDBCursorDirection$I `direction$m; readonly attribute `any$ `key$m; readonly attribute `any$ `primaryKey$m; [`SameObject$] readonly attribute `IDBRequest$I `request$m; `undefined$ `advance$m( [`EnforceRange$] `unsigned long$ %count ); `undefined$ `continue$m( optional `any$ %key ); `undefined$ `continuePrimaryKey$m( `any$ %key, `any$ %primaryKey ); [`NewObject$] `IDBRequest$I `update$m( `any$ %value ); [`NewObject$] `IDBRequest$I `delete$m(); }; enum `IDBCursorDirection@I { `next$l, `nextunique$l, `prev$l, `prevunique$l };
- %cursor . `source$m
- %cursor の`~source$Cs ( `IDBObjectStore$I / `IDBIndex$I ) を返す。 ◎ Returns the IDBObjectStore or IDBIndex the cursor was opened from.
- %cursor . `direction$m
- %cursor の`方向$Cs ( `next$l / `nextunique$l / `prev$l / `prevunique$l ) を返す。 ◎ Returns the direction ("next", "nextunique", "prev" or "prevunique") of the cursor.
- %cursor . `key$m
- %cursor の`~key$Csを返す。 ◎ Returns the key of the cursor.\
- %cursor を進めている間 / 反復し終えていた場合、 `InvalidStateError$E が投出される†。 ◎ Throws a "InvalidStateError" DOMException if the cursor is advancing or is finished.
- %cursor . `primaryKey$m
- %cursor の`実効~key$Csを返す。 ◎ Returns the effective key of the cursor.\
- %cursor を進めている間 / 反復し終えていた場合、 `InvalidStateError$E が投出される†。 ◎ Throws a "InvalidStateError" DOMException if the cursor is advancing or is finished.
- 【† これらの要件は、 下の規範的な~textには述べられていない (何かの間違い?)。 】
- %cursor . `request$m
- %cursor を得するために利用された`要請$Csを返す。 ◎ Returns the request that was used to obtain this cursor.
`source@m 取得子~手続きは ⇒ ~RET コレの`~source$Cs ◎ The source getter steps are to return this's source.
注記: コレの`~source$Cs %S は、 `コレを作成する@#_X-new-cursor$よう要請した[ `保管庫~handle$/`索引~handle$ ]に初期化され, それ以降は変化しない — %S が`専属する$~txが `作動中$i でなくなっても, %S↗ が破壊されても。 ◎ NOTE: The source 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.
`key@m 取得子~手続きは ⇒ ~RET `Value$( コレの`~key$Cs ) ◎ The key getter steps are to return the result of converting a key to a value with the cursor’s current key.
注記: ~obj( `Date$jT や `Array$jT など)を返す場合、 コレの`~key$Cs が変更されるまで,毎回~同じ~instanceを返すことになる。 すなわち、 ~objに加えられる改変は,どこからも見えることになる — しかしながら、 その改変が~dbの内容を改変することはない。 ◎ NOTE: If key returns an object (e.g. a Date or 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@m 取得子~手続きは ⇒ ~RET `Value$( コレの`実効~key$Cs ) ◎ The primaryKey getter steps are to return the result of converting a key to a value with the cursor’s current effective key.
注記: `key^m 取得子の`注記@#_key-getter-return-value$は、 この取得子にも該当する。 ◎ NOTE: If primaryKey returns an object (e.g. a Date or 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.
`request@m 取得子~手続きは ⇒ ~RET コレの`要請$Cs ◎ The request getter steps are to return this's request.
🚧 これは、 この版による新たな属性である。 [ Chrome 76, Edge 79, Firefox 77, Safari 15 ]から~supportされている。 🚧 ◎ 🚧 The request attribute is new in this edition. It is supported in Chrome 76, Edge 79, Firefox 77, and Safari 15. 🚧
注記: 以下に挙げる~methodは、 `~cursor$を その`範囲$Csに入る次の`~record$以降へ進めるよう要請する: ◎ The following methods advance a cursor.
- 進め終えた時点で、 ~cursorの`要請$Csに向けて `success$et ~eventが発火されることになる。 `result$m は、 `範囲$Csに入る`~record$が[ 在るならば ~cursor自身 / 無いならば `undefined^jv ]になる。 ◎ Once the cursor has advanced, a success event will be fired at the same IDBRequest returned when the cursor was opened. The result will be the same cursor if a record was in range, or undefined otherwise.
- ~cursorを進める前回の要請が在って,それが完了する前に~callされた場合、 `InvalidStateError$E を投出する。 ◎ If called while the cursor is already advancing, an "InvalidStateError" DOMException will be thrown.
- `~tx$が `作動中$i でないときに~callされた場合、 `TransactionInactiveError$E を投出する。 ◎ The following methods throw a "TransactionInactiveError" DOMException if called when the transaction is not active.
- %cursor . `advance(count)$m
- %cursor を %count 個だけ先の~recordへ進める。 ◎ Advances the cursor through the next count records in range.
- %cursor . `continue$m()
- %cursor を次の~recordへ進める。 ◎ Advances the cursor to the next record in range.
- %cursor . `continue(key)$m
- %cursor を,次を満たす最初の~recordへ進める ⇒ [ 次の~record以降に在る ]~AND[ `~key$ ~GTE~cmpkey %key ] ◎ Advances the cursor to the next record in range matching or after key.
- %cursor . `continuePrimaryKey(key, primaryKey)$m
- %cursor を,次を満たす最初の~recordへ進める ⇒ [ 次の~record以降に在る ]~AND[ ( `~key$, `値$ ) ~GTE~cmpkey ( %key, %primaryKey ) ] ◎ Advances the cursor to the next record in range matching or after key and primaryKey.\
- %cursor の`~source$Cs↗が`索引$でない場合、 `InvalidAccessError$E が投出される。 ◎ Throws an "InvalidAccessError" DOMException if the source is not an index.
`advance(count)@m ~method手続きは: ◎ The advance(count) method steps are:
- ~IF[ %count ~EQ 0 ] ⇒ ~THROW `TypeError$E ◎ If count is 0 (zero), throw a TypeError.
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`値は取得-済みか$Cs ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
- コレの`値は取得-済みか$Cs ~SET ~F ◎ Set this's got value flag to false.
- %要請 ~SET コレの`要請$Cs ◎ Let request be this's request.
- %要請 の ⇒# `処理-済みか$ ~SET ~F, `済んだか$ ~SET ~F ◎ Set request’s processed flag to false. ◎ Set request’s done flag to false.
- 次の`演算$を走らす`要請を非同期に実行する$( コレの`~source$Cs, %要請 ) ⇒ `~cursorを反復する$( コレ, `現在の~realm$, ε, ε, %count ) ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record, this, and count. ◎ Run asynchronously execute a request with this's source, operation, and request.
注記: 新たな~cursor~dataが読込まれる前に,この~methodを重ねて~callした場合 — 例えば,同じ `onsuccess^m ~handlerの~callの中で重ねて~callした場合 — 2 回目の~call時には、 ~cursorの`値は取得-済みか$Cs ~EQ ~F なので, `InvalidStateError$E 例外が投出されることになる。 ◎ NOTE: Calling this method more than once before new cursor data has been loaded - for example, calling advance() twice from the same onsuccess handler - results in an "InvalidStateError" DOMException being thrown on the second call because the cursor’s got value flag has been set to false.
`continue(key)@m ~method手続きは: ◎ The continue(key) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`値は取得-済みか$Cs ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
-
~IF[ %key ~NEQ ε ]: ◎ If key is given, then:
- %key ~LET `Key$( %key ) ? ◎ Let r be the result of converting a value to a key with key. Rethrow any exceptions. ◎ If r is invalid, throw a "DataError" DOMException. ◎ Let key be r.
- ~IF[ %key ~LTE~cmpkey コレの`位置$Cs ]~AND[ コレの`方向$Cs ~IN { `next^l, `nextunique^l } ] ⇒ ~THROW `DataError$E ◎ If key is less than or equal to this's position and this's direction is "next" or "nextunique", then throw a "DataError" DOMException.
- ~IF[ %key ~GTE~cmpkey コレの`位置$Cs ]~AND[ コレの`方向$Cs ~IN { `prev^l, `prevunique^l } ] ⇒ ~THROW `DataError$E ◎ If key is greater than or equal to this's position and this's direction is "prev" or "prevunique", then throw a "DataError" DOMException.
- コレの`値は取得-済みか$Cs ~SET ~F ◎ Set this's got value flag to false.
- %要請 ~SET コレの`要請$Cs ◎ Let request be this's request.
- %要請 の ⇒# `処理-済みか$ ~SET ~F, `済んだか$ ~SET ~F ◎ Set request’s processed flag to false. ◎ Set request’s done flag to false.
- 次の`演算$を走らす`要請を非同期に実行する$( コレの`~source$Cs, %要請 ) ⇒ `~cursorを反復する$( コレ, `現在の~realm$, %key ) ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record, this, and key (if given). ◎ Run asynchronously execute a request with this's source, operation, and request.
注記: `advance$m の注記と同じ文言がこの~methodにも該当する。 ◎ NOTE: Calling this method more than once before new cursor data has been loaded - for example, calling continue() twice from the same onsuccess handler - results in an "InvalidStateError" DOMException being thrown on the second call because the cursor’s got value flag has been set to false.
`continuePrimaryKey(key, primaryKey)@m ~method手続きは: ◎ The continuePrimaryKey(key, primaryKey) method steps are:
- `状態を検査する$( コレ ) ? ◎ Let transaction be this's transaction. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`~source$Csは`索引~handle$でない ] ⇒ ~THROW `InvalidAccessError$E ◎ If this's source is not an index throw an "InvalidAccessError" DOMException.
- ~IF[ コレの`方向$Cs ~NIN { `next^l, `prev^l } ] ⇒ ~THROW `InvalidAccessError$E ◎ If this's direction is not "next" or "prev", throw an "InvalidAccessError" DOMException.
- ~IF[ コレの`値は取得-済みか$Cs ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
- %key ~LET `Key$( %key ) ? ◎ Let r be the result of converting a value to a key with key. Rethrow any exceptions. ◎ If r is invalid, throw a "DataError" DOMException. ◎ Let key be r.
- %首key ~LET `Key$( %primaryKey ) ? ◎ Let r be the result of converting a value to a key with primaryKey. Rethrow any exceptions. ◎ If r is invalid, throw a "DataError" DOMException. ◎ Let primaryKey be r.
- ~IF[ コレの`方向$Cs ~EQ `next^l ]~AND[ ( %key, %首key ) ~LTE~cmpkey コレの ( `位置$Cs, `保管庫~位置$Cs ) ] ⇒ ~THROW `DataError$E ◎ ↓
- ~IF[ コレの`方向$Cs ~EQ `prev^l ]~AND[ ( %key, %首key ) ~GTE~cmpkey コレの ( `位置$Cs, `保管庫~位置$Cs ) ] ⇒ ~THROW `DataError$E ◎ If key is less than this's position and this's direction is "next", throw a "DataError" DOMException. ◎ If key is greater than this's position and this's direction is "prev", throw a "DataError" DOMException. ◎ If key is equal to this's position and primaryKey is less than or equal to this's object store position and this's direction is "next", throw a "DataError" DOMException. ◎ If key is equal to this's position and primaryKey is greater than or equal to this's object store position and this's direction is "prev", throw a "DataError" DOMException.
- コレの`値は取得-済みか$Cs ~SET ~F ◎ Set this's got value flag to false.
- %要請 ~SET コレの`要請$Cs ◎ Let request be this's request.
- %要請 の ⇒# `処理-済みか$ ~SET ~F, `済んだか$ ~SET ~F ◎ Set request’s processed flag to false. ◎ Set request’s done flag to false.
- 次の`演算$を走らす`要請を非同期に実行する$( コレの`~source$Cs, %要請 ) ⇒ `~cursorを反復する$( コレ, `現在の~realm$, %key, %首key ) ◎ Let operation be an algorithm to run iterate a cursor with the current Realm record, this, key, and primaryKey. ◎ Run asynchronously execute a request with this's source, operation, and request.
注記: `advance$m の注記と同じ文言がこの~methodにも該当する。 ◎ NOTE: Calling this method more than once before new cursor data has been loaded - for example, calling continuePrimaryKey() twice from the same onsuccess handler - results in an "InvalidStateError" DOMException being thrown on the second call because the cursor’s got value flag has been set to false.
注記: 以下に挙げる~methodは、[ `~readonly~tx$の中で~callされた場合は `ReadOnlyError$E / `~tx$が `作動中$i でないときに~callされた場合は `TransactionInactiveError$E ]を投出する。 ◎ The following methods throw a "ReadOnlyError" DOMException if called within a read-only transaction, and a "TransactionInactiveError" DOMException if called when the transaction is not active.
- %request = %cursor . `update(value)$m
- %cursor が指している`~record$†の値を %value に更新するよう要請する。 ◎ Updated the record pointed at by the cursor with a new value.
- 【† `~source$Csが`索引$の場合は、 その`参照先~record$。 】
- [ %cursor の`実効~保管庫$Csの`~key~path$Os ~NEQ ε ]の下で, `~key$を変更しようとした場合†、 `DataError$E が投出される。 ◎ Throws a "DataError" DOMException if the effective object store uses in-line keys and the key would have changed.
- 【† すなわち,当の~recordの~keyが %value 内の`~key~path$Osが指す部位と等しくない場合。 】
- 成功した場合の %request の `result$m は、 更新した`~record$の`~key$になる。 ◎ If successful, request’s result will be the record's key.
- %request = %cursor . `delete$m()
- %cursor が指している~recordを削除するよう要請する。 【! *原文誤 with a new value. 】 ◎ Delete the record pointed at by the cursor with a new value.
- 成功した場合の %request の `result$m は、 `undefined^jv になる。 ◎ If successful, request’s result will be undefined.
`update(value)@m ~method手続きは: ◎ The update(value) method steps are:
- `状態を検査する$( コレ, `readwrite^l ) ? ◎ Let transaction be this's transaction. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException. ◎ If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`値は取得-済みか$Cs ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`~keyのみか$Cs ~EQ ~T ] ⇒ ~THROW `InvalidStateError$E ◎ If this's key only flag is true, throw an "InvalidStateError" DOMException.
- %clone ~LET `~txの間に値を~cloneする$( %value, コレの`~source$Csが`専属する$`~tx$ ) ? ◎ Let targetRealm be a user-agent defined Realm. ◎ Let clone be a clone of value in targetRealm during transaction. Rethrow any exceptions. ◎ Why create a copy of the value? ◎ The value is serialized when stored. Treating it as a copy here allows other algorithms in this specification to treat it as an ECMAScript value, but implementations can optimize this if the difference in behavior is not observable.
- %keyPath ~LET コレの`実効~保管庫$Csの`~key~path$Os ◎ ↓
-
~IF[ %keyPath ~NEQ ε ]:
- %抽出d~key ~LET `Extract$( %clone, %keyPath ) ?
- ~IF[ %抽出d~key ~NEQ~cmpkey ~cursorの`実効~key$Cs ] ⇒ ~THROW `DataError$E ◎ ↑
-
~RET 次の`演算$を走らす`要請を非同期に実行する$( コレの`~source$Cs ) ⇒ `保管庫に~recordを格納する$( コレの`実効~保管庫$Cs, %clone, コレの`実効~key$Cs ) ◎ Let operation be an algorithm to run store a record into an object store with this's effective object store, clone, this's effective key, and false. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
注記: `保管庫に~recordを格納する$演算は、[ ~cursorを ある~recordを指す位置に移動した後,その~recordが削除されていた場合 ]には,新たな~recordを作成することになる。 ◎ NOTE: A result of 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.
`delete()@m ~method手続きは: ◎ The delete() method steps are:
- `状態を検査する$( コレ, `readwrite^l ) ? ◎ Let transaction be this's transaction. ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException. ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException. ◎ If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`値は取得-済みか$Cs ~EQ ~F ] ⇒ ~THROW `InvalidStateError$E ◎ If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
- ~IF[ コレの`~keyのみか$Cs ~EQ ~T ] ⇒ ~THROW `InvalidStateError$E ◎ If this's key only flag is true, throw an "InvalidStateError" DOMException.
- ~RET 次の`演算$を走らす`要請を非同期に実行する$( コレの`~source$Cs ) ⇒ `保管庫から~recordを削除する$( コレの`実効~保管庫$Cs, `Only$( コレの`実効~key$Cs ) ) ◎ Let operation be an algorithm to run delete records from an object store with this's effective object store and this's effective key. ◎ Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
`~keyのみか$Cs ~EQ ~F にされた`~cursor$は、 `IDBCursorWithValue$I ~interfaceも実装する。 ◎ A cursor that has its key only flag set to false implements the IDBCursorWithValue interface as well.
[`Exposed$=(Window,Worker)] interface `IDBCursorWithValue@I : `IDBCursor$I { readonly attribute `any$ `value$m; };
- %cursor . `value$m
- %cursor の現在の`値$Csを返す。 ◎ Returns the cursor's current value.
`value@m 取得子~手続きは ⇒ ~RET [ コレの`値$Cs ~NEQ ε ならば それ / ~ELSE_ `undefined^jv ] ◎ The value getter steps are to return this's current value.
注記: `key^m 取得子の`注記@#_key-getter-return-value$は、 この取得子にも該当する。 ◎ NOTE: If value 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.
4.9. `IDBTransaction^I ~interface
【! TODO Add example. Should examples be in a separate section?】`~tx$は、 次の~interfaceを実装する~objで表現される: ◎ Transaction objects implement the following interface:
[`Exposed$=(Window,Worker)]
interface `IDBTransaction@I : `EventTarget$I {
readonly attribute `DOMStringList$I `objectStoreNames$m;
readonly attribute `IDBTransactionMode$I `mode$m;
readonly attribute `IDBTransactionDurability$I `durability$m;
[`SameObject$] readonly attribute `IDBDatabase$I `db$m;
readonly attribute `DOMException$I? `error$m;
`IDBObjectStore$I `objectStore$m(`DOMString$ %name);
`undefined$ `commit$m();
`undefined$ `abort$m();
// ~event~handler:
attribute `EventHandler$I `onabort$m;
attribute `EventHandler$I `oncomplete$m;
attribute `EventHandler$I `onerror$m;
};
enum `IDBTransactionMode@I {
`readonly$l,
`readwrite$l,
`versionchange$l
};
- %transaction . `objectStoreNames$m
- %transaction の`視野$に入る各`保管庫$の名前たちが成す~listを返す。 `昇格~tx$に対しては、 視野は,当の`~db$の`保管庫$すべてからなる。 ◎ 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 . `mode$m
- %transaction の`~mode$を返す。 `昇格~tx$に対しては, `versionchange$l / 他の~txに対しては,その作成-時に与えたもの( `readonly$l / `readwrite$l )になる。 ◎ Returns the mode the transaction was created with ("readonly" or "readwrite"), or "versionchange" for an upgrade transaction.
- %transaction . `durability$m
- %transaction の作成-時に与えた`耐久能~hint$ ( `strict$l / `relaxed$l / `default$l ) を返す。 ◎ Returns the durability hint the transaction was created with ("strict", "relaxed"), or "default").
- %transaction . `db$m
- %transaction が`専属する$`接続$を返す。 ◎ Returns the transaction’s connection.
- %transaction . `error$m
- %transaction が すでに`中止-$されている場合、 その事由を供する~error( `DOMException$I )を返す。 ◎ If the transaction was aborted, returns the error (a DOMException) providing the reason.
`objectStoreNames@m 取得子~手続きは: ◎ The objectStoreNames getter steps are:
- %名前~群 ~LET [ コレが`視野$に入れている各`保管庫$の`名前$Os ]たちが成す`~list$ ◎ Let names be a list of the names of the object stores in this's scope.
- ~RET `~sort済み名前~listを作成する$( %名前~群 ) ◎ Return the result (a DOMStringList) of creating a sorted name list with names.
注記: この属性が返す~listの内容は、 変化しない — ただし,`昇格~tx$の間は、 保管庫が[ 作成される/削除される ]に伴い変化し得る。 ◎ NOTE: The contents of each list returned by this attribute does not change, but subsequent calls to this attribute during an upgrade transaction can return lists with different contents as object stores are created and deleted.
`durability@m 取得子~手続きは ⇒ ~RET コレの`耐久能~hint$ ◎ The durability getter steps are to return this's durability hint.
🚧 これは、 この版による新たな属性である。 [ Chrome 82, Edge 82, Firefox 126, Safari 15 ]から~supportされている。 🚧 ◎ 🚧 The durability attribute is new in this edition. It is supported in Chrome 82, Edge 82, Firefox 126, and Safari 15. 🚧
`error@m 取得子~手続きは ⇒ ~RET [ コレの`~error$tx ~NEQ ε ならば それ / ~ELSE_ ~NULL ] ◎ The error getter steps are to return this's error, or null if none.
注記: ~txが中止されたときは、 その事由に応じて,次を返す:
- 失敗した`要請$に因り`中止-$された場合、 `要請$の`~error$と同じ名前の~error。
- ~event~handlerから投出された例外に因り`中止-$された場合、 `AbortError$E
- `~commit$時の~errorに因り`中止-$された場合、 失敗の事由を反映する~error — 例えば `QuotaExceededError$E / `ConstraintError$E / `UnknownError$E
【 `abort()$m ~methodに因り`中止-$された場合は、 ~NULL が返される。 】
◎ NOTE: If this transaction was aborted due to a failed request, this will be the same as the request's error. If this transaction was aborted due to an uncaught exception in an event handler, the error will be a "AbortError" DOMException. If the transaction was aborted due to an error while committing, it will reflect the reason for the failure (e.g. "QuotaExceededError", "ConstraintError", or "UnknownError" DOMException).- %transaction . `objectStore(name)$m
- %transaction の`視野$に入る`名前$Os %name の`保管庫$を`~access先$とする `IDBObjectStore$I を返す。 ◎ Returns an IDBObjectStore in the transaction's scope.
- %transaction . `abort()$m
- %transaction を中止する。 処理待ちにあるすべての`要請$は `AbortError$E で失敗し、 接続先~dbに加えられた すべての変更は復帰されることになる。 ◎ Aborts the transaction. All pending requests will fail with a "AbortError" DOMException and all changes made to the database will be reverted.
- %transaction . `commit()$m
- ~txを~commitしようと試みる。 処理待ちにあるすべての`要請$は完了できるようになるが、 新たな要請は受容されなくなる。 これを利用すれば,~txを素早く完遂するよう強制できる — [ ~commitしようと試みる前に,処理待ち要請に対し `success$et ~eventが発火されるまで待機する ]通常のふるまいに代えて。 ◎ Attempts to commit the transaction. All pending requests will be allowed to complete, but no new requests will be accepted. This can be used to force a transaction to quickly finish, without waiting for pending requests to fire success events before attempting to commit normally.
- 処理待ち要請が — 例えば拘束~errorに因り — 失敗した場合、 ~txは中止される。 成功した要請に対しては,依然として `success$et ~eventは発火されるが、 ~event~handler内で例外を投出しても,~txは中止されなくなる。 同様に,失敗した要請に対しても,依然として `error$et ~eventは発火されるが、 `preventDefault()^m を~callしても,~txは中止できない。 ◎ The transaction will abort if a pending request fails, for example due to a constraint error. The success events for successful requests will still fire, but throwing an exception in an event handler will not abort the transaction. Similarly, error events for failed requests will still fire, but calling preventDefault() will not prevent the transaction from aborting.
`objectStore(name)@m ~method手続きは: ◎ The objectStore(name) method steps are:
- ~IF[ コレの`状態$tx ~EQ `完遂d$i ] ⇒ ~THROW `InvalidStateError$E ◎ If this's state is finished, then throw an "InvalidStateError" DOMException.
- %保管庫 ~LET 次を満たす`保管庫$ ⇒ [ コレの`視野$に入る ]~AND[ `名前$Os ~EQ %name ] ◎ Let store be the object store named name in this's scope,\
- ~IF[ %保管庫 ~EQ ε ] ⇒ ~THROW `NotFoundError$E ◎ or throw a "NotFoundError" DOMException if none.
- ~RET 次を満たすような`保管庫~handle$ %H ⇒# %H↗ ~EQ %保管庫, %H はコレに`専属する$, `一意性$の要件を満たす ◎終 (`可換性$の要件は、`視野$の構成から自動的に満たされる) ◎ Return an object store handle associated with store and this.
注記: `一意性$の要件から,返される~instanceは一意に定まる 【~instanceがその前のどの時点で作成されるかは,実装の詳細~になる】 。 よって、 `昇格~tx$の間を除き、 同じ `IDBTransaction$I ~instance上で,同じ %name をこの~methodに渡して返される `IDBObjectStore$I ~instanceは、 常に同じになる。 ◎ NOTE: Each call to this method on the same IDBTransaction instance with the same name returns the same IDBObjectStore instance.
注記: %H はコレに`専属する$ので、 他の `IDBTransaction$I ~instanceに対し同じ引数で この~methodを呼出しても, %H と異なる `IDBObjectStore$I ~instanceが返される。 ◎ NOTE: The returned IDBObjectStore instance is specific to this IDBTransaction. If this method is called on a different IDBTransaction, a different IDBObjectStore instance is returned.
`abort()@m ~method手続きは: ◎ The abort() method steps are:
- ~IF[ コレの`状態$tx ~IN { `~commit中$i, `完遂d$i } ] ⇒ ~THROW `InvalidStateError$E ◎ If this's state is committing or finished, then throw an "InvalidStateError" DOMException.
- コレの`状態$tx ~SET `非作動中$i ◎ Set this's state to inactive and\
- `~txを中止する$( コレ, ~NULL ) ◎ run abort a transaction with this and null.
`commit()@m ~method手続きは: ◎ The commit() method steps are:
- ~IF[ コレの`状態$tx ~NEQ `作動中$i ] ⇒ ~THROW `InvalidStateError$E ◎ If this's state is not active, then throw an "InvalidStateError" DOMException.
- `~txを~commitする$( コレ ) ◎ Run commit a transaction with this.
🚧 これは、 この版による新たな~methodである。 [ Chrome 76, Edge 79, Firefox 74, Safari 15 ]から~supportされている。 🚧 ◎ 🚧 The commit() method is new in this edition. It is supported in Chrome 76, Edge 79, Firefox 74, and Safari 15. 🚧
注記: `~tx$上でこの~methodを~callすることは、 通常は必要yでない。 ~txは、 未決な要請がすべて満たされ,新たな要請は為されていなければ,自動的に~commitされる。 この~callを利用すれば、 未決な`要請$から配送される~eventを待機することなく,`~commit$処理-を開始できる。 ◎ NOTE: It is not normally necessary to call commit() on a transaction. A transaction will automatically commit when all outstanding requests have been satisfied and no new requests have been made. This call can be used to start the commit process without waiting for events from outstanding requests to be dispatched.
`onabort@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `abort$et である。 ◎ The onabort attribute is an event handler IDL attribute whose event handler event type is abort.
`oncomplete@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `complete$et である。 ◎ The oncomplete attribute is an event handler IDL attribute whose event handler event type is complete.
`onerror@m 属性は、 `~event~handler~IDL属性$であり,その`~event~handler~event型$は `error$et である。 ◎ The onerror attribute is an event handler IDL attribute whose event handler event type is error.
注記: `~tx$が成功裡に完了したかどうかは、 要請に配送される `success$et ~eventではなく,`~tx$に配送される `complete$et ~eventを~listenして決定すること — `~tx$は、 `success$et ~eventを発火した後でも失敗し得るので。 ◎ NOTE: To determine if a transaction has completed successfully, listen to the transaction's complete event rather than the success event of a particular request, because the transaction can still fail after the success event fires.
X. この訳に特有な各種~algo
【 この節では、 原文~仕様の各種~API定義に繰り~~返し現れる記述を集約して定義する。 集約~以外にも、 ~APIの演算において即時に行われる演算 (失敗した場合は例外が投出される, この節にて述べるもの)と, `要請$にて非同期に行われる演算(失敗は~eventを通して通知される) とを区別して,挙動を明快にする目的もある。 【! 両者が同じ下位~algoを重複して呼出すこともある。】 】
X.1. Error( %~error名 )
名前 %~error名 の新たな `DOMException$I ~objを`作成して@~WEBIDL#dfn-create-exception$返す。
X.2. 状態を検査する( %O, %要求mode )
%O を通して[ `保管庫$/`索引$ ]に[ ~accessし得るかどうか, および演算し得るかどうか ]を検査する:
- ~Assert: %O は[ `保管庫~handle$/`索引~handle$/`~cursor$ ]である
-
~IF[ %O は`~cursor$である ]:
- %O ~SET %O の`~source$Cs
- 下の手続きを `段 A^i, `段 C^i, `段 B^i の順に実行する
- ~RET
-
`段 A^i:
- %~tx ~LET %O が`専属する$~tx
- ~IF[ %要求mode ~EQ `versionchange^l ]~AND[ %~tx は`昇格~tx$でない ] ⇒ ~THROW `InvalidStateError$E ◎ If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException.
-
`段 B^i:
- ~IF[ %O↗ はすでに削除されている ] ⇒ ~THROW `InvalidStateError$E ◎ If index or index’s object store has been deleted, throw an "InvalidStateError" DOMException. ◎ If store has been deleted, throw an "InvalidStateError" DOMException.
-
`段 C^i:
- ~IF[ %~tx の`状態$tx ~NEQ `作動中$i ] ⇒ ~THROW `TransactionInactiveError$E ◎ If transaction’s state is not active, then throw a "TransactionInactiveError" DOMException.
- ~IF[ %要求mode ~EQ `readwrite^l ]~AND[ %~tx は`~readonly~tx$である ] ⇒ ~THROW `ReadOnlyError$E ◎ If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException.
【 原文では、 `IDBIndex.name$m, `IDBObjectStore.name$m の設定子については、 上の手続きを他と異なる順序で検査するように記述されている (この2つについても互いに異なる — 単なる誤記かも?)。 詳細は原文を参照されたし。 `現実の実装も,上のものと一致するとは限らない@~IDBISSUES/11$ (各~実装, 各~methodごとにまちまちな部分もあるかもしれない)。 】
X.3. Value( %key )
所与の[ `~key$/ ε ]を値に変換した結果を返す:
- ~IF[ %key ~EQ ε ] ⇒ ~RET `undefined^jv
- ~RET `~keyを値に変換する$( %key )
X.4. Key( %入力 )
所与の値を`~key$に変換した結果を返すか例外を`投出-$する:
- %~key ~LET `値を~keyに変換する$( %入力 ) ?
- ~IF[ %~key ~EQ `妥当でない^i ] ⇒ ~THROW `DataError$E
- ~RET %~key
X.5. Extract( %値, %~key~path, %生成器 )
所与の ( `値$, `~key~path$, `~key生成器$ ) に対し,[ `~key$ / ε ]を返すか例外を`投出-$する:
- %抽出d~key ~LET `値から~keyを抽出する$ ( %値, %~key~path ) ?
-
%抽出d~key に応じて:
- `~key$である
- ~RET %抽出d~key
- `妥当でない^i
- ~THROW `DataError$E
- `失敗^i
-
- ~IF[ %生成器 ~EQ ε ] ⇒ ~THROW `DataError$E
- ~RET ε
X.6. Dispatch( %~target, %~event )
%~target に向けて %~event を配送した上で,真偽値を返す — この~algoの目的においては、 %~event には真偽値をとる `(旧来の)~listenerは投出したか@ が結付けられ,初期~時は ~F をとるとする:
- `~eventを配送する$( %~target, %~event )
- ~RET %~event の`(旧来の)~listenerは投出したか$
5. 各種~algo
5.1. ~db接続の~open法
`~db接続を~openする@ ときは、 所与の ( `~storage~key$ %~storage~key, `名前$db %名前 `~version$db %~version `~open要請$ %要請 ) に対し,次を走らす: ◎ To open a database connection with storageKey which requested the database to be opened, a database name, a database version, and a request, run these steps:
- %~queue ~LET ( %~storage~key, %名前 ) に対する`接続~queue$ ◎ Let queue be the connection queue for storageKey and name.
- %要請 を %~queue に追加する ◎ Add request to queue.
- %~queue 内の %要請 以前の要請すべてが処理されるまで待機する ◎ Wait until all previous requests in queue have been processed.
- %~db ~LET %~storage~key に`専属する$`~db$のうち,次を満たすもの ⇒ `名前$db ~EQ %名前 ◎ Let db be the database named name in storageKey, or null otherwise.
- ~IF [ %~version ~EQ ε ] ⇒ %~version ~SET [ %~db ~EQ ε ならば 1 / ~ELSE_ %~db の`~version$db ] ◎ If version is undefined, let version be 1 if db is null, or db’s version otherwise.
-
~IF [ %~db ~EQ ε ]:
- %~db ~LET 次のようにされた,新たな`~db$ ⇒# %~storage~key に`専属する$, `名前$db ~SET %名前, `~version$db ~SET `0^c, `専属する$`保管庫$はない
- ~IF[ 何らかの事由で前~段は失敗した ] ⇒ ~RET `Error$( 適切な~error名 ) — 例えば `QuotaExceededError$E / `UnknownError$E
- ~IF[ %~version ~LT %~db の`~version$db ] ⇒ ~RET `Error$( `VersionError$E ) ◎ If db’s version is greater than version, return a newly created "VersionError" DOMException and abort these steps.
- %新~接続 ~LET %~db を`~access先$とする新たな`接続$ ◎ Let connection be a new connection to db.
- %新~接続 の`~version$Cn ~SET %~version ◎ Set connection’s version to version.
-
~IF [ %~version ~GT %~db の`~version$db ]: ◎ If db’s version is less than version, then:
- %接続~群 ~LET [ %~db を`~access先$とする`接続$のうち %新~接続 でないもの ]たちが成す`集合$ ◎ Let openConnections be the set of all connections, except connection, associated with db.
-
%接続~群 を成す ~EACH( %接続 ) に対し ⇒ ~IF[ %接続 の`状態$Cn ~EQ `~open中$i ] ⇒ 次を走らす`~taskを~queueする$ ⇒ `~version変更~eventを発火する$( %接続, `versionchange$et, %~db の`~version$db, %~version ) ◎ For each entry of openConnections that does not have its close pending flag set to true, queue a task to fire a version change event named versionchange at entry with db’s version and version.
注記: この~eventの発火は、 上の反復の途中で,いくつかの接続を`~close$させ得る。 それらの接続に向けては、 まだ終えてなくとも `versionchange$et ~eventは発火されない。 ◎ NOTE: Firing this event might cause one or more of the other objects in openConnections to be closed, in which case the versionchange event is not fired at those objects, even if that hasn’t yet been done.
- すべての~eventが発火されるまで待機する ◎ Wait for all of the events to be fired.
- ~IF[ %接続~群 内に,[ `状態$Cn ~NEQ `~close済み$i ]なる`接続$が依然としてある ] ⇒ 次を走らす`~taskを~queueする$ ⇒ `~version変更~eventを発火する$( %新~接続, `blocked$et, %~db の`~version$db, %~version ) ◎ If any of the connections in openConnections are still not closed, queue a task to fire a version change event named blocked at request with db’s version and version.
- %接続~群 を成す すべての`接続$について,[ その`状態$Cn ~EQ `~close済み$i ]になるまで,待機する ◎ Wait until all connections in openConnections are closed.
-
`~dbを昇格する$( %新~接続, %~version, %要請 ) ◎ Run upgrade a database using connection, version and request.
【 `昇格~tx$が`完遂-$するまで待機した上で 】
- [ %新~接続 の`状態$Cn ~EQ `~close済み$i ]になったときは ⇒ ~RET `Error$( `AbortError$E ) ◎ If connection was closed, return a newly created "AbortError" DOMException and abort these steps.
-
`昇格~tx$が中止されたときは:
- `~db接続を~closeする$( %新~接続 )
- ~RET `Error$( `AbortError$E )
- ~RET %新~接続 ◎ Return connection.
5.2. ~db接続の~close法
`~db接続を~closeする@ ときは、 所与の ( `接続$ %接続, %強制するか ~IN { `強制する^i, ε } ) に対し,次を走らす: ◎ To close a database connection with a connection object, and an optional forced flag, run these steps:
- %接続 の`状態$Cn ~SET `~close待ち$i ◎ Set connection’s close pending flag to true.
- %~tx群 ~LET [ %接続 に`専属する$`~tx$であって, `完遂-$していないもの ]たちが成す集合 ◎ ↓
- ~IF[ %強制するか ~EQ `強制する^i ] ⇒ %~tx群 を成す ~EACH( `~tx$ %~tx ) に対し ⇒ `~txを中止する$( %~tx, `AbortError$E ) ◎ If the forced flag is true, then for each transaction created using connection run abort a transaction with transaction and newly created "AbortError" DOMException.
- %~tx群 を成す すべての~txが`完遂-$するまで待機する ◎ Wait for all transactions created using connection to complete.\
- %接続 の`状態$Cn ~SET `~close済み$i ◎ Once they are complete, connection is closed.
-
~IF %強制するか ~EQ `強制する^i ⇒ `~eventを発火する$( %接続, `close$et ) ◎ If the forced flag is true, then fire an event named close at connection.
注記: `close$et ~eventが発火されるのは、 接続が異常に~closeされた場合に限られる — 例えば: `~storage~key$に対する~storageが~clearされた場合 / 破損または入出力~errorがあるとき。 明示的に `close()$m を~callした場合には、 この~eventは`発火されない^em。 ◎ NOTE: The close event only fires if the connection closes abnormally, e.g. if the storage key's storage is cleared, or there is corruption or an I/O error. If close() is called explicitly the event does not fire.
注記: %接続 の`状態$Cnが `~close待ち$i になって以降は、 %接続 を利用して新たな`~tx$を`作成-$することはできなくなる。 ~txを`作成-$する すべての~methodは、 最初に %接続 の`状態$Cnを検査した上で, `~open中$i でないならば例外を投出する。 ◎ NOTE: Once a connection's close pending flag has been set to true, no new transactions can be created using the connection. All methods that create transactions first check the connection's close pending flag first and throw an exception if it is true.
注記: %接続 が `~close済み$i になったなら、[ 所与の`~db$( %接続 ↗ )への`接続$たち すべてが~closeされる ]まで`待機して@#delete-close-block$いた[ `~dbを昇格する$/`~dbを削除する$ ]演算は,`阻まれ@#version-change-close-block$ないようになり得る。 ◎ NOTE: Once the connection is closed, this can unblock the steps to upgrade a database, and the steps to delete a database, which both wait for connections to a given database to be closed before continuing.
5.3. ~dbの削除-法
`~dbを削除する@ ときは、 所与の ( `~storage~key$ %~storage~key, `名前$db %名前, `~open要請$ %要請 ) に対し,次を走らす: ◎ To delete a database with the storageKey that requested the database to be deleted, a database name, and a request, run these steps:
- %~queue ~LET ( %~storage~key, %名前 ) に対する`接続~queue$ ◎ Let queue be the connection queue for storageKey and name.
- %要請 を %~queue に追加する ◎ Add request to queue.
- %~queue 内の %要請 以前の要請すべてが処理されるまで待機する ◎ Wait until all previous requests in queue have been processed.
- %~db ~LET %~storage~key に`専属する$`~db$であって, [ `名前$db ~EQ %名前 ]なるもの ◎ Let db be the database named name in storageKey, if one exists.\
- ~IF[ %~db ~EQ ε ] ⇒ ~RET 0 ◎ Otherwise, return 0 (zero).
- %接続~群 ~LET [ %~db を`~access先$とする`接続$ ]のうち[ `状態$Cn ~NEQ `~close済み$i ]を満たすものたちが成す`集合$ ◎ Let openConnections be the set of all connections associated with db.
-
%接続~群 を成す ~EACH( %接続 ) に対し ⇒ ~IF[ %接続 の`状態$Cn ~EQ `~open中$i ] ⇒ 次を走らす`~taskを~queueする$ ⇒ ~version変更~eventを発火する$( %接続, `versionchange$et, %~db の`~version$db, ~NULL ) ◎ For each entry of openConnections that does not have its close pending flag set to true, queue a task to fire a version change event named versionchange at entry with db’s version and null.
注記: ここでも,`~dbの~open法と同様の注記@#_note-open-steps$が該当する。 ◎ NOTE: Firing this event might cause one or more of the other objects in openConnections to be closed, in which case the versionchange event is not fired at those objects, even if that hasn’t yet been done.
- すべての~eventが発火されるまで待機する ◎ Wait for all of the events to be fired.
- ~IF[ %接続~群 内に[ `状態$Cn ~NEQ `~close済み$i ]なる`接続$は依然としてある ] ⇒ 次を走らす`~taskを~queueする$ ⇒ `~version変更~eventを発火する$( %要請, `blocked$et, %~db の`~version$db, ~NULL ) ◎ If any of the connections in openConnections are still not closed, queue a task to fire a version change event named blocked at request with db’s version and null.
- %接続~群 を成すすべての`接続$について,[ その`状態$Cn ~EQ `~close済み$i ]になるまで,待機する ◎ Wait until all connections in openConnections are closed.
- %~version ~LET %~db の`~version$db ◎ Let version be db’s version.
- %~db を削除する ◎ Delete db.\
- ~IF[ 何らかの事由で前~段は失敗した ] ⇒ ~RET `Error$( 適切な~error名 ) — 例えば `QuotaExceededError$E / `UnknownError$E ◎ If this fails for any reason, return an appropriate error (e.g. "QuotaExceededError" or "UnknownError" DOMException).
- ~RET %~version ◎ Return version.
5.4. ~txの~commit法
`~txを~commitする@ ときは、 所与の ( `~tx$ %~tx ) に対し,次を走らす: ◎ To commit a transaction with the transaction to commit, run these steps:
- %~tx の`状態$tx ~SET `~commit中$i ◎ Set transaction’s state to committing.
-
この段は`並列的$に走らす: ◎ Run the following steps in parallel:
- %~tx の`要請~list$を成す すべての~itemが`処理-済み$になるまで待機する ◎ Wait until every item in transaction’s request list is processed.
- ~IF[ %~tx の`状態$tx ~NEQ `~commit中$i ] ⇒ ~RET ◎ If transaction’s state is no longer committing, then terminate these steps.
- %~db ~LET ( %~tx が`専属する$`接続$ )↗ ◎ ↓
- %~tx により為された未決な変更のすべてを — %~tx の`耐久能~hint$も考慮する下で — %~db に書込もうと試みる ◎ Attempt to write any outstanding changes made by transaction to the database, considering transaction’s durability hint.
-
~IF[ 前~段により書込む間に~errorが生じた ]: ◎ If an error occurs while writing the changes to the database, then\
- `~txを中止する$( %~tx, その~errorに適切な~error名 (例: `QuotaExceededError$E / `UnknownError$E ) ) ◎ run abort a transaction with transaction and an appropriate type for the error, for example "QuotaExceededError" or "UnknownError" DOMException,\
- ~RET ◎ and terminate these steps.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- ~IF[ %~tx は`昇格~tx$である ] ⇒ %~db の`昇格~tx$db ~SET ε ◎ If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.
- %~tx の`状態$tx ~SET `完遂d$i ◎ Set transaction’s state to finished.
-
`~eventを発火する$( %~tx, `complete$et ) ◎ Fire an event named complete at transaction.
注記: この~event用の~event~handlerから例外が投出されようが、 ~db変更の書込みは~eventを配送する前に終わるので,~txは~commitされる。 `complete$et ~eventが発火されるのは、 ~txが成功裡に書込まれた後に限られる。 ◎ NOTE: Even 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 place. Only after the transaction has been successfully written is the complete event fired.
- ~IF[ %~tx は`昇格~tx$である ] ⇒ [ %~tx を`設置-先~tx$とする`要請$ 【すなわち、`~dbを昇格する$ときに渡された %要請 】 ]の`設置-先~tx$ ~SET ε ◎ If transaction is an upgrade transaction, then let request be the request associated with transaction and set request’s transaction to null.
【 `~readonly~tx$に対しては、 この手続きは (特に呼出さないようにする要件は見当たらないが) 実質的に何もしない。 】
5.5. ~txの中止-法
`~txを中止する@ ときは、 所与の ( `~tx$ %~tx, ~error名 %error ) に対し,次を走らす: ◎ To abort a transaction with the transaction to abort, and error, run these steps:
- %~db ~LET ( %~tx が`専属する$`接続$ )↗ ◎ ↓
-
%~tx により %~db に為された,すべての変更を、 復帰させる — `昇格~tx$に対しては:
- %~db に`専属する$[ `保管庫$/`索引$ ]たちが成す集合, および`~version$dbの変更も,復帰させる。
- %~tx の間に作成された[ `保管庫$/`索引$ ]は、 他の~algoの目的においては,削除されたものと見なされる。
-
~IF[ %~tx は`昇格~tx$である ] ⇒ `昇格~txを中止する$( %~tx ) ◎ If transaction is an upgrade transaction, run the steps to abort an upgrade transaction with transaction.
注記: この結果、[ %~tx が`専属する$`接続$ / %~tx に`専属する$[ `保管庫~handle$ / `索引~handle$ ]]すべての~instanceに対する変更は復帰されることになる。 ◎ NOTE: This reverts changes to all connection, object store handle, and index handle instances associated with transaction.
- %~tx の`状態$tx ~SET `完遂d$i ◎ Set transaction’s state to finished.
- ~IF[ %error ~NEQ ~NULL ] ⇒ %~tx の`~error$tx ~SET `Error$( %error ) ◎ If error is not null, set transaction’s error to error.
-
%~tx の`要請~list$を成す ~EACH( `要請$ %要請 ) に対し: ◎ For each request of transaction’s request list,\
- %要請 を`非同期に実行する$手続きを中止する ◎ abort the steps to asynchronously execute a request for request,\
- %要請 の`処理-済みか$ ~SET ~T ◎ set request’s processed flag to true,\
-
次を走らす`~taskを~queueする$: ◎ and queue a task to run these steps:
- %要請 の ⇒# `済んだか$ ~SET ~T, `結果$ ~SET ε, `~error$ ~SET `Error$( `AbortError$E ) ◎ Set request’s done flag to true. ◎ Set request’s result to undefined. ◎ Set request’s error to a newly created "AbortError" DOMException.
- `~eventを発火する$( %要請, `error$et ) — 次のように初期化して ⇒# `bubbles$m 属性 ~SET ~T, `cancelable$m 属性 ~SET ~T ◎ Fire an event named error at request with its bubbles and cancelable attributes initialized to true.
注記: これは常に `error$et ~eventを発火させるとは限らない。 例えば~txが `~commit中$i の間に~errorに因り中止された場合や,それは失敗した最後の残りの要請であった場合 【?】。 ◎ NOTE: This 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.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- ~IF[ %~tx は`昇格~tx$である ] ⇒ %~db の`昇格~tx$db ~SET ε ◎ If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.
- `~eventを発火する$( %~tx, `abort$et ) — 次のように初期化して ⇒ `bubbles$m 属性 ~SET ~T ◎ Fire an event named abort at transaction with its bubbles attribute initialized to true.
-
~IF[ %~tx は`昇格~tx$である ]: ◎ If transaction is an upgrade transaction, then:
- %要請 ~LET %~tx を`設置-先~tx$とする`~open要請$ 【すなわち、`~dbを昇格する$ときに渡された %要請 】 ◎ Let request be the open request associated with transaction.
- %要請 の ⇒# `設置-先~tx$ ~SET ε, `結果$ ~SET ε, `処理-済みか$ ~SET ~F, `済んだか$ ~SET ~F ◎ Set request’s transaction to null. ◎ Set request’s result to undefined. ◎ Set request’s processed flag to false. ◎ Set request’s done flag to false.
5.6. 要請の非同期的な実行-法
所与の ( ~db上で遂行される`演算$ %演算 ) を走らす `要請を非同期に実行する@ ときは、 所与の ( [ `保管庫~handle$/`索引~handle$ ] %~source, `要請$ %要請 (省略時は ε ) ) に対し,次の手続きを走らす — この手続きは:
- %要請 が省略された場合、 新たな`要請$を作成して返す。
- 当の`要請$の`設置-先~tx$が`~txを中止-$する手続きを利用して`中止-$された場合、 いつでも中止され得る
- %~tx ~LET %~source が`専属する$`~tx$ ◎ Let transaction be the transaction associated with source.
- ~Assert: %~tx の`状態$tx ~EQ `作動中$i ◎ Assert: transaction’s state is active.
- ~IF[ %要請 ~EQ ε ] ⇒ %要請 ~SET `要請$を表現する,新たな `IDBRequest$I ~obj — その ⇒# `~source$ ~SET %~source, `設置-先~tx$ ~SET %~tx ◎ If request was not given, let request be a new request with source as source.
- %~tx の`要請~list$に %要請 を追加する ◎ Add request to the end of transaction’s request list.
- ~RET %要請 — ただし,以降も`並列的$に走らす ◎ Run these steps in parallel:
- 次が満たされるまで待機する ⇒ %要請 は[ %~tx の`要請~list$を成す`処理-済み$でない~item ]のうち最初のものである ◎ Wait until request is the first item in transaction’s request list that is not processed.
- %結果 ~LET %演算 を遂行した結果 ◎ Let result be the result of performing operation.
- ~IF[ %結果 は~errorである ]~AND[ %~tx の`状態$tx ~EQ `~commit中$i ] ⇒# `~txを中止する$( %~tx, %結果 ); ~RET ◎ If result is an error and transaction’s state is committing, then run abort a transaction with transaction and result, and terminate these steps.
-
~IF[ %結果 は~errorである ] ⇒ %演算 により生じたすべての変更を復帰する ◎ If result is an error, then revert all changes made by operation.
注記: これは、 この要請により行われた変更のみを復帰させる。 ~txにより為された他の変更は復帰されない。 ◎ NOTE: This only reverts the changes done by this request, not any other changes made by the transaction.
- %要請 の`処理-済みか$ ~SET ~T ◎ Set request’s processed flag to true.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- %~tx の`要請~list$から %要請 を除去する ◎ Remove request from transaction’s request list.
-
%要請 の ⇒# `済んだか$ ~SET ~T, `結果$ ~SET ε, `~error$ ~SET ε ◎ Set request’s done flag to true. ◎ ↓
-
~IF[ %結果 は~errorである ]: ◎ If result is an error, then:
- %要請 の`~error$ ~SET %結果 ◎ Set request’s result to undefined. ◎ Set request’s error to result.
- `~error~eventを発火する$( %要請 ) ◎ Fire an error event at request.
-
~ELSE: ◎ Otherwise:
- %要請 の`結果$ ~SET %結果 ◎ Set request’s result to result. ◎ Set request’s error to undefined.
- `~success~eventを発火する$( %要請 ) ◎ Fire a success event at request.
◎ ↑↑Return request.
5.7. ~dbの昇格-法
`~dbを昇格する@ ときは、 所与の ( `接続$ %接続, %~version `要請$ %要請 ) に対し,次に従う: ◎ To upgrade a database with connection (a connection), a new version, and a request, run these steps:
- %~db ~LET %接続↗ ◎ Let db be connection’s database.
- %~tx ~LET 新たな`昇格~tx$ — その ⇒# `専属する$`接続$ ~SET %接続, `視野$ ~SET %接続 の`保管庫~集合$Cn ◎ Let transaction be a new upgrade transaction with connection used as connection. ◎ Set transaction’s scope to connection’s object store set.
- %~db の`昇格~tx$db ~SET %~tx ◎ Set db’s upgrade transaction to transaction.
- %~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
-
%~tx を開始する ◎ Start transaction.
注記: この`~tx$が`完遂-$するまで,他の`接続$は %~db を~openできないことに注意。 ◎ NOTE: Note that until this transaction is finished, no other connections can be opened to the same database.
- %旧~version ~LET %~db の`~version$db ◎ Let old version be db’s version.
- %~db の`~version$db ~SET %~version — この変更は,`~tx$の一部と見なされ、 ~txが`中止-$された場合には復帰される。 ◎ Set db’s version to version. This change is considered part of the transaction, and so if the transaction is aborted, this change is reverted.
- %要請 の`処理-済みか$ ~SET ~T ◎ Set request’s processed flag to true.
-
次を走らす`~taskを~queueする$: ◎ Queue a task to run these steps:
- %要請 の`結果$ ~SET %接続 ◎ Set request’s result to connection.
- %要請 の`設置-先~tx$ ~SET %~tx ◎ Set request’s transaction to transaction.
- %要請 の`済んだか$ ~SET ~T ◎ Set request’s done flag to true.
- %~tx の`状態$tx ~SET `作動中$i ◎ Set transaction’s state to active.
- %~listenerは投出したか ~LET `~version変更~eventを発火する$( %要請, `upgradeneeded$et, %旧~version, %~version ) ◎ Let didThrow be the result of firing a version change event named upgradeneeded at request with old version and version.
- %~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
- ~IF[ %~listenerは投出したか ~EQ ~T ] ⇒ `~txを中止する$( %~tx, `AbortError$E ) ◎ If didThrow is true, run abort a transaction with transaction and a newly created "AbortError" DOMException.
-
%~tx が`完遂-$するまで待機する ◎ Wait for transaction to finish.
注記: [ `~txを~commitする$/ `~txを中止する$ ]手続きなど,~txの存続期間に呼出される一部の~algoは、 `昇格~tx$に特有な手続きを含む。 ◎ NOTE: Some of the algorithms invoked during the transaction's lifetime, such as the steps to commit a transaction and the steps to abort a transaction, include steps specific to upgrade transactions.
5.8. 昇格~txの中止-法
`昇格~txを中止する@ ときは、 所与の ( `昇格~tx$ %~tx ) に対し,次を走らす: ◎ To abort an upgrade transaction with transaction, run these steps:
注記: この手続きは,`~txを中止-$する手続き内で必要に応じて走らされ、 `~db$に`専属する$[ `保管庫$/`索引$ ]たちが成す集合, および `~version$db変更を復帰させる。 【~APIに公開される部分を復帰させる。】 ◎ NOTE: These steps are run as needed by the steps to abort a transaction, which revert changes to the database including the set of associated object stores and indexes, as well as the change to the version.
- %接続 ~LET %~tx が`専属する$`接続$ ◎ Let connection be transaction’s connection.
- %~db ~LET %接続↗ ◎ Let database be connection’s database.
-
%接続 の`~version$Cn ~SET %~db の`~version$db ( %~tx が %~db を新たに作成したのであれば 0 ) ◎ Set connection’s version to database’s version if database previously existed, or 0 (zero) if database was newly created.
注記: これは、 `IDBDatabase!I ~objから返される `version$m 値を復帰させる。 ◎ NOTE: This reverts the value of version returned by the IDBDatabase object.
-
%接続 の`保管庫~集合$Cn ~SET %~db に`専属する$`保管庫$たちが成す集合 ( %~tx が %~db を新たに作成したのであれば 空~集合 ) ◎ Set connection’s object store set to the set of object stores in database if database previously existed, or the empty set if database was newly created.
注記: これは、 `IDBDatabase!I ~objから返される `objectStoreNames$m 値を復帰させる。 ◎ NOTE: This reverts the value of objectStoreNames returned by the IDBDatabase object.
-
この段において反復される~handleたちには、 その`~access先$が %~tx により削除-または作成されたものも含まれることに注意。 ◎ ↓
%~tx に`専属する$ ~EACH( `保管庫~handle$ %H ) に対し: ◎ For each object store handle handle associated with transaction, including those for object stores that were created or deleted during transaction:
- ~IF[ %H↗ は %~tx により作成されたものではない ] ⇒ %H の`名前$OsH ~SET %H↗ の`名前$Os ◎ If handle’s object store was not newly created during transaction, set handle’s name to its object store's name.
-
%H の`索引~集合$OsH ~SET %H↗ に`専属する$`索引$たちが成す集合 ◎ Set handle’s index set to the set of indexes that reference its object store.
注記: これは、 %H (を表現する `IDBObjectStore!I ~obj)が返す[ `name$m, `indexNames$m ]値を復帰させる。 ◎ NOTE: This reverts the values of name and indexNames returned by related IDBObjectStore objects.
~scriptは、 %~tx が中止されて以降も,依然として自身が有する %H の[ `name$m / `indexNames$m ]属性は~queryできる — %~tx の `objectStore()$m ~methodを利用しても, %H↗ には~accessできなくなるが。 ◎ How is this observable? ◎ Although script cannot access an object store by using the objectStore() method on an IDBTransaction instance after the transaction is aborted, it can still have references to IDBObjectStore instances where the name and indexNames properties can be queried.
-
%H に`専属する$ ~EACH( `索引~handle$ %I ) に対し: ◎ For each index handle handle associated with transaction, including those for indexes that were created or deleted during transaction:
- ~IF[ %I↗ は %~tx により作成されたものではない ] ⇒ %I の`名前$IxH ~SET %I↗ の`名前$Ix ◎ If handle’s index was not newly created during transaction, set handle’s name to its index's name.
注記: これは、 %I (を表現する `IDBIndex!I ~obj)が返す `name$m 値を復帰させる。 ◎ NOTE: This reverts the value of name returned by related IDBIndex objects.
~scriptは、 %~tx が中止されて以降も,自身が有する %I の `name$m 属性は~queryできる — %H の `index()$m ~methodを利用しても, %I↗ には~accessできなくなるが。 ◎ How is this observable? ◎ Although script cannot access an index by using the index() method on an IDBObjectStore instance after the transaction is aborted, it can still have references to IDBIndex instances where the name property can be queried.
注記: [ %接続 を表現する `IDBDatabase!I ~instance ]の `name$m は、 中止された`昇格~tx$が新たな`~db$を作成していたとしても,`値を保持し続ける$。 ◎ NOTE: The name property of the IDBDatabase instance is not modified, even if the aborted upgrade transaction was creating a new database.
5.9. `success^et ~eventの発火-法
`~success~eventを発火する@ ときは、 所与の ( `要請$ %要請 ) に対し,次を走らす: ◎ To fire a success event at a request, run these steps:
- %~event ~LET `~eventを作成する$( `Event$I ) ◎ Let event be the result of creating an event using Event.
- %~event の各種~属性を次のように初期化する ⇒# `type$m ~SET `success^l, `bubbles$m ~SET ~F, `cancelable$m ~SET ~F ◎ • Set event’s type attribute to "success". • Set event’s bubbles and cancelable attributes to false.
- %~tx ~LET %要請 の`設置-先~tx$ ◎ Let transaction be request’s transaction. ◎ ↓Let legacyOutputDidListenersThrowFlag be initially false.
- ~IF[ %~tx の`状態$tx ~EQ `非作動中$i ] ⇒ %~tx の`状態$tx ~SET `作動中$i ◎ If transaction’s state is inactive, then set transaction’s state to active.
- %~listenerは投出したか ~LET `Dispatch$( %要請, %~event ) ◎ Dispatch event at request with legacyOutputDidListenersThrowFlag.
- ~IF[ %~tx の`状態$tx ~NEQ `作動中$i ] ⇒ ~RET ◎ If transaction’s state is active, then:
- %~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
- ~IF[ %~listenerは投出したか ~EQ ~T ] ⇒ `~txを中止する$( %~tx, `AbortError$E ) ◎ If legacyOutputDidListenersThrowFlag is true, then run abort a transaction with transaction and a newly created "AbortError" DOMException.
- ~IF[ %~tx の`要請~list$は空である ] ⇒ `~txを~commitする$( %~tx ) ◎ If transaction’s request list is empty, then run commit a transaction with transaction.
5.10. `error^et ~eventの発火-法
`~error~eventを発火する@ ときは、 所与の ( `要請$ %要請 ) に対し,次を走らす: ◎ To fire an error event at a request, run these steps:
- %~event ~LET `~eventを作成する$( `Event$I ) ◎ Let event be the result of creating an event using Event.
- %~event の各種~属性を次のように初期化する ⇒# `type$m ~SET `error^l, `bubbles$m ~SET ~T, `cancelable$m ~SET ~T ◎ • Set event’s type attribute to "error". • Set event’s bubbles and cancelable attributes to true.
- %~tx ~LET %要請 の`設置-先~tx$ ◎ Let transaction be request’s transaction. ◎ ↓Let legacyOutputDidListenersThrowFlag be initially false.
- ~IF[ %~tx の`状態$tx ~EQ `非作動中$i ] ⇒ %~tx の`状態$tx ~SET `作動中$i ◎ If transaction’s state is inactive, then set transaction’s state to active.
- %~listenerは投出したか ~LET `Dispatch$( %要請, %~event ) ◎ Dispatch event at request with legacyOutputDidListenersThrowFlag.
- ~IF[ %~tx の`状態$tx ~NEQ `作動中$i ] ⇒ ~RET ◎ If transaction’s state is active, then:
- %~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
-
~IF[ %~listenerは投出したか ~EQ ~T ]: ◎ If legacyOutputDidListenersThrowFlag is true, then\
- `~txを中止する$( %~tx, `AbortError$E ) ◎ run abort a transaction with transaction and a newly created "AbortError" DOMException and\
- ~RET ◎ terminate these steps.\
この段は、[ %~event の`取消されたか$ev ~EQ ~F ]の下でも行われる。 ◎ This is done even if event’s canceled flag is false.
注記: すなわち、 `error$et ~eventの配送-時に,いずれかの~event~handlerから例外が投出されたときは:
- ~eventが `preventDefault()$m の~callにより取消されようが されまいが,~txは中止される。
- ~tx上の `error^m 属性には、 要請の`~error$に代わって, `AbortError$E が利用される。
- ~IF[ %~event の`取消されたか$ev ~EQ ~F ] ⇒# `~txを中止する$( %~tx, %要請 の`~error$ ); ~RET ◎ If event’s canceled flag is false, then run abort a transaction using transaction and request's error, and terminate these steps.
- ~IF[ %~tx の`要請~list$は空である ] ⇒ `~txを~commitする$( %~tx ) ◎ If transaction’s request list is empty, then run commit a transaction with transaction.
5.11. 値の~clone法
`~txの間に値を~cloneする@ ときは、 所与の ( %値, `~tx$ %~tx ) に対し,次を走らす: ◎ To make a clone of value in targetRealm during transaction, run these steps:
注記: 値を複製するわけは: 値は格納-時に【 `StructuredSerializeForStorage$jA により】直列化されるが,この手続きを用いて複製として扱うことにより、 この仕様~内の他の~algoは,それを~ES値として扱えるようになる。 実装は、 異なる挙動が観測され得ないならば,これを最適化できる。 【! https://github.com/w3c/IndexedDB/commit/4ccf4371e3e1a32a6f3ab1606605e71a8f4f8334】
- %宛先~realm ~LET ~UAにより定義される`~realm$ 【この訳では、この手続きを利用している各所の記述を集約するため,この段と上の注記をここに追加している。】
- ~Assert: %~tx の`状態$tx ~EQ `作動中$i ◎ Assert: transaction’s state is active.
-
%~tx の`状態$tx ~SET `非作動中$i ◎ Set transaction’s state to inactive.
注記: %~tx を `非作動中$i にするのは、 ~cloneする演算により誘発される取得子その他の副作用が, %~tx に対し追加の要請を為せないようにするためである。 ◎ NOTE: The transaction is made inactive so that getters or other side effects triggered by the cloning operation are unable to make additional requests against the transaction.
- %直列形 ~LET ~ABRUPT `StructuredSerializeForStorage$jA( %値 ) ◎ Let serialized be ? StructuredSerializeForStorage(value).
- %~clone ~LET ~ABRUPT `StructuredDeserialize$jA( %直列形, %宛先~realm ) ◎ Let clone be ? StructuredDeserialize(serialized, targetRealm).
- %~tx の`状態$tx ~SET `作動中$i ◎ Set transaction’s state to active.
- ~RET %~clone ◎ Return clone.
6. 各種~db演算
この節では、[ `保管庫$内の~data/`~db$内の`索引$ ]にて行われる各種 演算について述べる。 これらの演算は、 `要請を非同期に実行する$ことにより走ることになる。 ◎ 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.
注記: 以下の各種 演算の手続きにおける `StructuredDeserialize$jA() からは、 ( `~NOABRUPT$ 接頭辞で指示されるとおり) 例外は投出されない — 演算する~dataは、 `StructuredSerializeForStorage$jA() から出力されたものに限られるので。 ◎ NOTE: Invocations of StructuredDeserialize() in the operation steps below can be asserted not to throw (as indicated by the ! prefix) because they operate only on previous output of StructuredSerializeForStorage().
6.1. 保管庫における~storage演算
`保管庫に~recordを格納する@ ときは、 所与の ( `保管庫$ %保管庫, `値$ %値, `~key$ %~key(省略時は ε ), %上書不可か ~IN { `上書不可^i, ε } ) に対し,次を走らす: ◎ To store a record into an object store with store, value, an optional key, and a no-overwrite flag, run these steps:
- %生成器 ~LET %保管庫 の`~key生成器$ ◎ ↓
- %~key~path ~LET %保管庫 の`~key~path$Os ◎ ↓
-
~IF[ %生成器 ~NEQ ε ]: ◎ If store uses a key generator, then:
-
~IF[ %~key ~EQ ε ]: ◎ If key is undefined, then:
- %~key ~LET `保管庫~用の~keyを生成する$( %保管庫 ) ◎ Let key be the result of generating a key for store.
- ~IF[ %~key ~EQ `失敗^i ] ⇒ ~RET `Error$( `ConstraintError$E ) ◎ If key is failure, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps.
- ~IF[ %~key~path ~NEQ ε ] ⇒ `~keyを値の中へ注入する$( %値, %~key, %保管庫 の`~key~path$Os ) ◎ If store also uses in-line keys, then run inject a key into a value using a key path with value, key and store’s key path.
- ~ELSE ⇒ `保管庫~用の~key生成器を可能なら更新する$( %保管庫, %~key ) ◎ Otherwise, run possibly update the key generator for store with key.
-
-
~IF[ %保管庫 の`~record~list$Os内に[ `~key$ ~EQ~cmpkey %~key ]を満たす`~record$は在る ] ◎ ↓
- ~IF[ %上書不可か ~EQ `上書不可^i ] ⇒ ~RET `Error$( `ConstraintError$E ) ◎ If the no-overwrite flag was given to these steps and is true, and a record already exists in store with its key equal to key, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps.
- `保管庫から~recordを削除する$( %保管庫, `Only$( %~key ) ) ◎ If a record already exists in store with its key equal to key, then remove the record from store using delete records from an object store.
- %保管庫 の`~record~list$Osに ~record{ %~key : ~NOABRUPT `StructuredSerializeForStorage$jA( %値 ) } を格納する — それに伴い,~listの~recordたちを~keyの`昇順$で~sortし直すことになる。 ◎ Store a record in store containing key as its key and ! StructuredSerializeForStorage(value) as its value. The record is stored in the object store’s list of records such that the list is sorted according to the key of the records in ascending order.
-
%保管庫 に`専属する$ ~EACH( `索引$ %索引 ) に対し: ◎ For each index which references store:
- %~key集合 ~LET `値から~key集合を抽出する$( %値, %索引 の`~key~path$Ix, %索引 の`複-~entryか$Ix ) ◎ Let index key be the result of extracting a key from a value using a key path with value, index’s key path, and index’s multiEntry flag.
- ~IF[ %~key集合 ~EQ `失敗^i ] ⇒ ~CONTINUE ◎ If index key is an exception, or invalid, or failure, take no further actions for index, and continue these steps for the next index. ◎ NOTE: An exception thrown in this step is not rethrown.
-
~IF[ %索引 の`一意か$Ix ~EQ ~T ]~AND[ %索引 の`~record~list$Ix内に[ `~key$ ~IN~cmpkey %~key集合 ]を満たす`~record$は在る ] ⇒ ~RET `Error$( `ConstraintError$E ) ◎ If index’s multiEntry flag is false, or if index key is not an array key, and if index already contains a record with key equal to index key, and index’s unique flag is true, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps. ◎ If index’s multiEntry flag is true and index key is an array key, and if index already contains a record with key equal to any of the subkeys of index key, and index’s unique flag is true, then this operation failed with a "ConstraintError" DOMException. Abort this algorithm without taking any further steps.
【 この手続きを呼び出した要請は失敗とされ、 `要請を非同期に実行する$手続きに従って,ここまでの改変は復帰されることになる。 したがって、 索引たちを反復する順序も,結果には影響しない。 】
-
%~key集合 を成す ~EACH( %索引~key ) に対し ⇒ %索引 の`~record~list$Ix内に 新たな~record{ %索引~key : %~key } を格納する — それに伴い、 ~record~listは 先ず~keyの`昇順$に~sortした上で,~keyが等しい~recordたちを値の`昇順$に~sortすることになる。 ◎ If index’s multiEntry flag is false, or if index key is not an array key then store a record in index containing 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 key, then for each subkey of the subkeys of index key store a record in index containing subkey 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.
注記: %~key集合 が空でも妥当である — その場合、 索引に追加される~recordはない。 ◎ NOTE: It is valid for there to be no subkeys. In this case no records are added to the index. ◎ NOTE: Even if any member of subkeys is itself an array key, the member is used directly as the key for the index record. Nested array keys are not flattened or "unpacked" to produce multiple rows; only the outer-most array key is.
- ~RET %~key ◎ Return key.
6.2./6.3. 保管庫/索引から検索取得する演算
【! Object Store Retrieval Operations 】 【! Index Retrieval Operations 】【 この訳では、 原文の § 6.2, § 6.3 に定義される各種~演算を入力を成す %~source, %対象 に関する場合分けにより,まとめて定義する。 】
`範囲に入る最初の~entryを検索取得する@ ときは、 所与の ⇒# %~source: `保管庫$/`索引$ %範囲: `~key範囲$ %対象 ~IN { `~key^i, `値^i } ◎終 に対し,次を走らす:
- %~record ~LET %~source の~record~list内に[ `~key$ ~IN~cmpkey %範囲 ]を満たす`~record$は[ 在るならば それらのうち最初のもの/ 無いならば ε ]
- ~IF[ %~record ~EQ ε ] ⇒ ~RET ε
- ~IF[ %~source は`索引$である ] ⇒ %~record ~SET %~record の`参照先~record$
-
%対象 に応じて:
- `~key^i ⇒ ~RET `~keyを値に変換する$( %~record の`~key$ )
-
`値^i:
-
%値 ~LET %~record の`値$
下層~storageから値を読取る間に~errorが生じたときは ⇒ ~RET `Error$( `NotReadableError$E )
【 原文は、 %~source が`索引$である場合に,この取扱いを指定していない(なぜ?)。 】
- ~RET ~NOABRUPT `StructuredDeserialize$jA( %値, `現在の~realm$ )
-
`範囲に入る~entryたちを検索取得する@ ときは、 所与の ⇒# %~source: `保管庫$ / `索引$, %範囲: `~key範囲$, %count: 取り出す最大個数(省略時は ε ), %対象 ~IN { `~key^i, `値^i } ◎終 に対し,次を走らす:
- %~record~list ~LET %~source の~record~list内の[ `~key$ ~IN %範囲 ]を満たす`~record$たちが成す`~list$
- ~IF[ %count ~NIN { ε, 0 } ] ⇒ %~record~list から[ 最初から %count 個までの~record ]以外の~recordを`除去する$
- %~list ~LET 新たな`~list$
-
%~record~list を成す ~EACH( %~record ) に対し:
- ~IF[ %~source は`索引$である ] ⇒ %~record ~SET %~record の`参照先~record$
-
%対象 に応じて:
- `~key^i ⇒ %~list に次の結果を付加する ⇒ `~keyを値に変換する$( %~record の`~key$ )
-
`値^i:
-
%値 ~LET %~record の`値$
下層~storageから値を読取る間に~errorが生じたときは ⇒ ~RET `Error$( `NotReadableError$E )
【 原文は、 %~source が`索引$である場合に,この取扱いを指定していない(なぜ?)。 】
- %~list に次の結果を付加する ⇒ %結果 ~SET ~NOABRUPT `StructuredDeserialize$jA( %値, `現在の~realm$ )
-
- ~RET %~list を `~SeqAny$ 型の値に変換した結果
6.4. 保管庫から~recordを削除する演算
`保管庫から~recordを削除する@ ときは、 所与の ( `保管庫$ %保管庫, `~key範囲$ %範囲 ) に対し,次を走らす: ◎ To delete records from an object store with store and range, run these steps:
- %保管庫 の`~record~list$Osから,次を満たす`~record$をすべて除去する ⇒ `~key$ ~IN~cmpkey %範囲 ◎ Remove all records, if any, from store’s list of records with key in range.
- %保管庫 に`専属する$ ~EACH( `索引$ ) に対し ⇒ `索引$の`~record~list$Ixから,次を満たす`~record$をすべて除去する ⇒ `値$ ~IN~cmpkey %範囲 ◎ For each index which references store, remove every record from index’s list of records whose value is in range, if any such records exist.
- ~RET ε ◎ Return undefined.
6.5. 範囲に入る~recordを数える演算
`範囲に入る~recordを数える@ 手続きは、 所与の ( `保管庫$または`索引$ %~source, `~key範囲$ %範囲 ) に対し,次を走らす: ◎ To count the records in a range with source and range, run these steps:
- ~RET %~source の~record~list内の,次を満たす`~record$の総数 ⇒ `~key$ ~IN~cmpkey %範囲 ◎ Let count be the number of records, if any, in source’s list of records with key in range. ◎ Return count.
6.6. 保管庫を~clearする演算
`保管庫を~clearする@ ときは、 所与の ( `保管庫$ %保管庫 ) に対し,次を走らす: ◎ To clear an object store with store, run these steps:
- %保管庫 からすべての`~record$を除去する ◎ Remove all records from store.
- %保管庫 に`専属する$ ~EACH( `索引$ ) に対し ⇒ `索引$からすべての`~record$を除去する ◎ In all indexes which reference store, remove all records.
- ~RET ε ◎ Return undefined.
6.X. ~cursorを作成する演算
【 この訳では、 原文にて繰り~~返し現れる記述をこの節に集約して定義する。 】
`~cursorを作成する@ ときは、 所与の ⇒# %~source : `保管庫~handle$/`索引~handle$, %宛先~realm :`~realm$, %方向 : `方向$Cs, %範囲: `~key範囲$, %~keyのみ~flag ~IN { `~keyのみ^i, ε }(省略時は ε ) ◎終 に対し,次を走らす:
- %~keyのみか ~LET ~IS[ %~keyのみ~flag ~EQ `~keyのみ^i ]
- %~interface ~LET %~keyのみか に応じて ⇒# ~T ならば `IDBCursor!I / ~F ならば `IDBCursorWithValue!I
- %~cursor ~LET %宛先~realm 内で %~interface を実装する新たな`~cursor$
- %~cursor の ⇒# `~source$Cs ~SET %~source, `範囲$Cs ~SET %範囲, `方向$Cs ~SET %方向, `位置$Cs ~SET ε, `保管庫~位置$Cs ~SET ε, `~key$Cs ~SET ε, `値$Cs ~SET ε, `値は取得-済みか$Cs ~SET ~F, `~keyのみか$Cs ~SET %~keyのみか
- ~RET `~cursorを反復する$( %~cursor, %宛先~realm )
6.7. ~cursorを反復する演算
`~cursorを反復する@ ときは、 所与の ⇒# %~cursor: `~cursor$, %宛先~realm:`~realm$, %~key : 移動先の`~key$(省略時は ε ), %首key : 保管庫における移動先の`~key$(省略時は ε ), %count : 反復する回数(省略時は ε ) ◎終 に対し,次を走らす: ◎ To iterate a cursor with targetRealm, cursor, an optional key and primaryKey to iterate to, and an optional count, run these steps:
- %~source ~LET %~cursor の`~source$Cs↗ ◎ Let source be cursor’s source.
- %方向 ~LET %~cursor の`方向$Cs ◎ Let direction be cursor’s direction.
- ~Assert: [ %首key ~EQ ε ]~OR[[ %~source は`索引$である ]~AND[ %方向 ~IN { `next^l, `prev^l } ]] ◎ Assert: if primaryKey is given, source is an index and direction is "next" or "prev".
-
%~record~list ~LET %~source 内の すべての~recordからなる~list ◎ Let records be the list of records in source.
注記: %~record~list は常に`~key$の昇順で~sortされる。 %~source が`索引$である場合、 それに加えて,同じ`~key$を有する~recordたちは,それらの`値$ (すなわち, ~recordの`参照先~record$の`~key$) の`昇順$でも~sortされる。 ◎ NOTE: records is always sorted in ascending key order. In the case of source being an index, records is secondarily sorted in ascending value order (where the value in an index is the key of the record in the referenced object store).
- %範囲 ~LET %~cursor の`範囲$Cs ◎ Let range be cursor’s range.
- %位置 ~LET %~cursor の`位置$Cs ◎ Let position be cursor’s position.
- %保管庫~位置 ~LET %~cursor の`保管庫~位置$Cs ◎ Let object store position be cursor’s object store position.
- ~IF[ %count ~EQ ε ] ⇒ %count ~SET 1 ◎ If count is not given, let count be 1.
-
%~record ~LET 次の手続きを走らせた結果 (これは、 %~record~list から一つの~recordに絞り込む):
- %~record~list から[ `~key$ ~NIN~cmpkey %範囲 ]を満たす~recordすべてを除去する
-
~IF[
%位置 ~NEQ ε
]:
-
~IF[ %~source は`保管庫$である ]~OR[ %方向 ~IN { `nextunique$l, `prevunique$l } ] ⇒ %~record~list から[ %方向 に応じて,次に与える条件 ]を満たす~recordすべてを除去する:
- `next$l
- `nextunique$l
- `~key$ ~LTE~cmpkey %位置
- `prev$l
- `prevunique$l
- `~key$ ~GTE~cmpkey %位置
-
~ELSE ⇒ %~record~list から[ %方向 に応じて,次に与える条件 ]を満たす~recordすべてを除去する:
- `next$l
- ( `~key$, `値$ ) ~LTE~cmpkey ( %位置, %保管庫~位置 )
- `prev$l
- ( `~key$, `値$ ) ~GTE~cmpkey ( %位置, %保管庫~位置 )
-
~IF[ %~key ~NEQ ε ]
-
~IF[ %首key ~EQ ε ] ⇒ %~record~list から[ %方向 に応じて,次に与える条件 ]を満たす~recordすべてを除去する:
- `next$l
- `nextunique$l
- `~key$ ~LT~cmpkey %~key
- `prev$l
- `prevunique$l
- `~key$ ~GT~cmpkey %~key
-
~ELSE ⇒ %~record~list から[ %方向 に応じて,次に与える条件 ]を満たす~recordすべてを除去する:
- `next$l
- ( `~key$, `値$ ) ~LT~cmpkey ( %~key, %首key )
- `prev$l
- ( `~key$, `値$ ) ~GT~cmpkey ( %~key, %首key )
-
-
- ~IF[ %方向 ~IN { `nextunique$l, `prevunique$l } ] ⇒ %~record~list を成す ~EACH( ~keyが互いに`等しい$一群の~record ) に対し ⇒ それらのうち,最初のもの以外の~recordすべてを %~record~list から除去する 【!Iterating with "prevunique" visits the same records that "nextunique" visits, but in reverse order.】
- ~IF[ %~record~list を成す~recordの個数 ~GTE %count ] ⇒ ~RET ε
-
~RET %方向 に応じて,次に与える~record:
- `next$l
- `nextunique$l
- %~record~list 内の最初から %count 個目の~record
- `prev$l
- `prevunique$l
- %~record~list 内の最後から %count 個目の~record
While count is greater than 0:
-
Switch on direction:
- "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 primaryKey is defined, the record’s key is equal to key and the record’s value is greater than or equal to primaryKey, or the record’s key is greater than 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.
- The record’s key is in range.
- "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.
- The record’s key is in range.
- "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 primaryKey is defined, the record’s key is equal to key and the record’s value is less than or equal to primaryKey, or the record’s key is less than 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.
- The record’s key is in range.
- "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.
- 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.
NOTE: Iterating with "prevunique" visits the same records that "nextunique" visits, but in reverse order.
-
↓↓ If found record is not defined, then:
- Set cursor’s key to undefined.
- If source is an index, set cursor’s object store position to undefined.
- If cursor’s key only flag is false, set cursor’s value to undefined.
- Return null.
- Let position be found record’s key.
- If source is an index, let object store position be found record’s value.
- Decrease count by 1.
-
~IF[ %~record ~EQ ε ]:
- %~cursor の`~key$Cs ~SET ε
- ~IF[ %~source は`索引$である ] ⇒ %~cursor の`保管庫~位置$Cs ~SET ε
- ~IF[ %~cursor の`~keyのみか$Cs ~EQ ~F ] ⇒ %~cursor の`値$Cs ~SET ε
- ~RET ~NULL
- %~cursor の`位置$Cs ~SET %~record の`~key$ ◎ Set cursor’s position to position.
- ~IF[ %~source は`索引$である ] ⇒ %~cursor の`保管庫~位置$Cs ~SET %~record の`値$ ◎ If source is an index, set cursor’s object store position to object store position.
- %~cursor の`~key$Cs ~SET %~record の`~key$ ◎ Set cursor’s key to found record’s key.
-
~IF[ %~cursor の`~keyのみか$Cs ~EQ ~F ]: ◎ If cursor’s key only flag is false, then:
- ~IF[ %~source は`索引$である ] ⇒ %直列形 ~LET %~record の`参照先~record$の`値$ ◎ Let serialized be found record’s referenced value.
- %~cursor の`値$Cs ~SET ~NOABRUPT `StructuredDeserialize$jA( %直列形, %宛先~realm ) ◎ Set cursor’s value to ! StructuredDeserialize(serialized, targetRealm)
- %~cursor の`値は取得-済みか$Cs ~SET ~T ◎ Set cursor’s got value flag to true.
- ~RET %~cursor ◎ Return cursor.
7. ~ES言語束縛
この節では、 この仕様にて定義された`~key$値を[ ~ES値に変換する/その逆向きに変換する ]方法, および `~key~path$を利用して`~key$を~ES値の[ 中から抽出する/中へ注入する ]方法を定義する。 この節では、 ~ES言語~仕様 `ECMA-262$r の各種 型/~algo を参照し,いくつかの`~algo表記規約@~TC39#sec-algorithm-conventions$†を利用する。 ここで述べない変換の詳細は `WEBIDL$r にて定義される。 ◎ This section defines how key values defined in this specification are converted to and from ECMAScript values, and how they may be extracted from and injected into ECMAScript values using key paths. This section references types and algorithms and uses some algorithm conventions from the ECMAScript Language Specification. [ECMA-262] Conversions not detailed here are defined in [WEBIDL].
【† 概ね、 ~algo内の抽象-演算( `Get^jA() など)の前に現れる記号 ~NOABRUPT, ~ABRUPT を指す。 大雑把に言えば、 ~NOABRUPT は 例外が生じ得ることを表し, ~ABRUPT は 例外は決して生じないことを表す。 ~NOABRUPT, ~ABRUPT とも付与されていない場合、 一般に,明示的な例外の取扱い,または表明( ~Assert )を要する。 】
7.1. 値から~keyを抽出する
`値から~keyを抽出する@ ときは、 所与の ( `値$ %値, `~key~path$ %~key~path ) に対し,[ `~key$/`失敗^i/`妥当でない^i ]を返すか例外を投出する:
- %r ~LET ~ABRUPT `~key~pathを評価する$( %値, %~key~path )
- ~IF[ %r ~EQ `失敗^i ] ⇒ ~RET %r
- ~RET ~ABRUPT `値を~keyに変換する$( %r )
`値から~key集合を抽出する@ ときは、 所与の ( `値$ %値, `~key~path$ %~key~path, 真偽値 %複-~entryか ) に対し,[ `~key$たちが成す集合 / `失敗^i ]を返す — 以下の中で例外が投出される所では、 `失敗^i を返すとする:
- %r ~LET ~ABRUPT `~key~pathを評価する$( %値, %~key~path )
- ~IF[ %r ~EQ `失敗^i ] ⇒ ~RET `失敗^i
- ~IF[ %複-~entryか ~EQ ~T ]~AND[ %r は`~Array~exotic~obj$である ] ⇒ ~RET ~ABRUPT `配列を~key集合に変換する$( %r )
- %~key ~LET ~ABRUPT `値を~keyに変換する$( %r )
- ~IF[ %~key は`~key$でない ] ⇒ ~RET `失敗^i
- ~RET %~key のみからなる集合
【 [ `値から~keyを抽出する$, `値から~key集合を抽出する$ ]は、 原文では一つの~algoとして定義されているが,この訳では 2 つに分離している。 そうした方が、 依存関係の見通しが良くなるので (同時に、 原文による`配列を~key集合に変換する$手続きの一部もこの手続きに移動している)。 原文における `値から~key集合を抽出する$ に該当する部分は,`配列~key$を返しているが、 ここでは,単に~keyたちが成す集合を返すように改めている。 その配列~keyは一時的にしか利用されておらず (また,実際に重複もなく順序も有意でない)、 そうした方が,この手続きを利用している箇所 (`保管庫に~recordを格納する$手続きの中で,索引を拡充するとき) の記述も簡明になるので。 】
`~key~pathを評価する@ ときは、 所与の ( `値$ %値, `~key~path$ %~key~path ) に対し,[ ~ES値/`失敗^i ]を返すか例外を投出する: ◎ To evaluate a key path on a value with value and keyPath, run the following steps. The result of these steps is an ECMAScript value or failure, or the steps may throw an exception.
【 返り値 `失敗^i は、 %値 の中に %~key~path が指す部位が無いことを表す。 】
-
~IF[ %~key~path は文字列たちが成す`~list$である ]: ◎ If keyPath is a list of strings, then:
- %結果 ~LET 式 `[]^jv で作成されるものと同じ,新たな `Array$jT ~obj ◎ Let result be a new Array object created as if by the expression [].
- %i ~LET 0 ◎ Let i be 0.
-
%~key~path を成す ~EACH( %item ) に対し: ◎ For each item of keyPath:
- %~key ~LET ~NOABRUPT `~key~pathを評価する$( %値, %item ) † 【!原文は引数順序が逆】 ◎ Let key be the result of recursively evaluating a key path on a value with item and value. ◎ Assert: key is not an abrupt completion.
- ~IF[ %~key ~EQ `失敗^i ] ⇒ ~RET `失敗^i ◎ If key is failure, abort the overall algorithm and return failure.
- %p ~LET ~NOABRUPT `ToString$jA( %i ) ◎ Let p be ! ToString(i).
- %状態s ~LET `CreateDataProperty$jA( %result, %p, %~key ) ◎ Let status be CreateDataProperty(result, p, key).
- ~Assert: %状態s ~EQ ~T ◎ Assert: status is true.
- %i ~INCBY 1 ◎ Increase i by 1.
- ~RET %結果 ◎ Return result.
注記(†): これは、 一階層のみ “再帰する” — `~key~path$ 連列は入子にできないので。 ◎ NOTE: This will only ever "recurse" one level since key path sequences can’t ever be nested.
- ~IF[ %~key~path ~EQ 空~文字列 ] ⇒ ~RET %値 【! この段は不要 】 ◎ If keyPath is the empty string, return value and skip the remaining steps.
- %識別子~list ~LET `区切子で厳密に分割する$( %~key~path, `002E^U (`.^l) ) ◎ Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).
-
%識別子~list を成す ~EACH( %識別子 ) に対し ◎ For each identifier of identifiers, jump to the appropriate step below:
-
~IF[ 下の表t内に ( %値 が満たす条件, %識別子 ) に該当する行は在る ] ⇒ %値 ~LET 同じ行の “結果” の列に与える値
%値 が満たす条件 %識別子 結果 `Type$jA( %値 ) ~EQ `String$jT `length^l %値 の`長さ$str【!the number of elements in】に等しい `Number$jT 値 `Array$jT である `length^l ~NOABRUPT `ToLength$jA( ~NOABRUPT `Get$jA( %値, `length^l ) ) `Blob$I である `size^l %値 の `size$mF に等しい `Number$jT 値 `Blob$I である `type^l %値 の `type$mF に等しい `String$jT 値 `File$I である `name^l %値 の `name$mF に等しい `String$jT 値 `File$I である `lastModified^l %値 の `lastModified$mF に等しい `Number$jT 値 【 `File^I であるならば `Blob^I でもあることに注意。 】
◎ If Type(value) is String, and identifier is "length" • Let value be a Number equal to the number of elements in value. ◎ If value is an Array and identifier is "length" • Let value be ! ToLength(! Get(value, "length")). ◎ If value is a Blob and identifier is "size" • Let value be a Number equal to value’s size. ◎ If value is a Blob and identifier is "type" • Let value be a String equal to value’s type. ◎ If value is a File and identifier is "name" • Let value be a String equal to value’s name. ◎ If value is a File and identifier is "lastModified" • Let value be a Number equal to value’s lastModified. -
~ELSE: ◎ Otherwise
- ~IF[ `Type$jA( %値 ) ~NEQ `Object$jT ] ⇒ ~RET `失敗^i ◎ If Type(value) is not Object, return failure.
- %hop ~LET ~NOABRUPT `HasOwnProperty$jA( %値, %識別子 ) ◎ Let hop be ! HasOwnProperty(value, identifier).
- ~IF[ %hop ~EQ `false^jv ] ⇒ ~RET `失敗^i ◎ If hop is false, return failure.
- %値 ~LET ~NOABRUPT `Get$jA( %値, %識別子 ) ◎ Let value be ! Get(value, identifier).
- ~IF[ %値 ~EQ `undefined^jv ] ⇒ ~RET `失敗^i ◎ If value is undefined, return failure.
-
- ~Assert: %値 は`中途完了$でない ◎ Assert: value is not an abrupt completion.
- ~RET %値 ◎ Return value.
注記: この~algoが適用される値は, `StructuredDeserialize$jA からの出力であり, “自前の” ~propのみに~accessするので、 上の手続きにおける ~Assert は満たされる。 ◎ NOTE: Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize and only access "own" properties.
7.2. ~keyを値の中へ注入する
注記: この節で利用される`~key~path$は、 常に文字列であり,決して連列( `~SeqDS$ )にはならなない — `~key生成器$を有する, かつ`~key~path$Osは連列にされた`保管庫$は作成し得ないので。 ◎ NOTE: The key paths used in this section are always strings and never sequences, since it is not possible to create a object store which has a key generator and also has a key path that is a sequence.
`~keyを値の中へ注入できるか検査する@ ときは、 所与の ( %値, %~key~path ) に対し,真偽値を返す: ◎ To check that a key could be injected into a value with value and a keyPath, run the following steps. The result of these steps is either true or false.
- %識別子~list ~LET `区切子で厳密に分割する$( %~key~path, `002E^U (`.^l) ) ◎ Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).
- ~Assert: %識別子~list は空でない ◎ Assert: identifiers is not empty.
- %識別子~list から最後の`~item$を`除去する$ ◎ Remove the last item of identifiers.
-
%識別子~list を成す ~EACH( %識別子 ) に対し: ◎ For each remaining identifier of identifiers, if any:
- ~IF[ %値 は[ `Object$jT, `Array$jT ]のいずれでもない ] ⇒ ~RET ~F ◎ If value is not an Object or an Array, return false.
- %hop ~LET ~NOABRUPT `HasOwnProperty$jA( %値, %識別子 ) ◎ Let hop be ! HasOwnProperty(value, identifier).
- ~IF[ %hop ~EQ `false^jv ] ⇒ ~RET ~T ◎ If hop is false, return true.
- %値 ~LET ~NOABRUPT `Get$jA( %値, %識別子 ) ◎ Let value be ! Get(value, identifier).
- ~RET ~IS[ %値 は[ `Object$jT / `Array$jT ]である ] ◎ Return true if value is an Object or an Array, or false otherwise.
注記: この~algoが適用される値は, `StructuredDeserialize$jA からの出力なので、 上の手続きにおける ~Assert は満たされる。 ◎ NOTE: Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize.
`~keyを値の中へ注入する@ ときは、 所与の ( `値$ %値, `~key$ %~key, `~key~path$Os %~key~path ) に対し,次を走らす: ◎ To inject a key into a value using a key path with value, a key and a keyPath, run these steps:
- %識別子~list ~LET `区切子で厳密に分割する$( %~key~path, `002E^U (`.^l) ) ◎ Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).
- ~Assert: %識別子~list は空でない ◎ Assert: identifiers is not empty.
- %最後の識別子 ~LET %識別子~list の最後の`~item$ ◎ Let last be the last item of identifiers\
- %識別子~list から最後の`~item$を`除去する$ ◎ and remove it from the list.
-
%識別子~list を成す ~EACH( %識別子 ) に対し: ◎ For each remaining identifier of identifiers:
- ~Assert %値 は[ `Object$jT, `Array$jT ]のいずれかである ◎ Assert: value is an Object or an Array.
- %hop ~LET ~NOABRUPT `HasOwnProperty$jA( %値, %識別子 ) ◎ Let hop be ! HasOwnProperty(value, identifier).
-
~IF[ %hop ~EQ `false^jv ]: ◎ If hop is false, then:
- %o ~LET 式 `({})^jv で作成されるものと同じ,新たな `Object$jT ◎ Let o be a new Object created as if by the expression ({}).
- %状態s ~LET `CreateDataProperty$jA( %値, %識別子, %o ) ◎ Let status be CreateDataProperty(value, identifier, o).
- ~Assert: %状態s ~EQ `true^jv ◎ Assert: status is true.
- %値 ~LET ~NOABRUPT `Get$jA( %値, %識別子 ) ◎ Let value be ! Get(value, identifier).
- ~Assert: %値 は `Object$jT または `Array$jT である ◎ Assert: value is an Object or an Array.
- %~key値 ~LET `~keyを値に変換する$( %~key ) ◎ Let keyValue be the result of converting a key to a value with key.
- %状態s ~LET `CreateDataProperty$jA( %値, %最後の識別子, %~key値 ) ◎ Let status be CreateDataProperty(value, last, keyValue).
- ~Assert: %状態s ~EQ `true^jv ◎ Assert: status is true.
注記: この~algoが適用される値は、 `StructuredDeserialize$jA からの出力であり,`~keyを値の中へ注入できるか検査-$した後なので、 上の手続きにおける ~Assert は満たされる。 ◎ NOTE: Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize, and the steps to check that a key could be injected into a value have been run.
7.3. ~keyを値に変換する
`~keyを値に変換する@ ときは、 所与の ( `~key$ %~key ) に対し,~ES値を返す: ◎ To convert a key to a value with key, run the following steps. The steps return an ECMAScript value.
- %値 ~LET %~key の`値$key ◎ Let type be key’s type. ◎ Let value be key’s value.
-
%~key の`型$keyに応じて: ◎ Switch on type:
- `number$i
- ~RET %値 に等しい~ES `Number$jT 値 ◎ Return an ECMAScript Number value equal to value
- `string$i
- ~RET %値 に等しい~ES `String$jT 値 ◎ Return an ECMAScript String value equal to value
- `date$i
-
- %日付 ~LET ~ES `Date$jT 構築子を ( %値 ) を引数に実行した結果 ◎ Let date be the result of executing the ECMAScript Date constructor with the single argument value.
- ~Assert: %日付 は`中途完了$でない ◎ Assert: date is not an abrupt completion.
- ~RET %日付 ◎ Return date.
- `binary$i
-
- %~buffer ~LET ~ES `ArrayBuffer$I 構築子を ( %値 の`長さ$byte ) を引数に実行した結果 ◎ Let len be value’s length. ◎ Let buffer be the result of executing the ECMAScript ArrayBuffer constructor with len.
- ~Assert: %~buffer は`中途完了$でない ◎ Assert: buffer is not an abrupt completion.
- %~buffer の `ArrayBufferData^sl 内部~slotの~entryたち ~SET %値 の~entryたち ◎ Set the entries in buffer’s [[ArrayBufferData]] internal slot to the entries in value.
- ~RET %~buffer ◎ Return buffer.
- `array$i
-
- %配列 ~LET ~ES `Array$jT 構築子を引数なしで実行した結果 ◎ Let array be the result of executing the ECMAScript Array constructor with no arguments.
- ~Assert: %配列 は`中途完了$でない ◎ Assert: array is not an abrupt completion.
-
~EACH( 整数 %~index ~IN { 0 〜 %値 の`~size$ ~MINUS 1 } ) に対し,昇順に: ◎ Let len be value’s size. ◎ Let index be 0. ◎ While index is less than len:
- %~entry ~LET `~keyを値に変換する$( %値[ %~index ] ) ◎ Let entry be the result of converting a key to a value with value[index].
- %状態s ~LET `CreateDataProperty$jA( %配列, %~index, %~entry ) ◎ Let status be CreateDataProperty(array, index, entry).
- ~Assert: %状態s ~EQ ~T ◎ Assert: status is true. ◎ Increase index by 1.
- ~RET %配列 ◎ Return array.
7.4. 値を~keyに変換する
`値を~keyに変換する@ ときは、 所与の ( ~ES値 %入力, `集合$ %seen ) に対し,[ `~key$/`妥当でない^i ]を返すか例外を投出する: ◎ To convert a value to a key with an ECMAScript value input, and an optional set seen, run the following steps. The result of these steps is a key or invalid, or the steps may throw an exception.
【 %seen は[ %入力 が配列であるときに,自身を入子にしているかどうか検査する ]ために利用される。 】
- ~IF[ %seen ~EQ ε ] ⇒ %seen ~SET 新たな`集合$ ◎ If seen was not given, then let seen be a new empty set.
- ~IF[ %入力 ~IN %seen ] ⇒ ~RET `妥当でない^i ◎ If seen contains input, then return invalid.
-
~IF[ `Type$jA( %入力 ) ~EQ `Number$jT ]: ◎ Jump to the appropriate step below: ◎ If Type(input) is Number
- ~IF[ %入力 ~EQ `NaN^jv ] ⇒ ~RET `妥当でない^i ◎ If input is NaN then return invalid.
- ~RET 新たな`~key$ — その ⇒# `型$key ~SET `number$i, `値$key ~SET %入力 ◎ Otherwise, return a new key with type number and value input.
-
~ELIF[ %入力 は `Date$jT ~objである ( `DateValue^sl 内部~slotを有する) ]: ◎ If input is a Date (has a [[DateValue]] internal slot)
- %ms ~LET %入力 の `DateValue^sl 内部~slotの値 ◎ Let ms be the value of input’s [[DateValue]] internal slot.
- ~IF[ %ms ~EQ `NaN^jv ] ⇒ ~RET `妥当でない^i ◎ If ms is NaN then return invalid.
- ~RET 新たな`~key$ — その ⇒# `型$key ~SET `date$i, `値$key ~SET %ms ◎ Otherwise, return a new key with type date and value ms.
-
~ELIF[ `Type$jA( %入力 ) ~EQ `String$jT ] ⇒ ~RET 新たな`~key$ — その ⇒# `型$key ~SET `string$i, `値$key ~SET %入力 ◎ If Type(input) is String • Return a new key with type string and value input.
-
~ELIF[ %入力 は`~buffer~source型$である ] ◎ If input is a buffer source type
- %~byte列 ~LET %入力 に`保持された~byte列の複製を取得する$ — これは、 例外を投出し得る ◎ Let bytes be the result of getting a copy of the bytes held by the buffer source input. Rethrow any exceptions.
- ~RET 新たな`~key$ — その ⇒# `型$key ~SET `binary$i, `値$key ~SET %~byte列 ◎ Return a new key with type binary and value bytes.
-
~ELIF[ %入力 は`~Array~exotic~obj$である ]: ◎ If input is an Array exotic object
- %長さ ~LET ~ABRUPT `ToLength$jA( ~ABRUPT `Get$jA( %入力, `length^l)) ◎ Let len be ? ToLength( ? Get(input, "length")).
- %seen に %入力 を`付加する$ ◎ Append input to seen.
- %~key群 ~LET 新たな`~list$ ◎ Let keys be a new empty list.
-
~EACH( 整数 %~index ~IN { 0 〜 %長さ ~MINUS 1 } ) に対し,昇順に: ◎ Let index be 0. ◎ While index is less than len:
- %hop ~LET ~ABRUPT `HasOwnProperty$jA( %入力, %~index ) ◎ Let hop be ? HasOwnProperty(input, index).
- ~IF[ %hop ~EQ `false^jv ] ⇒ ~RET `妥当でない^i ◎ If hop is false, return invalid.
- %~entry ~LET ~ABRUPT `Get$jA( %入力, %~index ) ◎ Let entry be ? Get(input, index).
- %~key ~LET ~ABRUPT `値を~keyに変換する$( %~entry, %seen ) ◎ Let key be the result of converting a value to a key with arguments entry and seen. ◎ ReturnIfAbrupt(key).
- ~IF[ %~key ~EQ `妥当でない^i ] ⇒ ~RET %~key ◎ If key is invalid abort these steps and return invalid.
- %~key群 に %~key を`付加する$ ◎ Append key to keys. ◎ Increase index by 1.
- ~RET 新たな`~key$ — その ⇒# `型$key ~SET `array$i, `値$key ~SET %~key群 ◎ Return a new array key with value keys.
- ~RET `妥当でない^i ◎ Otherwise • Return invalid.
`配列を~key集合に変換する@ ときは、 所与の ( ~ES `Array$jT 値 %配列 ) に対し,`~key$たちが成す集合を返すか例外を投出する: ◎ To convert a value to a multiEntry key with an ECMAScript value input, run the following steps. The result of these steps is a key or invalid, or the steps may throw an exception. ◎ If input is an Array exotic object, then:
- %長さ ~LET ~ABRUPT `ToLength$jA( ~ABRUPT `Get$jA( %配列, `length^l)) ◎ Let len be ? ToLength( ? Get(input, "length")).
- %seen ~LET %配列 のみからなる新たな`集合$ ◎ Let seen be a new set containing only input.
- %~key群 ~LET 新たな`集合$ ◎ Let keys be a new empty list.
- %~index ~LET 0 ◎ Let index be 0.
-
~WHILE ( %~index ~LT %長さ ) : ◎ While index is less than len:
- %~entry ~LET `Get$jA( %配列, %~index ) ◎ Let entry be Get(input, index).
-
~IF[ %~entry は`中途完了$でない ]: ◎ If entry is not an abrupt completion, then:
- %~key ~LET `値を~keyに変換する$( %~entry, %seen ) ◎ Let key be the result of converting a value to a key with arguments entry and seen.
- ~IF[ %~key は`中途完了$でない ]~AND[ %~key ~NEQ `妥当でない^i ]~AND[ %~key ~NIN~cmpkey %~key群 ] ⇒ %~key を %~key群 に`付加する$set ◎ If key is not invalid or an abrupt completion, and there is no item in keys equal to key, then append key to keys.
- %~index ~INCBY 1 ◎ Increase index by 1.
- ~RET %~key群 ◎ Return a new array key with value set to keys.
この手続きは、 `~key$へ変換できない~memberは無視した上で, 重複するものを除去する。 ◎ Otherwise, return the result of converting a value to a key with argument input. Rethrow any exceptions. ◎ NOTE: These steps are similar to those to convert a value to a key but if the top-level value is an Array then members which can not be converted to keys are ignored, and duplicates are removed.
例えば配列 `[10, 20, null, 30, 20]^jv は、 `~key$たちが成す集合 { 10, 20, 30 } に変換される。 ◎ For example, the value [10, 20, null, 30, 20] is converted to an array key with subkeys 10, 20, 30.
8. ~privacy上の考慮点
◎非規範的8.1. 利用者の追跡
第三者-主体~host (あるいは、 複数の~siteに配布される内容を取得する能力がある任意の~obj) は、 その~client側~db内に格納された一意な識別子を利用して,複数~sessionにわたって利用者を追跡した上で,利用者の活動について~profileを築くこともできる。 利用者の本当の~~識別情報を知る~site (例えば、 認証-済み資格証を要求する電子商取引~site) と組み合わされれば、 どこかの圧政的団体が,純粋に匿名な~webの用法より ずっと正確aに各個人を~targetにすることも可能になる。 ◎ 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.
利用者~追跡の~riskを軽減するために利用できる,いくつもの技法がある: ◎ There are a number of techniques that can be used to mitigate the risk of user tracking:
- 第三者-主体による~storageを阻止する ◎ Blocking third-party storage
- ~UAは、 ~db~objへの~accessを[ 閲覧~文脈の~top-level文書の~domainを出自にする~script ]に制約してもヨイ — 一例として, `iframe^e 内で稼働している他の~domainからの~pageに対しては~APIへの~accessを否認するなど。 ◎ User agents may restrict access to the database objects to scripts originating at the domain of the top-level document of the browsing context, for instance denying access to the API for pages from other domains running in iframes.
- 格納された~dataを失効させる ◎ Expiring stored data
-
~UAは、 格納されている~dataを、 一定期間~後に自動的に削除してもヨイ。 ◎ User agents may automatically delete stored data after a period of time.
これは、 ~siteが利用者を追跡する能を制約し得る — ~siteは、 ~site自身が利用者を認証する (例:購入や~serviceへのログイン時など) 以外にも,利用者を複数~sessionにわたって追跡できなくする。 ◎ 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 she authenticates with the site itself (e.g. by making a purchase or logging in to a service).
しかしながら一方で、 利用者の~dataも~riskに晒す。 ◎ However, this also puts the user’s data at risk.
- 持続的な~storageを~cookieと同様に扱う ◎ Treating persistent storage as cookies
-
~UAは、 ~db特能を ~HTTP~session~cookie `COOKIES$r に強く結付けるような仕方で利用者に呈示するべきである。 ◎ User agents should present the database feature to the user in a way that associates them strongly with HTTP session cookies. [COOKIES]
これは、 利用者が そのような~storageを~~健全な疑いで見ることを促すであろう。 ◎ This might encourage users to view such storage with healthy suspicion.
- ~dbへ~accessできる~siteを個別に安全listに入れる ◎ Site-specific safe-listing of access to databases
- ~UAは、 ~siteがこの仕様の特能を利用できるようになる前に、 ~dbに~accessする権限付与-を利用者に要求してもヨイ。 ◎ User agents may require the user to authorize access to databases before a site can use the feature.
- 第三者-主体~storageの帰属 ◎ Attribution of third-party storage
-
~UAは、 第三者-主体 `生成元$に属する内容を包含している~siteが,~dataを格納させたときは、 その~siteの`生成元$を記録してもヨイ。 ◎ User agents may record the origins of sites that contained content from third-party origins that caused data to be stored.
その上で、 この情報を[ 持続的な~storage内にある現在の~dataを呈示する ]ために利用するならば、 利用者は,その情報を吟味した上で 持続的な~storageからどの部分を取り除くか裁定を下せるようになる。 ~阻止list ( “この~dataを削除して,この~domainにこれ以上~dataを格納させない” ) と組合わすことで、 利用者は,持続的な~storageの利用を自身が信用する~siteのみに制約できるようになる。 ◎ 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 blocklist ("delete this data and prevent this domain from ever storing data again"), the user can restrict the use of persistent storage to sites that she trusts.
- 共有d阻止list ◎ Shared blocklists
-
~UAは、 利用者たちが,持続的な~storage~domainの~阻止listを共有できるようにしてもヨイ。 ◎ User agents may allow users to share their persistent storage domain blocklists.
これは、 ~communityが~~協同して自らの~privacyを保護できるようにする。 ◎ This would allow communities to act together to protect their privacy.
これらの提言は、 この~APIによる,利用者を追跡するための自明な利用については防止するが、 すべてを阻止できるわけではない。 単独の~domainの中では、 ~siteは,~sessionの間 利用者を追跡し続けて、 その情報すべてを[ ~siteが得した識別情報 (名前, クレジットカード番号, 住所など) ]と一緒に第三者-主体に渡すこともできる。 それでも、 第三者-主体が複数の~siteと協力して,そのような情報を得した場合、 ~profileを作成し得る。 ◎ 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.
しかしながら,利用者~追跡は、 ~UAからの協力が一切なくても,ある~~範囲までアリになる — 一例として,~URL内に~session識別子を利用するなど。 この技法は、 差し障りない目的で すでに共通的に利用されているが、 利用者~追跡にも容易に(遡及的にすら)転用できる。 しかる後,この情報は、 他~siteと共有され得る — 訪問者の IP ~addressその他の,利用者に特有な~data (例: user-agent ~headerや環境設定) を利用して、 別々な~sessionを首尾一貫した利用者~profileを成すように組合せることにより。 ◎ 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 visitors' IP addresses and other user-specific data (e.g. user-agent headers and configuration settings) to combine separate sessions into coherent user profiles.
8.3. ~dataの敏感~性
~UAは、 持続的に格納された~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.
ゆえに、 ~UAは、 ~dataを削除するときには,下層の~storageからも即座に削除されることを確保するべきである。 ◎ To this end, user agents should ensure that when deleting data, it is promptly deleted from the underlying storage.
9. ~securityの考慮点
9.1. DNS 偽装~攻撃
DNS 偽装~攻撃の~~可能性があるので、 ある~domainに属すると主張している~hostが本当にその~domainなのかは,保証できない。 これを軽減するため、 ~pageは TLS を利用できる。 TLS を利用している~pageは、 その~domainの~dbに~accessできる~pageは[ TLS を利用していて, 同じ~domainを識別する証明書を有するもの ]に限られることを確保できる。 ◎ 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 TLS. Pages using TLS can be sure that only pages using TLS that have certificates identifying them as being from the same domain can access their databases.
9.2. ~cross-directory攻撃
同じ~host名 — 例えば `geocities.com^c — を共有している作者たちは、 同じ[ ~dbたちが成す集合 ]を共有する。 ◎ Different authors sharing one host name, for example users hosting content on geocities.com, all share one set of databases.
~accessを~URL~pathに基いて制約する特能は無い。 したがって、 共有d~host上の作者には、 これらの特能を利用しないことが推奨される — 他の作者が,その~dataを読取ったり上書できるのは自明なので。 ◎ 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.
注記: ~pathによる制約の特能が可用にされたとしても、 通例の~DOM ~scriptにおける~security~modelの下では,この保護を迂回して任意の~pathから~dataへ~accessすることは自明になる。 ◎ NOTE: 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.
9.3. 実装にあたっての~risk
これらの持続的な~storage用の特能を実装するにあたっては、 2 つの首な~risk — 敵対的~siteが[ 他の~domainから情報を読取る / 情報を書込んで他の~domainに読取らせる ]こと — がある: ◎ 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.
- 第三者-主体~siteが,その~domainから読取られるものと~~想定されていないような~dataを読取れるようになれば、 `情報~漏洩e^emになる。 例えば,ある購買~site~domainの,利用者の “欲しい物リスト” が、 別の~domainにより~targeted広告に利用されたり,あるいは、 文書作成~siteに格納された,利用者が作業中の機密的~文書を,競合企業~siteが覗き見ることも可能になる。 ◎ 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.
- 第三者-主体~siteが,他の~domainの持続的な~storageに~dataを書込めるようになれば、 `情報~偽装^em(なりすまし)になり,同等に危険である。 例えば,敵対的~siteは、 利用者の “欲しい物リスト” に~recordを追加したり、 利用者の~session識別子を既知な ID に設定して,利用者の被害者~siteにおける行動を追跡するためにそれを利用することも可能になる。 ◎ 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.
したがって、 この仕様に述べられる~storage~key~modelに厳密に従うことは、 利用者の~securityにとって重要である。 ◎ Thus, strictly following the storage key model described in this specification is important for user security.
~file~systemにおける持続性のために, ~host名や~db名を利用して~pathを構築する場合、 敵対者が[ `../^l などの相対~pathを利用している他の`~storage~key$ ]から情報に~accessするのを防止するため、 適切に~escapeするモノトスル。 ◎ If host names or database names are used to construct paths for persistence to a file system they must be appropriately escaped to prevent an adversary from accessing information from other storage keys using relative paths such as "../".
9.4. 持続性の~risk
実用的な実装は、 不揮発~storage媒体に~dataを持続化することになる。 ~dataは、 格納-時に直列化され,検索取得-時に逆直列化されることになる — 直列化~形式の詳細は、 ~UAに特有になるが。 ~UAの直列化~形式は、 時を経れば変更される可能性が高い。 例えば、[ 新たな~data型を取扱う/処理能を改善する ]ため,形式は更新されることもある。 したがって、 この仕様の運用上の要件を満たすためには、 実装は,何らかの仕方で旧~直列化~形式を取扱えるモノトスル。 旧~dataの不適正な取扱いは、 基本的な直列化の懸念に加えて,~security上の課題にもなり得る。 直列化された旧~dataは、[ ~versionが新しくされた~UAの下では妥当でない,形式 ]を符号化しかねない。 ◎ Practical implementations will persist data to a non-volatile storage medium. Data will be serialized when stored and deserialized when retrieved, although the details of the serialization format will be user-agent specific. User agents are likely to change their serialization format over time. For example, the format may be updated to handle new data types, or to improve performance. To satisfy the operational requirements of this specification, implementations must therefore handle older serialization formats in some way. Improper handling of older data can result in security issues. In addition to basic serialization concerns, serialized data could encode assumptions which are not valid in newer versions of the user agent.
実用的な例として、 `RegExp$jT 型が挙げられる — その型の~objも `StructuredSerializeForStorage$jA 演算で直列化できる。 代表的な~UAは、 入力~dataが渡され, 結果が返される方法を前提に,正規表現を~machineに~nativeな~~命令に~compileすることになる。 この内部~状態が~dbに格納された~dataの一部として直列化されていた場合、 内部~表現が後で逆直列化されるときに様々な問題が生じることもある。 例えば、 ~dataが~codeの中へ渡される手段は変更されるかもしれない。 ~compiler出力における~security~bugは,~UAの更新~時に識別され修正できようが、 直列化された内部~状態は残り続ける。 ◎ A practical example of this is the RegExp type. The StructuredSerializeForStorage operation allows serializing RegExp objects. A typical user agent will compile a regular expression into native machine instructions, with assumptions about how the input data is passed and results returned. If this internal state was serialized as part of the data stored to the database, various problems could arise when the internal representation was later deserialized. For example, the means by which data was passed into the code could have changed. Security bugs in the compiler output could have been identified and fixed in updates to the user agent, but remain in the serialized internal state.
~UAは、 旧~dataを適切に識別して取扱えるモノトスル。 ~approachの一例としては、 直列化~形式~内に~version識別子を含ませておき,旧~dataに遭遇したときは,~scriptから可視な状態から内部~状態を構築し直すことが挙げられる。 ◎ User agents must identify and handle older data appropriately. One approach is to include version identifiers in the serialization format, and to reconstruct any internal state from script-visible state when older data is encountered.
10. ~accessibilityの考慮点
◎非規範的この仕様が述べる~APIに対する~accessibilityの考慮点は、 以下のように制限される: ◎ The API described by this specification has limited accesibility considerations:
- 内容の視覚的な具現化/色に対する制御は、 供さない。 ◎ It does not provide for visual rendering of content, or control over color.
- 利用者~入力を受容する特能は、 供さない。 ◎ It does not provide features to accept user input.
- 利用者とヤリトリする特能は、 供さない。 ◎ It does not provide user interaction features.
- 文書の意味論は定義しない。 ◎ It does not define document semantics.
- 時間に基づく視覚-~mediaは、 供さない。 ◎ It does not provide time-based visual media.
- 時間~制限sは許容しない。 ◎ It does not allow time limits.
- 末端利用者~向け内容は、 直に供さない — ~textな形でも,~graphicな形など他の形でも。 ◎ It does not directly provide content for end-users, either in textual, graphical or other or non-textual form.
- 伝送~protocolは定義しない。 ◎ It does not define a transmission protocol.
この~APIは、 有構造~内容の~storageを許容する。 ~textな内容は文字列として格納できる。 この~APIには、 画像や音声などの他の代替な内容を[ `Blob$I / `File$I / `ImageData$I ]~objとして格納する開発者~向け~supportは存在する。 この~APIを利用して動的な内容~appを制作している開発者は、 当の内容は様々な技術や必要性により利用者から~access可能になることを確保するベキである。 ◎ The API does allow storage of structured content. Textual content can be stored as strings. Support exists in the API for developers to store alternative non-textual content such as images or audio as Blob, File, or ImageData objects. Developers producing dynamic content applications using the API should ensure that the content is accessible to users with a variety of technologies and needs.
この~API自身は,国際-化に特有な仕組みは定義しないが、 有構造~内容の~storageは,[ 異なる~recordや構造を利用して,~recordの中に各 言語~代替を保持することで、 国際-化された内容を格納する ]ことも開発者に許容する。 ◎ While the API itself does not define a specific mechanism for it, storage of structured content also allows developers to store internationalized content, using different records or structure within records to hold language alternatives.
この~APIは、 この~APIとのヤリトリを可能化する~UIを どう生成するかは定義しないし,それを~UAに要求することもない。 ~UAは、 任意選択で,この~APIを~supportする~UI要素を供してもヨイ。 例:[ 追加的な~storage~quotaが要求されるとき,利用者に~promptする / 特定0の~web~siteが利用している~storageを観測する機能性 / ~recordを[ 検分する/改変する/削除する ]など,~APIの~storageに特有な~tool ]。 そのような~UI要素は、 ~accessibility~toolを念頭に設計するモノトスル。 例えば,利用される~storage~quotaの~~一部分を~graphicな形で呈示している~UIは、 ~screen-readerなどの~toolにも同じ~dataを供するモノトスル。 ◎ The API does not define or require any a user agent to generate a user interface to enable interaction with the API. User agents may optionally provide user interface elements to support the API. Examples include prompts to users when additional storage quota is required, functionality to observe storage used by particular web sites, or tools specific to the API’s storage such as inspecting, modifying, or deleting records. Any such user interface elements must be designed with accessibility tools in mind. For example, a user interface presenting the fraction of storage quota used in graphical form must also provide the same data to tools such as screen readers.
11. 改訂~履歴
◎非規範的以下は、 この仕様の最後の公表版からの変更点の要約である。 `完全な改訂~履歴@https://github.com/w3c/IndexedDB/$ / `第 1 版の改訂~履歴@~TR/IndexedDB/#revision-history$ / `第 2 版の改訂~履歴@~TR/IndexedDB-2/#revision-history$ ◎ The following is an informative summary of the changes since the last publication of this specification. A complete revision history can be found here. For the revision history of the first edition, see that document’s Revision History. For the revision history of the second edition, see that document’s Revision History.
- 他の仕様との統合~用に、 `索引付き~db~txを片付ける$~algoは値を返すようにした。 (`pull#232@https://github.com/w3c/IndexedDB/pull/232$) ◎ The cleanup Indexed Database transactions algorithm now returns a value for integration with other specs. (PR #232)
- `WindowOrWorkerGlobalScope$I は今や~mixinになったので、 部分的~interface定義を更新した。 (`pull#238@https://github.com/w3c/IndexedDB/pull/238$) ◎ Updated partial interface definition since WindowOrWorkerGlobalScope is now a mixin (PR #238).
- `IDBFactory!I に `databases()$m ~methodを追加した。 ( `31$issue ) ◎ Added databases() method. (Issue #31)
- `IDBTransaction!I に `commit()$m ~methodを追加した。 ( `234$issue ) ◎ Added commit() method. (Issue #234)
- `IDBCursor!I に `request$m 属性を追加した。 ( `255$issue ) ◎ Added request attribute. (Issue #255)
- `File$I ~objから標準でない `lastModifiedDate^m ~propの取扱いを除去した。 ( `215$issue ) ◎ Removed handling for nonstandard lastModifiedDate property of File objects. (Issue #215)
- `includes()^m ~methodの識別子に対する~escapeを除去した。 ( `294$issue ) ◎ Remove escaping includes() method. (Issue #294)
- `配列~key$を`~Array~exotic~obj$に制約した (すなわち、 `Proxy^jT ~objを許容しないようにした)。 ( `309$issue ) ◎ Restrict array keys to Array exotic objects (i.e. disallow proxies). (Issue #309)
- ~clone演算の間は、 ~txは一時的に `非作動中$i になるようにした。 ◎ Transactions are now temporarily made inactive during clone operations.
- `durability$mb ~optionと `durability^m 属性を追加した。 ( `50$issue ) ◎ Added durability option and durability attribute. (Issue #50)
- `§ ~txの~schedule法@#transaction-scheduling$をもっと精確に指定した。 `視野が重合して$いる`~readonly~tx$が生きている【!running】間は、 `~readwrite~tx$は開始できないようにした。 ( `253$issue ) ◎ Specified § 2.7.2 Transaction scheduling more precisely and disallow starting read/write transactions while read-only transactions with overlapping scope are running. (Issue #253)
- `§ ~accessibilityの考慮点@#accessibility$を追加した。 ( `327$issue ) ◎ Added Accessibility considerations section. (Issue #327)
- `infra$r の~list~sort法の定義を利用するようにした。 ( `346$issue ) ◎ Used [infra]'s list sorting definition. (Issue #346)
- “`running^en” を一義化するため、 【 “`running^en ~tx” に代えて】 `生きて$いる~tx用の定義を追加して, “昇格~txを `run^en する” を`~dbを昇格する$に改称した。 ( `408$issue ) ◎ Added a definition for live transactions, and renamed "run an upgrade transaction" to upgrade a database, to disambiguate "running". (Issue #408)
- `保管庫から検索取得する演算@#_retrieval-operations$において, 下層~storageから値を読取るときの失敗~用の例外~型を指定した。 ( `423$issue ) ◎ Specified the DOMException type for failures when reading a value from the underlying storage in § 6.2 Object store retrieval operations. (Issue #423)
12. 謝辞
◎非規範的この仕様の第1版の元々の作者である `Nikunj Mehta^en 氏に特に感謝する。 次の方々,並びに第1版の他の編集者たちにも。
Special thanks to Nikunj Mehta, the original author of the first edition, and Jonas Sicking, Eliot Graff, Andrei Popescu, and Jeremy Orlow, additional editors of the first edition.
この仕様の設計に極めて影響力があった `Garret Swart^en 氏に。 ◎ Garret Swart was extremely influential in the design of this specification.
この文書の作成-時に利用した 仕様~著作~tool `Bikeshed^en を作成-/保守され,一般的な著作~法を~~助言された `Tab Atkins, Jr.^en 氏に。 ◎ Thanks to Tab Atkins, Jr. for creating and maintaining Bikeshed, the specification authoring tool used to create this document, and for his general authoring advice.
~feedbackと提言を寄せられ,この仕様を向上させた,次の方々に特別な謝意を:
Special thanks to Nikunj Mehta, Adam Klein, Addison Phillips, Adrienne Walker, Alec Flett, Andrea Marchesini, Andreas Butler, Andrew Sutherland, Anne van Kesteren, Anthony Ramine, Ari Chivukula, Arun Ranganathan, Ben Dilts, Ben Turner, Bevis Tseng, Boris Zbarsky, Brett Zamir, Chris Anderson, Dana Florescu, Danillo Paiva, David Grogan, Domenic Denicola, Dominique Hazael-Massieux, Evan Stade, Glenn Maynard, Hans Wennborg, Isiah Meadows, Israel Hilerio, Jake Archibald, Jake Drew, Jerome Hode, Josh Matthews, João Eiras, Kagami Sascha Rosylight, Kang-Hao Lu, Kris Zyp, Kristof Degrave, Kyaw Tun, Kyle Huey, Laxminarayan G Kamath A, Maciej Stachowiak, Marcos Cáceres, Margo Seltzer, Marijn Kruisselbrink, Ms2ger, Odin Omdal, Olli Pettay, Pablo Castro, Philip Jägenstedt, Shawn Wilsher, Simon Pieters, Tobie Langel, Victor Costan, Xiaoqian Wu, Yannic Bonenberger, Yaron Tausky, Yonathan Randolph, and Zhiqiang Zhang, all of whose feedback and suggestions have led to improvements to this specification.