これは Indexed Database API の第三版です。 第一版、 単に「Indexed Database API」と題され、 2015年1月8日にW3C勧告となりました。 第二版、 「Indexed Database API 2.0」と題され、 2018年1月30日にW3C勧告となりました。
Indexed Database API 3.0はIndexed Database API 2.0を置き換えることを目的としています。
1. はじめに
ユーザーエージェントは、Webアプリケーションのオフラインデータ要件を満たすために、大量のオブジェクトをローカルに保存する必要があります。[WEBSTORAGE] は、キーとその値のペアを保存するのに役立ちます。 しかし、キーの順序付き取得や値の効率的な検索、キーに対する重複値の保存などは提供しません。
この仕様は、高度なキー・値データ管理を行う具体的なAPIを提供します。これは多くの高度なクエリプロセッサの中心的機能です。トランザクション型データベースを使用してキーとそれに対応する値(キーごとに1つ以上)を保存し、キーを決定的な順序で巡回する手段を提供します。これはしばしば、非常に大量のデータレコードの挿入・削除・順序付き巡回に効率的とされる永続的なB-treeデータ構造を用いて実装されます。
"library"
データベースへアクセスするものです。"books"
オブジェクトストアには"isbn"
プロパティを主キーとして書籍レコードが保存されています。
書籍レコードには"title"
プロパティがあります。この例では書籍タイトルが一意であることを求めます。コードは"by_title"
という名前のインデックスをunique
オプション付きで作成し、タイトルで書籍検索を可能にし、重複タイトルの追加を防ぎます。
書籍レコードには"author"
プロパティもあり、こちらは一意である必要はありません。コードは"by_author"
というインデックスも作成し、このプロパティで検索できるようにします。
コードはまずデータベースへの接続を開きます。upgradeneeded
イベントハンドラーで必要に応じてオブジェクトストアとインデックスを作成します。success
イベントハンドラーは後の例で使うために開いた接続を保存します。
const request= indexedDB. open( "library" ); let db; request. onupgradeneeded= function () { // データベースが存在しない場合は、オブジェクトストアとインデックスを作成します。 const db= request. result; const store= db. createObjectStore( "books" , { keyPath: "isbn" }); const titleIndex= store. createIndex( "by_title" , "title" , { unique: true }); const authorIndex= store. createIndex( "by_author" , "author" ); // 初期データで埋める。 store. put({ title: "Quarry Memories" , author: "Fred" , isbn: 123456 }); store. put({ title: "Water Buffaloes" , author: "Fred" , isbn: 234567 }); store. put({ title: "Bedrock Nights" , author: "Barney" , isbn: 345678 }); }; request. onsuccess= function () { db= request. result; };
次の例はトランザクションを使ってデータベースにデータを追加します。
const tx= db. transaction( "books" , "readwrite" ); const store= tx. objectStore( "books" ); store. put({ title: "Quarry Memories" , author: "Fred" , isbn: 123456 }); store. put({ title: "Water Buffaloes" , author: "Fred" , isbn: 234567 }); store. put({ title: "Bedrock Nights" , author: "Barney" , isbn: 345678 }); tx. oncomplete= function () { // すべてのリクエストが成功し、トランザクションがコミットされました。 };
次の例はインデックスを使ってタイトルで単一の書籍を検索します。
const tx= db. transaction( "books" , "readonly" ); const store= tx. objectStore( "books" ); const index= store. index( "by_title" ); const request= index. get( "Bedrock Nights" ); request. onsuccess= function () { const matching= request. result; if ( matching!== undefined ) { // 該当するレコードが見つかりました。 report( matching. isbn, matching. title, matching. author); } else { // 該当するレコードがありませんでした。 report( null ); } };
次の例はインデックスとカーソルを使って著者で全ての書籍を検索します。
const tx= db. transaction( "books" , "readonly" ); const store= tx. objectStore( "books" ); const index= store. index( "by_author" ); const request= index. openCursor( IDBKeyRange. only( "Fred" )); request. onsuccess= function () { const cursor= request. result; if ( cursor) { // 各該当レコードごとに呼び出されます。 report( cursor. value. isbn, cursor. value. title, cursor. value. author); cursor. continue (); } else { // 該当レコードがもうありません。 report( null ); } };
次の例はリクエストが失敗した場合のエラー処理方法の一例です。
const tx= db. transaction( "books" , "readwrite" ); const store= tx. objectStore( "books" ); const request= store. put({ title: "Water Buffaloes" , author: "Slate" , isbn: 987654 }); request. onerror= function ( event) { // "by_title"インデックスの一意制約が失敗しました。 report( request. error); // event.preventDefault()を呼び出せば、トランザクションの自動中止を防げます。 }; tx. onabort= function () { // 失敗したリクエストによりトランザクションは自動で中止されます。 report( tx. error); };
データベース接続は不要になったら閉じることができます。
db. close();
将来、データベースに他のオブジェクトストアやインデックスが追加されているかもしれません。次の例は、古いバージョンからの移行方法の一例です。
const request= indexedDB. open( "library" , 3 ); // バージョン3を要求。 let db; request. onupgradeneeded= function ( event) { const db= request. result; if ( event. oldVersion< 1 ) { // バージョン1はデータベースの最初のバージョン。 const store= db. createObjectStore( "books" , { keyPath: "isbn" }); const titleIndex= store. createIndex( "by_title" , "title" , { unique: true }); const authorIndex= store. createIndex( "by_author" , "author" ); } if ( event. oldVersion< 2 ) { // バージョン2では書籍の年による新しいインデックスが導入されます。 const bookStore= request. transaction. objectStore( "books" ); const yearIndex= bookStore. createIndex( "by_year" , "year" ); } if ( event. oldVersion< 3 ) { // バージョン3では雑誌用の新しいオブジェクトストアと2つのインデックスが追加されます。 const magazines= db. createObjectStore( "magazines" ); const publisherIndex= magazines. createIndex( "by_publisher" , "publisher" ); const frequencyIndex= magazines. createIndex( "by_frequency" , "frequency" ); } }; request. onsuccess= function () { db= request. result; // db.versionは3になります。 };
upgradeneeded
イベント)を行いたい場合、他のクライアントがデータベースの現在のバージョンへの接続をすべて閉じるまで、それを行うことはできません。
新しいクライアントによるアップグレードの妨げを防ぐため、クライアントは
versionchange
イベントを監視できます。これは他のクライアントがデータベースのアップグレードを求めているときに発火します。これに対応して、このクライアントの接続を閉じるような処理を行い、アップグレードを許可します。
このための一つの方法はページをリロードすることです:
db. onversionchange= function () { // まず、未保存データを保存: saveUnsavedData(). then( function () { // ドキュメントがアクティブでない場合は、ユーザー操作なしでページをリロードしてもよいでしょう。 if ( ! document. hasFocus()) { location. reload(); // リロードによりデータベースが閉じられ、新しいJavaScriptおよびデータベース定義も読み込まれます。 } else { // ドキュメントがフォーカスされている場合、ページのリロードは強制的すぎるかもしれません。 // ユーザーに手動でリロードしてもらうよう促すこともできます: displayMessage( "最新バージョンのため、このページをリロードしてください。" ); } }); }; function saveUnsavedData() { // 実装方法はアプリによります。 } function displayMessage() { // ユーザーに非モーダルメッセージを表示します。 }
もう一つの方法は接続のclose()
メソッドを呼び出すことです。ただし、これを行う場合はアプリがその状態を認識している必要があり、以降のデータベースアクセスは失敗します。
db. onversionchange= function () { saveUnsavedData(). then( function () { db. close(); stopUsingTheDatabase(); }); }; function stopUsingTheDatabase() { // アプリがデータベースを使用しない状態にします。 }
新しいクライアント(アップグレードを試みている側)は、他のクライアントがアップグレードを妨げているかをblocked
イベントで検出できます。blocked
イベントは、他のクライアントがversionchange
を受け取った後もデータベースへの接続を保持している場合に発火します。
const request= indexedDB. open( "library" , 4 ); // バージョン4を要求。 let blockedTimeout; request. onblocked= function () { // 他のクライアントが非同期でデータを保存できるよう時間を与えます。 blockedTimeout= setTimeout( function () { displayMessage( "アップグレードがブロックされています - このサイトを表示している他のタブを閉じてください。" ); }, 1000 ); }; request. onupgradeneeded= function ( event) { clearTimeout( blockedTimeout); hideMessage(); // ... }; function hideMessage() { // 以前表示したメッセージを非表示にします。 }
上記のメッセージは、他のクライアントがデータベースから切断しなかった場合のみユーザーに表示されます。理想的にはユーザーがこのメッセージを見ることはありません。
2. 構成要素
name(名前)とは、string
に相当し、DOMString
と同じです。
つまり、任意の長さの16ビットコードユニットの並びであり、空文字列も含みます。name(名前)は常に
16ビットコードユニットの不透明な並びとして比較されます。
実装が任意の文字列をサポートしない記憶装置を使う場合は、エスケープ機構などを使って指定された name を保存可能な文字列へマッピングできます。
ソート済みnameリストを作成するには、 list names を使い、以下の手順を実行します:
-
sorted に names を 昇順でソートしたものを格納します。ソートには code unit less than アルゴリズムを使います。
-
sorted に対応する新しい
DOMStringList
を返します。
詳細
これはsort()
メソッドと一致します。
Array
の
String
に対して、各文字列の16ビットコードユニットを比較し、高速かつ一貫性のある決定的なソート順を生成します。結果のリストは特定のアルファベット順や辞書順とは一致しません。サロゲートペアで表されるコードポイントでは特にそうです。
2.1. データベース
各 storage key は関連する データベース の集合を持ちます。 データベース は0個以上の オブジェクトストア を持ち、 データベースに保存されたデータを保持します。
データベースは、特定の name(名前)を持ち、個々の storage key 内で識別されます。name は name であり、データベースの寿命中は一定です。
データベースは version(バージョン)を持ちます。データベースが初めて作成されたときは、 version は0(ゼロ)です。
注意: 各 データベース は同時に1つのバージョンのみ持ちます。 データベースが複数バージョンで同時に存在することはありません。 バージョンを変更する唯一の方法は、アップグレードトランザクションを使うことです。
データベースは最大1つの関連 upgrade transaction(アップグレードトランザクション)を持ちます。 これは null か アップグレードトランザクション のいずれかで、初期値は null です。
2.1.1. データベース接続
スクリプトは データベース と直接やり取りしません。 スクリプトは connection(接続)を介して間接的にアクセスします。 connection オブジェクトは、対応する データベースのオブジェクト操作に使えます。 また、データベースに対する トランザクションを 取得する唯一の手段です。
データベースを開くことで connection が作成されます。 1つの データベース に複数の connection が同時に存在する場合もあります。
connection は、 storage key のグローバルスコープから開かれた データベースのみアクセスできます。
注意:
これは Document
の
domain
の変更によって影響されません。
connection は version(バージョン)を持ち、 connection の作成時にセットされます。 connection の寿命中は一定ですが、 アップグレードが中止された場合は データベースの前のバージョンに変更されます。connection が閉じられた後は version は変化しません。
各接続は close pending flag(閉じ待ちフラグ)を持ち、初期値は false です。
connection が作成された直後は opened(開かれた)状態です。接続は複数の方法で closed(閉じられた)状態になりえます。 connection が作成された実行コンテキストが 破棄された場合(例えばユーザーがページから離れた場合)、接続は閉じられます。データベース接続を閉じる手順を使って明示的に閉じることもできます。 接続が閉じられると、その close pending flag はまだ設定されていなければ必ず true になります。
connection は、例外的な状況下で ユーザーエージェントによって閉じられる場合があります。例えばファイルシステムへのアクセス喪失、権限変更、storage key のストレージ消去などです。この場合、ユーザーエージェントは データベース接続を閉じる手順を connection に対して forced flag を true にして実行します。
connection は object store set(オブジェクトストア集合)を持ち、 connection の作成時に関連付けられた データベースの オブジェクトストア集合で初期化されます。 アップグレードトランザクションが live(生存中)の場合のみ内容が変化し得ます。
connection の get the parent アルゴリズムは null を返します。
イベント型 versionchange
は、
オープン中の connection に対して、
データベースのアップグレードや削除が試みられた場合に発火します。
connection に
アップグレードや削除を進めるために閉じる機会を与えます。
イベント型 close
は、
connection が異常終了により
閉じられた場合に発火します。
2.2. オブジェクトストア
オブジェクトストアは、 データベース内でデータを保存する主要な保存機構です。
各データベースはオブジェクトストアの集合を持ちます。
オブジェクトストアの集合は変更できますが、
アップグレードトランザクション
(すなわちupgradeneeded
イベントへの応答時)のみ可能です。
新しいデータベースが作成された時点では、オブジェクトストアは含まれていません。
オブジェクトストアは レコードのリストを持ちます。 これはオブジェクトストアに格納されたデータです。 各レコードは キーと値から構成されます。リストはキーに従い 昇順でソートされます。 1つのオブジェクトストア内で同じキーを持つ複数のレコードが存在することはありません。
オブジェクトストアは 名前を持ち、これはnameです。 ある時点で、その名前は所属するデータベース内で一意です。
オブジェクトストアは 任意でキーパスを持ちます。 キーパスがある場合はインラインキーを使うと言い、 ない場合はアウトオブラインキーを使うと言います。
2.2.1. オブジェクトストアハンドル
スクリプトはオブジェクトストアと直接やり取りしません。 代わりに、トランザクション内で間接的に オブジェクトストアハンドル を介してアクセスします。
オブジェクトストアハンドルは 関連するオブジェクトストアと トランザクションを持ちます。 複数のハンドルが異なるトランザクションで 同じオブジェクトストアに紐づくことは可能ですが、 特定のトランザクション内で 1つのオブジェクトストアに 紐づくハンドルは1つだけです。
オブジェクトストアハンドルは インデックス集合を持ちます。 これは、ハンドル作成時に関連するオブジェクトストアを参照する インデックスの集合で初期化されます。 アップグレードトランザクションが liveの場合のみ内容が変化し得ます。
オブジェクトストアハンドルは 名前を持ちます。 これはハンドル作成時に関連するオブジェクトストアの名前で初期化されます。 名前はアップグレードトランザクションが liveの場合のみ変更されることがあります。
2.3. 値
各レコードには値が関連付けられています。ユーザーエージェントは
あらゆるシリアライズ可能オブジェクトをサポートしなければなりません。これには、
String
のプリミティブ値やDate
オブジェクト、Object
やArray
インスタンス、File
オブジェクト、Blob
オブジェクト、ImageData
オブジェクトなどが含まれます。レコードの値は参照ではなく値として保存・取得されるため、値を後から変更してもデータベース内のレコードには影響しません。
レコードの値は、Record型で、 StructuredSerializeForStorage操作の出力です。
2.4. キー
インデックス付きデータベースに保存されたレコードを効率的に取得するため、各レコードはその キーに従って整理されます。
キーには関連する型があり、 以下のいずれかです: number(数値)、 date(日付)、 string(文字列)、 binary(バイナリ)、 array(配列)。
キーはさらに、関連する値を持ちます。
これは以下のいずれかです:
numberまたはdateの場合は
unrestricted double
、
stringの場合はDOMString
、
binaryの場合はバイト列、
arrayの場合は他のキーの
リストです。
ECMAScript [ECMA-262]値は、 値をキーに変換する手順によって キーに変換できます。
-
Number
プリミティブ値(NaNを除く)。Infinityや-Infinityも含みます。 -
Date
オブジェクト(ただし[[DateValue]]内部スロットがNaNの場合は除く)。 -
String
プリミティブ値。 -
ArrayBuffer
オブジェクト(またはUint8Array
などバッファのビュー)。 -
Array
オブジェクト(すべての要素が定義され、各要素が有効なキーであり、直接または間接的に自分自身を含まない場合)。空配列も含みます。配列は他の配列を含むこともできます。
その他のECMAScript値をキーに変換しようとすると失敗します。
配列キーは、キーのうち 型がarrayのものです。 サブキーは 配列キーの 要素です。 配列キーの 値になります。
2つのキーを比較するには、aとbに対し以下の手順を行います:
-
taをaの型とする。
-
tbをbの型とする。
-
もしtaとtbが異なれば、以下を実行:
-
taがarrayなら1を返す。
-
tbがarrayなら-1を返す。
-
taがbinaryなら1を返す。
-
tbがbinaryなら-1を返す。
-
taがstringなら1を返す。
-
tbがstringなら-1を返す。
-
taがdateなら1を返す。
-
Assert:tbはdateである。
-
-1を返す。
-
-
vaをaの値とする。
-
vbをbの値とする。
-
taに応じて分岐:
- number
- date
-
-
もしvaがvbより大きければ1を返す。
-
もしvaがvbより小さければ-1を返す。
-
0を返す。
-
- string
-
-
もしvaがvbよりコードユニット順で小さければ-1を返す。
-
もしvbがvaよりコードユニット順で小さければ1を返す。
-
0を返す。
-
- binary
-
-
もしvaがvbよりバイト順で小さければ-1を返す。
-
もしvbがvaよりバイト順で小さければ1を返す。
-
0を返す。
-
- array
- number
キーaが より大きいのは、 2つのキーを比較するをaとbに対して実行した結果が1の場合です。
キーaが より小さいのは、 2つのキーを比較するをaとbに対して実行した結果が-1の場合です。
キーaが 等しいのは、 2つのキーを比較するをaとbに対して実行した結果が0の場合です。
注意: 上記規則の結果、負の無限大はキーの最小値です。 numberキーはdateキーより小さく、 dateキーはstringキーより小さく、 stringキーはbinaryキーより小さく、 binaryキーはarrayキーより小さいです。 キー値の最大値は存在しません。 これは、いかなる候補となる最大キーの配列に別のキーを続ければさらに大きくなるためです。
注意:
binaryキーの要素は符号なしバイト(0~255)として比較されます。符号付きbyte
(-128~127)とは異なります。
2.5. キーパス
キーパスは、文字列または文字列のリストであり、 キーを 値から抽出する方法を定義します。有効なキーパスは以下のいずれかです:
-
空文字列。
-
識別子(identifier)、これは IdentifierName 生成規則(ECMAScript言語仕様 [ECMA-262])に一致する文字列です。
-
2つ以上の識別子(identifier)がピリオド(U+002E FULL STOP)で区切られた文字列。
-
上記要件を満たす文字列のみを含む空でないリスト。
注意: キーパス内に空白は許可されません。
キーパス値は、 StructuredSerializeForStorageによって 明示的にコピーされたプロパティおよび以下の型固有プロパティからのみアクセスできます:
型 | プロパティ |
---|---|
Blob
| size ,
type
|
File
| name ,
lastModified
|
Array
| length
|
String
| length
|
2.6. インデックス
時には、レコードを オブジェクトストア内で キー以外の方法で取得したい場合があります。 インデックスは、 レコードを オブジェクトストア内で 値のプロパティを使って検索できるようにします。 オブジェクトストアの レコードに対してです。
インデックスは、特殊な永続的なキー・バリュー型ストレージであり、参照先のオブジェクトストアを持ちます。 インデックスには、インデックスに保存されたデータを保持するレコードの一覧があります。 インデックス内のレコードは、参照先のオブジェクトストアでレコードが挿入、更新、または削除されるたびに自動的に追加・更新されます。 同じオブジェクトストアを参照するインデックスが複数存在する場合、オブジェクトストアに変更があると、それら全てのインデックスが更新されます。
インデックスの値は、常にインデックスのレコード内のキーの値であり、インデックスの参照先オブジェクトストアに存在します。 キーは、参照先オブジェクトストアの値からキーパスを使って導出されます。 例えば、インデックスが参照するオブジェクトストアにキーXのレコードがあり、その値がAで、インデックスのキーパスをAに評価すると結果がYになった場合、インデックスにはキーY、値Xのレコードが含まれることになります。
123
、値{ name: "Alice", title: "CEO" }
のレコードがあり、
インデックスのキーパスが
"name
"の場合、インデックスにはキー"Alice
"、値123
のレコードが含まれることになります。
インデックス内のレコードは参照値(referenced value)を持つと言います。 これはインデックスの参照先オブジェクトストアでキーがインデックスのレコード値と等しいレコードの値です。 先の例では、インデックス内でキーY、値Xのレコードの 参照値は Aです。
注意: インデックス内の各レコードは、そのインデックスの参照先オブジェクトストアのレコードを1つだけ参照します。ただし、インデックス内には同じオブジェクトストアのレコードを参照する複数のレコードが存在する場合があります。また、オブジェクトストアのあるレコードを参照するインデックスレコードが1つも存在しない場合もあります。
インデックス内のレコードは、常に レコードのキーでソートされます。ただし、オブジェクトストアとは異なり、インデックスには同じキーを持つ複数のレコードが含まれることがあります。そのようなレコードはさらに、インデックスのレコードの値(つまり参照先オブジェクトストア内のレコードのキー)でソートされます。
インデックスは名前(name)を持ちます。 名前は常にインデックスの参照先オブジェクトストア内で一意です。
インデックスは一意フラグを持ちます。trueの場合、インデックスはインデックス内の レコードが同じキーを持たないように強制します。インデックスの参照オブジェクトストアで レコードの追加や変更が行われ、その新しい値でインデックスのキー・パスを評価した結果がすでにインデックス内に存在する場合、 そのオブジェクトストアへの変更は失敗します。
インデックスはmultiEntryフラグを持ちます。このフラグは、インデックスの キー・パスを評価した結果が 配列キーだった場合のインデックスの挙動に影響します。 multiEntryフラグ がfalseの場合は、キーが配列キーである1つのレコードがインデックスに追加されます。trueの場合は、 サブキーごとに1つずつレコードがインデックスに追加されます。
2.6.1. インデックスハンドル
スクリプトはインデックスと直接やり取りしません。代わりに、 トランザクション内で 間接的にインデックスハンドルを介してアクセスします。
インデックスハンドルは 関連するインデックスと オブジェクトストアハンドルを持ちます。 インデックスハンドルのトランザクションは、関連するオブジェクトストアハンドルのトランザクションです。 複数のハンドルが異なるトランザクションで 同じインデックスに紐づくことは可能ですが、 特定のトランザクション内で 1つのインデックスに 紐づくインデックスハンドルは1つだけです。
インデックスハンドルは 名前を持ちます。 これはハンドル作成時に関連するインデックスの名前で初期化されます。 名前はアップグレードトランザクションが liveの場合のみ変更されることがあります。
2.7. トランザクション
トランザクションは データベース内のデータ操作に使われます。 データベースの読み書きは必ずトランザクション経由で行われます。
トランザクションは アプリケーションやシステムの障害からある程度保護します。 トランザクションは複数のデータレコードを保存したり、 条件付きで一部レコードを変更したりできます。 トランザクションは 原子的かつ永続的なデータアクセス・変更操作の集合です。
すべてのトランザクションは接続経由で作成されます。これはトランザクションの接続です。
トランザクションは スコープを持ちます。これは、トランザクションが操作できる 集合の オブジェクトストアです。
注意: トランザクションのスコープは アップグレードトランザクションでない限り固定です。
2つのトランザクションは、どちらのスコープにも同じオブジェクトストアが含まれる場合 スコープが重複していると言います。
トランザクションは モードを持ち、 そのトランザクションでどの操作ができるかを決めます。 モードは 作成時にセットされ、トランザクションの生存期間中は固定です。 トランザクションのモードは以下のいずれかです:
- "
readonly
" -
このトランザクションはデータの読み取りのみ許可されます。変更はできません。 このタイプのトランザクションは、スコープが重複している(同じオブジェクトストアを使う)場合でも 複数同時に開始できます。 データベースが開かれた後はいつでも作成できます。
- "
readwrite
" -
このトランザクションは既存のオブジェクトストアからデータの読み取り、変更、削除が可能です。 ただし、オブジェクトストアやインデックスの追加・削除はできません。 複数の"
readwrite
" トランザクションは、スコープが重複している場合は同時に開始できません。 これは、トランザクションの途中で互いのデータを変更できてしまうためです。 データベースが開かれた後はいつでも作成できます。 - "
versionchange
" -
このトランザクションは既存のオブジェクトストアのデータの読み取り、変更、削除に加え、 オブジェクトストアやインデックスの新規作成・削除が可能です。 このような操作ができる唯一のタイプです。 このトランザクションは手動では作成できず、
upgradeneeded
イベント発火時に自動で作成されます。
トランザクションは 耐久性ヒントを持つことがあります。 これはコミット時にパフォーマンスか耐久性のどちらを優先するかを示します。 耐久性ヒントは以下のいずれかです:
- "
strict
" -
すべての変更が永続的記憶媒体に正常に書き込まれたことを確認した後のみ、 ユーザーエージェントはトランザクションが正常にコミットされたとみなすことができます。
- "
relaxed
" -
すべての変更がOSに書き込まれた時点で、追加の検証なしで トランザクションが正常にコミットされたとみなすことができます。
- "
default
" -
ユーザーエージェントはストレージバケットに対し デフォルトの耐久性動作を使うべきです。これは特に指定しない場合のデフォルトです。
strict
"
はユーザーエージェントへのヒントとなり、complete
イベント発火前にOSのI/Oバッファをフラッシュするよう促します。
これにより、OSクラッシュや電源喪失があっても変更が永続化される可能性が高まりますが、
バッファフラッシュは時間がかかり、携帯端末ではバッテリー消費も増えます。
Webアプリケーションはキャッシュや頻繁に変わる一時的データには
"relaxed
"
を、データ損失リスク低減がパフォーマンスや電力消費への影響より重要な場合は
"strict
"
を推奨します。
実装はアプリケーションからの耐久性ヒントとユーザー/デバイスへの影響を総合的に考慮すべきです。
トランザクションは 任意でクリーンアップイベントループを持ちます。 これはイベントループです。
トランザクションは エラーを持ち、トランザクションが 中止された場合にセットされます。
abort()
からセットされます。
トランザクションのget the parent アルゴリズムはトランザクションの接続を返します。
読み取り専用トランザクションは
トランザクションで
モードが
"readonly
"です。
読み書きトランザクションは
トランザクションで
モードが
"readwrite
"です。
2.7.1. トランザクションのライフサイクル
トランザクションは 状態を持ち、次のいずれかです:
- アクティブ
-
トランザクションが初めて作成された時や、 トランザクションに関連付けられたリクエストからイベントが発行されている間はこの状態になります。
この状態のときのみ新しいリクエストをトランザクションに対して行えます。
- 非アクティブ
-
トランザクションの作成後に制御がイベントループに戻ったときや、イベントが発行されていないときはこの状態です。
この状態のとき、トランザクションに対してリクエストを行うことはできません。
- コミット中
-
トランザクションに関連するすべてのリクエストが完了すると、 コミットを試みるためこの状態になります。
この状態のとき、トランザクションに対してリクエストを行うことはできません。
- 完了
-
トランザクションがコミットまたは中止された後、この状態になります。
この状態のとき、トランザクションに対してリクエストを行うことはできません。
トランザクションは短命であることが期待されます。これは下記の自動コミット機能によって促進されます。
注意: 著者はトランザクションを生存状態で長時間維持することもできますが、 この利用パターンは推奨されません。ユーザー体験が悪化する可能性があります。
トランザクションの ライフタイムは次の通りです:
-
実装がトランザクションのスコープとモードの制約を (下記参照)満たせる場合、 実装は非同期でトランザクションを開始するデータベースタスクをキューします。
トランザクションが開始されると、 実装はトランザクションに対して行われたリクエストの実行を開始できます。リクエストは トランザクションに対して行われた順に実行し、結果も同じ順で返さなければなりません。 ただし、異なるトランザクション間のリクエスト結果の順序は保証されません。
注意: トランザクションのモードは 異なるトランザクションに対して行われたリクエストがどの順番で実行されても、 データベースに保存される結果に影響しないことを保証します。
-
トランザクションに関連する各リクエストが 処理されると、
success
またはerror
のイベントが発火します。 イベントをディスパッチしている間は トランザクションの状態が アクティブとなり、 追加のリクエストが可能です。イベントのディスパッチが完了すると、 状態は再び非アクティブとなります。 -
トランザクションは完了する前なら、アクティブでなくても、まだ開始されていなくても いつでも中止できます。
abort()
を明示的に呼ぶことで 中止が開始されます。 スクリプトで処理されないリクエストの失敗でも中止が開始されます。トランザクションが中止された場合、実装はそのトランザクション中にデータベースに加えた変更(オブジェクトストア内容の変更、オブジェクトストア・インデックスの追加・削除)をすべて元に戻さなければなりません。
-
実装は、トランザクションに対して行われたすべてのリクエストが完了し、 その返却結果が処理され、新しいリクエストが行われておらず、中止されていない場合、 非アクティブなトランザクションを コミットしようとしなければなりません。
commit()
の明示的呼び出しは、リクエスト結果がスクリプトで処理されるのを待たずに コミットを開始します。コミット時、トランザクションの状態は コミット中になります。 実装はトランザクションで行われたすべての変更をデータベースに原子的に書き込まなければなりません。 すべての変更が書き込まれるか、エラー(例えばディスク書き込みエラー)が発生した場合は変更を一切書き込まず トランザクションの中止手順が実行されます。
実装は、トランザクションがアクティブな間は リクエストを置くことを許可しなければなりません。 これはトランザクションがまだ開始されていなくても同様です。 開始されるまではリクエストは実行されませんが、実装はリクエストとその順序を記録しておく必要があります。
トランザクションは 生存状態は作成時から状態が完了にセットされるまでです。
Indexed Database トランザクションのクリーンアップ方法は以下の通りです。 何らかのトランザクションがクリーンアップされた場合は true、されなければ false を返します。
-
現在のイベントループに クリーンアップイベントループが一致する トランザクションがなければ false を返す。
-
現在のイベントループに クリーンアップイベントループが一致する 各トランザクション transactionに対して:
-
transactionのクリーンアップイベントループをクリアする。
-
true を返す。
注意:
これらの手順は[HTML]によって呼び出されます。
スクリプトからtransaction()
を呼び出して作成されたトランザクションが
呼び出し元タスクの完了後に非アクティブ化されることを保証します。
この手順は各トランザクションにつき最大1回だけ実行されます。
型complete
のイベントは、
正常にコミットされたトランザクションに対して発火します。
型abort
のイベントは、
中止された
トランザクションに対して発火します。
2.7.2. トランザクションのスケジューリング
以下の制約により、トランザクションが開始できるタイミングが決まります:
-
読み取り専用トランザクション tx は、 下記条件を満たす読み書きトランザクションが存在しない場合に 開始できます:
-
読み書きトランザクション tx は、 下記条件を満たすトランザクションが存在しない場合に 開始できます:
実装は追加の制約を課しても構いません。例えば、実装は開始される 非重複スコープの 読み書きトランザクションを並列で処理することを要求されませんし、 開始できるトランザクション数に上限を課しても構いません。
-
読み取り専用トランザクションは、 開始時に いくつでも同時に許可されます。たとえスコープが重複していても構いません。
-
読み取り専用トランザクションが生存している間は、 そのトランザクションで生成したリクエスト経由で返されるデータは一定です。 つまり、同じデータの読み取りリクエストは、データが存在する場合は常に同じ結果となり、存在しない場合は常にデータ無しが示されます。
-
読み書きトランザクションは、 そのトランザクション自身によるオブジェクトストアの変更のみ影響を受けます。 他のトランザクションがその読み書きトランザクションの スコープ内のオブジェクトストア内容を変更することはありません。 また、読み書きトランザクションが正常完了した場合、 そのトランザクションで書き込まれた変更は競合なくオブジェクトストアにコミットできます。
-
複数の読み書きトランザクションが 同じオブジェクトストアにアクセスしようとする場合(すなわちスコープが重複している場合)、 先に作成されたトランザクションが最初にオブジェクトストアへアクセスでき、 そのトランザクションが完了するまで他のトランザクションはアクセスできません。
-
読み書きトランザクションより後に 作成されたトランザクションは、 その読み書きトランザクションが書き込んだ変更を参照できます。たとえば、 読み書きトランザクションAが作成され、後でトランザクションBが作成され、 両者のスコープが重複している場合、 トランザクションBはAがその重複スコープ内のオブジェクトストアに加えた変更を参照できます。 また、BはAが完了するまで重複スコープ内のオブジェクトストアへアクセスできません。
2.7.3. アップグレードトランザクション
アップグレードトランザクションは、
トランザクションで、
モードが
"versionchange
"です。
アップグレードトランザクションは、
接続を
データベースに開いたとき、
現在のバージョンより
大きいバージョンが
指定された場合、データベースのアップグレード手順で
自動作成されます。このトランザクションは、
upgradeneeded
イベントハンドラ内でアクティブになります。
アップグレードトランザクションは排他的です。
データベース接続のオープン手順は、
アップグレードトランザクションが生存しているとき
データベースへの接続が1つだけオープンになるよう保証します。
upgradeneeded
イベントは発火されず、
アップグレードトランザクションは開始されません。
他の接続が同じデータベースに
オープンされている限りです。
これにより、すべての従来のトランザクションが完了していることが保証されます。
アップグレードトランザクションが
生存している間は、
同じデータベースへの追加の接続は遅延されます。
また、同じ接続で
transaction()
を呼んで追加のトランザクションを開始しようとすると例外が発生します。
これにより、他のトランザクションが同時に生存することはなく、
アップグレードトランザクションが
生存している間は、
新たなトランザクションが同じデータベースに対してキューされることもありません。
さらに、アップグレードトランザクションが完了した後は、 データベース内の オブジェクトストアと インデックスの集合は、 以降すべての接続とトランザクションの寿命中一定となります。
2.8. リクエスト
各非同期操作は、データベース上でリクエストを使って行われます。各リクエストは1つの操作を表します。
リクエストには、最初は false に設定されるprocessed flagが存在します。 このフラグは、リクエストに関連する操作が実行されたとき true に設定されます。
リクエストは、processed flagが true の場合、処理済みとみなされます。
リクエストには、最初は false に設定されるdone flagが存在します。 このフラグは、リクエストに関連する操作の結果が利用可能になったとき true に設定されます。
リクエストにはsourceオブジェクトがあります。
リクエストにはresultやerrorが存在しますが、どちらもdone flagが true になるまではアクセスできません。
リクエストには、最初は null に設定されるtransactionがあります。 これは、placedされ、transactionに対して リクエストを非同期で実行する手順が使用された場合に設定されます。
リクエストが作成されると、新しいリクエストが返され、done flagは false
です。リクエストが正常に完了すると、
done flagが true
になり、
resultがそのリクエストの結果に設定され、
success
というタイプのイベントが
リクエストに対して発火されます。
操作の実行中にエラーが発生した場合、リクエストのdone flagが true になり、
リクエストのerrorがエラーに設定され、error
というタイプのイベントがリクエストに対して発火されます。
リクエストのget the parent アルゴリズムはリクエストの transactionを返します。
注記:
リクエストは通常再利用されませんが、例外があります。カーソルを反復する場合、
反復の成功はカーソルを開くために使用された同じリクエストオブジェクトで報告されます。
また、アップグレードトランザクションが必要な場合、
open
requestは、
upgradeneeded
イベントと
open操作自体の最終結果の両方に使用されます。場合によってはリクエストのdone flagが
false になり、再び true になり、resultが変更されたり、
errorが設定されることもあります。
2.8.1. オープンリクエスト
open requestは、
リクエストの特別な種類であり、
コネクションのオープンや
データベースの削除時に使用されます。
success
や
error
イベントに加え、
進行状況を示すために、blocked
およびupgradeneeded
イベントが
open
requestに発火される場合があります。
sourceは open requestの場合、常に null です。
transactionは
open
requestの場合、
upgradeneeded
イベントが発火されない限り
null です。
open requestの get the parentアルゴリズムは null を返します。
2.8.2. 接続キュー
open requestは、 接続キューで処理されます。 キューには、open requestが、 storage keyおよびnameごとに格納されます。キューに追加された 接続キューは順番に処理され、 各リクエストが完了してから次のリクエストが処理されます。 open requestは他の接続によってブロックされる場合があり、 それらの接続が閉じられるまで リクエストが完了せず、後続リクエストの処理も進みません。
注意: 接続キューは、 タスクキュー( イベントループに紐づく)とは異なり、 リクエストは特定の閲覧コンテキスト外で処理されます。完了した open requestへのイベント配送は、 リクエストが行われたコンテキストのタスクキュー およびイベントループ経由で行われます。
2.9. キー範囲
オブジェクトストアや インデックスからレコードを取得する際は、 キーまたはキー範囲を使います。 キー範囲は、 キーとして利用されるデータ型上の連続区間です。
キー範囲には、関連する下限(nullまたは キー)があります。
キー範囲には、関連する上限(nullまたは キー)があります。
キー範囲には、関連する下端開放フラグがあります。 明示されない限りfalseです。
キー範囲には、関連する上端開放フラグがあります。 明示されない限りfalseです。
キー範囲がkeyのみを含む場合、 下限と 上限が 両方ともkeyと等しいです。
keyがキー範囲に含まれる(in a key range)rangeであるとは、 以下の2条件を満たす場合です:
無限キー範囲(unbounded key range)は、 キー範囲で 下限と 上限が 両方ともnullです。すべてのキーは 無限キー範囲に含まれます。
valueと省略可能なnull disallowed flagを使い、 値をキー範囲に変換する手順は以下の通りです:
潜在的に有効なキー範囲とは、 ECMAScript値で、キー範囲に変換可能な型を持つものです。 実際に変換が成功するか(値をキー範囲に変換する手順で例外が発生するか)は問いません。
注意: 例えば、切り離されたBufferSourceは 潜在的に有効なキー範囲ですが、 値をキー範囲に変換する手順で使うと例外が発生します。
値valueが潜在的に有効なキー範囲であるか判定するには、以下の手順を実行します:
getAll()
やgetAllKeys()
メソッドは第一引数に潜在的に有効なキー範囲を使うか判定します。
引数が潜在的に有効なキー範囲なら、
getAll()
やgetAllKeys()
はその引数で値をキー範囲に変換する手順を実行します。
そうでなければIDBGetAllOptions
を第一引数に使います。
getAll()
やgetAllKeys()
は、Date
、
Array
、
ArrayBuffer
を第一引数に与え、値をキーに変換する
手順で"invalid value"となった場合は例外を投げます。例えば、NaNな
Date
を第一引数にしてgetAll()
を呼ぶと、デフォルト値の
IDBGetAllOptions
辞書ではなく例外となります。
2.10. カーソル
カーソルは、 インデックスまたは オブジェクトストアの レコード範囲を特定の方向に反復するために使われます。
カーソルは ソースハンドルを持ち、 これはカーソルを開いたインデックスハンドルまたは オブジェクトストアハンドルです。
カーソルは トランザクションを持ち、 これはカーソルのソースハンドルから得られる トランザクションです。
カーソルは 範囲を持ち、 これはインデックスまたは オブジェクトストアの範囲です。
カーソルは ソースを持ち、 これはカーソルのソースハンドルから得られる インデックスまたは オブジェクトストアです。 カーソルのソースは カーソルが反復しているレコードがどの インデックスまたは オブジェクトストアに紐付くかを示します。 ソースハンドルがインデックスハンドルなら、 ソースは インデックスハンドルが紐付くインデックスです。 そうでなければ、カーソルのソースは オブジェクトストアハンドルが紐付くオブジェクトストアです。
カーソルにはdirection(方向)があり、 イテレーション時に レコードキーの 単調に増加または減少する順序で移動するかどうか、 インデックスをイテレートする際に重複した値をスキップするかどうかを決定します。 カーソルの方向は、カーソルの初期位置が ソースの先頭か末尾かも決定します。 カーソルのdirectionは、 以下のいずれかです。
- "
next
" -
この方向の場合、カーソルはソースの先頭で開かれます。反復時、カーソルは重複も含め キーの単調増加順で全レコードを返します。
- "
nextunique
" -
この方向の場合、カーソルはソースの先頭で開かれます。反復時、同じキーのレコードは返さず、 それ以外はキーの単調増加順で全レコードを返します。重複値があるキーは最初のレコードのみ返されます。 ソースがオブジェクトストアまたは インデックスで uniqueフラグがtrueの場合、 この方向は"
next
"とまったく同じ挙動になります。 - "
prev
" -
この方向の場合、カーソルはソースの末尾で開かれます。反復時、カーソルは重複も含め キーの単調減少順で全レコードを返します。
- "
prevunique
" -
この方向の場合、カーソルはソースの末尾で開かれます。反復時、同じキーのレコードは返さず それ以外はキーの単調減少順で全レコードを返します。重複値があるキーは最初のレコードのみ返されます。 ソースがオブジェクトストアまたは インデックスで uniqueフラグがtrueの場合、 この方向は"
prev
"とまったく同じ挙動になります。
カーソルには、その範囲内で位置があります。 カーソルがイテレートしているレコードの一覧が、カーソルの範囲全体を イテレートし終える前に変更される可能性があります。 これに対応するため、カーソルはindexとしてではなく、直前に返されたレコードのキーとして 位置を保持します。 順方向にイテレートするカーソルの場合、次にカーソルが次のレコードへのイテレーションを要求されたとき、直前に返されたものより キーがより大きい中で 最も小さいキーのレコードを返します。逆方向にイテレートするカーソルの場合は逆で、 直前に返されたものよりキーがより小さい中で 最も大きいキーのレコードを返します。
インデックス反復の場合は、同じキーの複数レコードが値でソートされるため、やや複雑になります。 インデックス反復時にはカーソルは オブジェクトストア位置も持ち、 これはインデックス内で直前に見つかったレコードの 値を示します。 位置と オブジェクトストア位置の両方が 次のレコード検索に使われます。
カーソルは キーと 値を持ち、 これは直前に反復されたレコードの キーと値です。
カーソルは got valueフラグを持ちます。 falseの場合、カーソルは次の値を読み込み中か、範囲の末尾に到達しています。 trueの場合は、カーソルが値を保持中で次に反復できる状態です。
カーソルのソースが オブジェクトストアの場合、 カーソルの有効オブジェクトストアはそのオブジェクトストアであり、 有効キーはカーソルの 位置です。 ソースがインデックスの場合、 有効オブジェクトストアはそのインデックスの参照先オブジェクトストアで、 有効キーはカーソルのオブジェクトストア位置です。
2.11. キー・ジェネレーター
オブジェクトストアが作成される際、 キー・ジェネレーターを使用するよう指定することができます。 キー・ジェネレーターは、オブジェクトストアにレコードが挿入される際に、他に指定されていなければキーを生成するために使われます。
キー・ジェネレーターには現在の数値があります。 現在の数値は常に1以上253(9007199254740992)+ 1以下の正の整数です。 キー・ジェネレーターの現在の数値の初期値は1で、関連するオブジェクトストアが作成されたときに設定されます。 現在の数値はキーが生成されるごとに増加し、明示的なキーの使用によって特定の値に更新される場合もあります。
注: キー・ジェネレーターを使用するそれぞれのオブジェクトストアは、独立したジェネレーターを持ちます。他のオブジェクトストアとやり取りしても、そのオブジェクトストアのキー・ジェネレーターには影響しません。
キー・ジェネレーターの現在の数値を変更することは、データベース操作の一部とみなされます。 つまり、操作が失敗して元に戻された場合、現在の数値も操作開始前の値に戻されます。 これは、キー・ジェネレーターの利用によって現在の数値が1だけ増加する場合や、 レコードが格納される際に指定されたキー値による変更にも適用されます。
同様に、トランザクションが中断された場合、トランザクションのスコープ内の各オブジェクトストアの キー・ジェネレーターの現在の数値もトランザクション開始前の値に戻されます。
キー・ジェネレーターの現在の数値は、データベース操作が元に戻された場合以外は減少しません。
レコードをオブジェクトストアから削除しても、
そのオブジェクトストアのキー・ジェネレーターには影響しません。
たとえばclear()
メソッドで全レコードをクリアしても、オブジェクトストアのキー・ジェネレーターの現在の数値は変わりません。
レコードを格納する際、 格納呼び出しでキーが指定されていなければ、キーが生成されます。
オブジェクトストア storeのためにキーを生成するには、以下の手順を実行します:
-
generatorをstoreのキー・ジェネレーターとする。
-
keyをgeneratorの現在の数値とする。
-
もしkeyが253(9007199254740992)より大きければ、失敗を返す。
-
generatorの現在の数値を1増やす。
-
keyを返す。
レコードを格納する際、 格納呼び出しでキーが指定されている場合、関連するキー・ジェネレーターが更新されることがあります。
オブジェクトストア storeにkeyでキー・ジェネレーターを更新する可能性があるには、次の手順を実行します:
-
keyの型がnumberでなければ、これらの手順を中止する。
-
valueをkeyの値とする。
-
valueをvalueと253(9007199254740992)の最小値にする。
-
valueをvalue以下の最大の整数値にする。
-
generatorをstoreのキー・ジェネレーターとする。
-
もしvalueがgeneratorの現在の数値以上なら、 generatorの現在の数値をvalue + 1に設定する。
指定されたキーのうち型がnumberのものだけが、 キー・ジェネレーターの現在の数値に影響します。 型がdate、array (含まれる他のキーに関係なく)、binary、string(数値解釈できても)が指定されても、 キー・ジェネレーターの現在の数値には影響しません。 型がnumberで、 値が1未満のものは、 常に現在の数値より低いため、影響しません。
キー・ジェネレーターの現在の数値が253(9007199254740992)を超えた場合、
それ以降キー・ジェネレーターで新しいキーを生成しようとすると
"ConstraintError
"
DOMException
となります。
ただし、明示的にキーを指定してレコードを挿入することは可能です。
その場合、キー・ジェネレーターを再び使うには、オブジェクトストアを削除して新しく作成し直すしかありません。
Number
として一意に表現できないためです。
例えば、ECMAScriptでは 9007199254740992 + 1 === 9007199254740992
となります。
通常通りキー・ジェネレーターを使う限り、この制限が問題になることはありません。 仮に1秒間に1000回キー生成をし続けても、28万5千年以上この上限には達しません。
この結果、オブジェクトストアで最初に生成されるキーは常に1(より大きい数値キーが先に挿入された場合を除く)であり、 その後生成されるキーは常にストア内で最も大きい数値キーより大きい正の整数となります。 同じオブジェクトストアで同じキーが二度生成されることは、トランザクションがロールバックされない限りありません。
各オブジェクトストアはそれぞれ独自のキー・ジェネレーターを持ちます:
store1= db. createObjectStore( "store1" , { autoIncrement: true }); store1. put( "a" ); // キー1が割り当てられる store2= db. createObjectStore( "store2" , { autoIncrement: true }); store2. put( "a" ); // キー1が割り当てられる store1. put( "b" ); // キー2が割り当てられる store2. put( "b" ); // キー2が割り当てられる
挿入が制約違反やIOエラー等で失敗した場合、キー・ジェネレーターは更新されません。
transaction. onerror= function ( e) { e. preventDefault() }; store= db. createObjectStore( "store1" , { autoIncrement: true }); index= store. createIndex( "index1" , "ix" , { unique: true }); store. put({ ix: "a" }); // キー1が割り当てられる store. put({ ix: "a" }); // 失敗する store. put({ ix: "b" }); // キー2が割り当てられる
オブジェクトストアからアイテムを削除してもキー・ジェネレーターには影響しません。
clear()
を呼び出しても同様です。
store= db. createObjectStore( "store1" , { autoIncrement: true }); store. put( "a" ); // キー1 store. delete ( 1 ); store. put( "b" ); // キー2 store. clear(); store. put( "c" ); // キー3 store. delete ( IDBKeyRange. lowerBound( 0 )); store. put( "d" ); // キー4
明示的なキーでアイテムを挿入した場合、キーが数値型かつ最後に生成されたキーより高い場合のみ、キー・ジェネレーターに影響します。
store= db. createObjectStore( "store1" , { autoIncrement: true }); store. put( "a" ); // キー1 store. put( "b" , 3 ); // キー3(明示的指定) store. put( "c" ); // キー4 store. put( "d" , - 10 ); // キー-10 store. put( "e" ); // キー5 store. put( "f" , 6.00001 ); // キー6.0001(明示的指定) store. put( "g" ); // キー7 store. put( "f" , 8.9999 ); // キー8.9999(明示的指定) store. put( "g" ); // キー9 store. put( "h" , "foo" ); // キー"foo"(明示的指定) store. put( "i" ); // キー10 store. put( "j" , [ 1000 ]); // キー[1000](明示的指定) store. put( "k" ); // キー11 // これらは、オブジェクトストアがkeyPathを使用し、明示的なキーがオブジェクト内でインライン指定された場合も同様に動作します
トランザクションを中断すると、そのトランザクション内でキー・ジェネレーターが増加した分もロールバックされます。 これは、クラッシュによるロールバックが増加値をコミットできないため、一貫性を保つためです。
db. createObjectStore( "store" , { autoIncrement: true }); trans1= db. transaction([ "store" ], "readwrite" ); store_t1= trans1. objectStore( "store" ); store_t1. put( "a" ); // キー1 store_t1. put( "b" ); // キー2 trans1. abort(); trans2= db. transaction([ "store" ], "readwrite" ); store_t2= trans2. objectStore( "store" ); store_t2. put( "c" ); // キー1 store_t2. put( "d" ); // キー2
以下の例は、インラインキーとキー・ジェネレーターを使って オブジェクトをオブジェクトストアに保存しようとしたときの異なる挙動を示します。
次の条件がすべて満たされる場合:
-
オブジェクトストアにキー・ジェネレーターがある。
-
キー・パスプロパティにインライン値がない。
この場合、キー・ジェネレーターが生成する値がキー値に使われます。
下記例ではオブジェクトストアのキー・パスは"foo.bar
"です。
実際のオブジェクトにはbar
プロパティがなく、{ foo: {} }
です。
このオブジェクトがオブジェクトストアに保存されると、bar
プロパティには次のキーである1が割り当てられます。
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 ); };
次の条件がすべて満たされる場合:
-
オブジェクトストアにキー・ジェネレーターがある。
-
キー・パスプロパティに値がある。
この場合、キー・パスプロパティに関連付けられた値が使用されます。
自動生成されたキーは使われません。
下記例ではキー・パスは"foo.bar
"で、オブジェクトは{ foo: { bar: 10} }
です。
保存時、bar
プロパティは10のままです。
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 ); };
次の例は、指定されたインラインキーがキー・パスで定義されているが、
それに対応するプロパティがない場合の挙動を示します。
この場合、キー・ジェネレーターが生成する値がキー値となり、
必要なプロパティ階層が自動的に作成されます。
下記例ではキー・パスは"foo.bar.baz
"で、
オブジェクトは{ zip: {} }
です。保存時、foo
、bar
、baz
の各プロパティが
階層的に作成され、次のキーである1がfoo.bar.baz
に割り当てられます。
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は: { zip: {}, foo: { bar: { baz: 1 } } } となる console. assert( value. foo. bar. baz=== 1 ); }; };
プリミティブ値にプロパティを保存しようとすると失敗し、エラーが投げられます。
最初の例では、オブジェクトストアのキー・パスは"foo
"です。
実際のオブジェクトはプリミティブ値4
です。
このプリミティブ値にプロパティを定義しようとするため失敗します。
const store= db. createObjectStore( "store" , { keyPath: "foo" , autoIncrement: true }); // キー生成はこのプリミティブ値にkeyPathプロパティを作成しようとする store. put( 4 ); // DataErrorが投げられる
2.12. レコードスナップショット
レコードスナップショットは、オブジェクトストアレコードまたはインデックスレコードからコピーされたキーおよび値を含みます。
レコードスナップショットは、キーを持ち、それはキーです。
レコードスナップショットは、値を持ち、それは値です。
注: インデックスレコードの場合、スナップショットの値はレコードの参照値のコピーです。 オブジェクトストアレコードの場合、スナップショットの値は、レコードの値です。
レコードスナップショットは、さらに主キーを持ち、それはキーです。
注: インデックスレコードの場合、スナップショットの主キーはレコードの値であり、それはインデックスの参照先オブジェクトストア内のレコードのキーです。 オブジェクトストアレコードの場合、スナップショットの主キーとキーは同じキーであり、それはレコードのキーです。
3. 例外
本書で使用される各例外は、DOMException
または DOMException
を継承したインターフェースであり、[WEBIDL]で定義されています。
下の表は、本書で使用されているDOMException
名と、その例外の用途説明を示します。
型 | 説明 |
---|---|
AbortError
| リクエストが中断されました。 |
ConstraintError
| トランザクション内の変更操作が、制約を満たさなかったため失敗しました。 |
DataCloneError
| 格納しようとしたデータが、内部の構造化複製アルゴリズムで複製できませんでした。 |
DataError
| 操作に渡されたデータが要件を満たしていません。 |
InvalidAccessError
| 不正な操作がオブジェクトに対して行われました。 |
InvalidStateError
| オブジェクトが許可されていないタイミングや状態で操作が呼び出された場合、または削除・除去されたソースオブジェクトに対してリクエストが行われた場合。 |
NotFoundError
| 操作が失敗したのは、要求されたデータベースオブジェクトが見つからなかったためです。 |
NotReadableError
| 要求されたデータを含む基盤ストレージが読み取れなかったため、操作が失敗しました。 |
SyntaxError
| keyPath引数が不正なキー・パスを含んでいます。 |
ReadOnlyError
| 変更操作が読み取り専用トランザクションで試行されました。 |
TransactionInactiveError
| 現在アクティブでない、または終了したトランザクションに対してリクエストが行われました。 |
UnknownError
| データベース自体とは無関係、または他のエラーでカバーされない一時的な理由で操作が失敗しました。 |
VersionError
| 既存より低いバージョンでデータベースを開こうとしました。 |
上記のDOMException
以外にも、QuotaExceededError
例外型は、残りのストレージ容量が足りない場合や、ストレージの上限に達し、ユーザーがデータベースへの追加容量付与を拒否した場合に使用されます。
注: 複数のIndexed DB操作が同じ型のエラーをスローする可能性があり、1つの操作でも複数の理由で同じ型のエラーとなる場合があるため、 実装では、開発者がエラー原因を特定できるよう、より具体的なメッセージを提供することが推奨されます。
4. API
APIメソッドは、呼び出し元のスレッドをブロックせずに返ります。すべての非同期操作は、直ちにIDBRequest
インスタンスを返します。このオブジェクトは、操作の結果に関する情報を最初は持っていません。情報が利用可能になると、リクエスト上でイベントが発火し、その情報がIDBRequest
インスタンスのプロパティから取得できるようになります。
これらのタスクのタスクソースは、データベースアクセス・タスクソースです。
データベースタスクをキューするには、タスクをキューするをデータベースアクセス・タスクソース上で実行します。
4.1. IDBRequest
インターフェース
IDBRequest
インターフェースは、データベースや
データベースオブジェクトに対する
非同期リクエストの結果にアクセスする手段を、イベントハンドラーIDL属性 [HTML]を使って提供します。
非同期リクエストを行うすべてのメソッドは、
イベントを通じてリクエスト元のアプリケーションと通信する
IDBRequest
オブジェクトを返します。この設計により、どのデータベースでも
任意の数のリクエストを同時にアクティブにできます。
次の例では、データベースを非同期でオープンしています。 さまざまな状況に応じてイベントハンドラーが登録されています。
const request= indexedDB. open( 'AddressBook' , 15 ); request. onsuccess= function ( evt) {...}; request. onerror= function ( evt) {...};
[Exposed =(Window ,Worker )]interface :
IDBRequest EventTarget {readonly attribute any result ;readonly attribute DOMException ?error ;readonly attribute (IDBObjectStore or IDBIndex or IDBCursor )?source ;readonly attribute IDBTransaction ?transaction ;readonly attribute IDBRequestReadyState readyState ; // Event handlers:attribute EventHandler onsuccess ;attribute EventHandler onerror ; };enum {
IDBRequestReadyState ,
"pending" };
"done"
- request .
result
-
リクエスト完了時、結果を返します。 リクエストが失敗した場合は
undefined
を返します。リクエストがまだ保留中の場合は、 "InvalidStateError
"DOMException
を投げます。 - request .
error
-
リクエスト完了時、エラー(
DOMException
)を返します。 リクエストが成功した場合はnullを返します。リクエストがまだ保留中の場合は "InvalidStateError
"DOMException
を投げます。 - request .
source
-
リクエストが行われた
IDBObjectStore
、IDBIndex
、 またはIDBCursor
を返します。 オープンリクエストの場合はnullを返します。 - request .
transaction
-
リクエストが行われた
IDBTransaction
を返します。 オープンリクエストの場合は、アップグレード・トランザクションが liveな間はそれを返し、それ以外はnullを返します。 - request .
readyState
result
ゲッターの手順は以下の通りです:
-
thisのdoneフラグがfalseなら、throw "
InvalidStateError
"DOMException
。
error
ゲッターの手順は以下の通りです:
-
thisのdoneフラグがfalseなら、throw "
InvalidStateError
"DOMException
。
source
ゲッターの手順は、
thisのsourceを返す。sourceが設定されていない場合はnull。
transaction
ゲッターの手順は、
thisのtransactionを返す。
注記: transaction
ゲッターは、open()
から返される
リクエストなど、特定のリクエストの場合に null を返すことがあります。
readyState
ゲッターの手順は、
thisのdoneフラグがfalseなら
"pending
"を返し、
それ以外の場合は
"done
"を返します。
onsuccess
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはsuccess
です。
onerror
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはerror
イベントです。
IDBDatabase
のメソッドで
オープンリクエストを返すものは、
blocked
およびupgradeneeded
イベントをリッスンできる拡張インターフェースを使用します。
[Exposed =(Window ,Worker )]interface :
IDBOpenDBRequest IDBRequest { // Event handlers:attribute EventHandler onblocked ;attribute EventHandler onupgradeneeded ; };
onblocked
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはblocked
です。
onupgradeneeded
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはupgradeneeded
です。
4.2. イベントインターフェース
この現行標準は、以下のカスタムインターフェースを用いてイベントを発火します:
[Exposed =(Window ,Worker )]interface :
IDBVersionChangeEvent Event {(
constructor DOMString ,
type optional IDBVersionChangeEventInit = {});
eventInitDict readonly attribute unsigned long long oldVersion ;readonly attribute unsigned long long ?newVersion ; };dictionary :
IDBVersionChangeEventInit EventInit {unsigned long long = 0;
oldVersion unsigned long long ?=
newVersion null ; };
oldVersion
ゲッターの手順は、初期化された値を返します。これはデータベースの以前のバージョンを表します。
newVersion
ゲッターの手順は、初期化された値を返します。これはデータベースの新しいバージョンを表しますが、データベースが削除される場合はnullとなります。データベースをアップグレードする手順も参照してください。
イベントは DOM § 2.5 イベントの構築 に従って構築されます。
バージョン変更イベントを発火するには、名前e、target、oldVersion、newVersionを指定して以下の手順を実行します:
-
eventを、イベントの生成の結果として
IDBVersionChangeEvent
を使って作成する。 -
eventの
type
属性をeに設定する。 -
eventの
bubbles
およびcancelable
属性をfalseに設定する。 -
eventの
oldVersion
属性をoldVersionに設定する。 -
eventの
newVersion
属性をnewVersionに設定する。 -
legacyOutputDidListenersThrowFlagをfalseにする。
-
eventをdispatchする。対象はtarget、フラグはlegacyOutputDidListenersThrowFlag。
-
legacyOutputDidListenersThrowFlagを返す。
注: このアルゴリズムの戻り値は常に使われるとは限りません。
4.3. IDBFactory
インターフェース
データベースオブジェクトは、
IDBFactory
インターフェースのメソッドを通じてアクセスされます。このインターフェースを実装するオブジェクトは、
Indexed DB操作をサポートする環境のグローバルスコープに1つ存在します。
partial interface mixin WindowOrWorkerGlobalScope { [SameObject ]readonly attribute IDBFactory indexedDB ; };
indexedDB
属性は、アプリケーションがインデックス付きデータベースの機能にアクセスする仕組みを提供します。
[Exposed =(Window ,Worker )]interface { [
IDBFactory NewObject ]IDBOpenDBRequest open (DOMString ,
name optional [EnforceRange ]unsigned long long ); [
version NewObject ]IDBOpenDBRequest deleteDatabase (DOMString );
name Promise <sequence <IDBDatabaseInfo >>databases ();short cmp (any ,
first any ); };
second dictionary {
IDBDatabaseInfo DOMString ;
name unsigned long long ; };
version
- request = indexedDB .
open
(name) -
指定したnameの接続を現行バージョンで開こうとします。存在しない場合はバージョン1で作成されます。 リクエストが成功すると、requestの
result
は接続となります。 - request = indexedDB .
open
(name, version) -
指定したversionでnameの接続を開こうとします。既存データベースのバージョンが低く、開かれた接続が
versionchange
イベントに応じて閉じない場合、すべて閉じるまでリクエストはブロックされ、その後アップグレードが行われます。バージョンが高い場合はリクエストが失敗します。 リクエストが成功すると、requestのresult
は接続になります。 - request = indexedDB .
deleteDatabase
(name) -
指定したnameのデータベースを削除しようとします。 既存データベースで開かれている 接続が
versionchange
イベントに応じて閉じない場合、すべて閉じるまでリクエストはブロックされます。成功した場合、requestのresult
はnullになります。 - result = await indexedDB .
databases
() -
このプロミスは、ストレージキー内の データベース名とバージョンのスナップショット一覧を返します。
このAPIは、たとえばサイトの以前のバージョンのデータベースをクリーンアップするなど、Webアプリケーションがデータベース利用状況を調べるために設計されています。 結果はスナップショットであり、データ収集やレスポンス配信の順序が、このコンテキストまたは他のコンテキストのデータベース作成・アップグレード・削除リクエストとどのように関連するかについて保証はありません。
open(name, version)
メソッドの手順は以下の通りです:
-
environmentをthisの関連設定オブジェクトとする。
-
storageKeyをストレージキーの取得にenvironmentを渡して得る。 失敗した場合は、throw "
SecurityError
"DOMException
し、処理を中止する。 -
requestを新しいオープンリクエストとする。
-
以下の手順を並列で実行:
-
resultをデータベース接続を開くの結果とする。引数はstorageKey、name、version(省略時はundefined)、request。
-
requestのprocessed flagをtrueにする。
-
データベースタスクをキューして以下を実行:
-
resultがエラーなら:
-
requestのresultをundefinedに設定。
-
requestのerrorをresultに設定。
-
requestのdone flagをtrueに。
-
errorイベントを発火する。requestが対象。
bubbles
とcancelable
属性はtrueで初期化。
-
-
それ以外の場合:
-
requestのresultをresultに設定。
-
requestのdone flagをtrueに。
-
successイベントを発火する。対象はrequest。
注: 上記の手順でアップグレードトランザクションが実行された場合、これらの手順はそのトランザクション終了後に実行されます。別バージョンアップグレードが直後に発生する場合でも、successイベントは先に接続で発火されるため、スクリプトが
versionchange
イベントのリスナーを登録する機会が得られます。なぜsuccessイベントの発火や errorイベントの発火手順を使わないのか?
この時点でリクエストに関連するトランザクションは存在しないため、それらの手順(dispatch前後でトランザクションをactivate/deactivateする)は適用されません。 -
-
-
-
requestに対して新しい
IDBOpenDBRequest
オブジェクトを返す。
deleteDatabase(name)
メソッドの手順は以下の通り:
-
environmentをthisの関連設定オブジェクトとする。
-
storageKeyをストレージキーの取得にenvironmentを渡して得る。 失敗した場合は、throw "
SecurityError
"DOMException
し、処理を中止する。 -
requestを新しいオープンリクエストとする。
-
以下の手順を並列で実行:
-
resultをデータベース削除の結果とする。引数はstorageKey、name、request。
-
requestのprocessed flagをtrueに。
-
データベースタスクをキューして以下を実行:
-
resultがエラーなら、 requestのerrorをresultに設定、 requestのdone flagをtrueに、 errorイベント発火(名前は
error
、対象はrequest)、bubbles
とcancelable
属性はtrueで初期化。 -
それ以外の場合、 requestのresultをundefinedに、 requestのdone flagをtrueに、 バージョン変更イベント発火(名前は
success
、対象はrequest、引数はresultとnull)。なぜsuccessイベントの発火や errorイベントの発火手順を使わないのか?
このリクエストに関連するトランザクションは存在しないため、それらの手順(dispatch前後でトランザクションをactivate/deactivateする)は適用されません。また、この
success
イベントはIDBVersionChangeEvent
であり、oldVersion
とnewVersion
の詳細が含まれます。
-
-
-
requestに対して新しい
IDBOpenDBRequest
オブジェクトを返す。
databases()
メソッドの手順は以下の通り:
-
environmentをthisの関連設定オブジェクトとする。
-
storageKeyをストレージキーの取得にenvironmentを渡して得る。 失敗した場合は
SecurityError
DOMException
でrejectされたプロミスを返す。 -
pを新しいプロミスとする。
-
以下の手順を並列で実行:
-
databasesをstorageKey内の集合からデータベースとして取得する。 何らかの理由で取得できない場合、データベースタスクをキューして、適切なエラー(例:"
UnknownError
"DOMException
)でpをrejectし、処理終了。 -
resultを新しいリストとする。
-
各dbについてdatabasesを繰り返す:
-
データベースタスクをキューして、resolveでpにresultを返す。
-
-
pを返す。
databases()
メソッドはこの版で新規追加です。
Chrome 71、Edge 79、Firefox 126、Safari 14でサポートされています。
🚧
- result = indexedDB .
cmp
(key1, key2) -
2つの値をキーとして比較します。key1がkey2より前なら-1、key2がkey1より前なら1、キーが等しければ0を返します。
どちらかの入力が有効なキーでない場合は、"
DataError
"DOMException
をthrowします。
cmp(first, second)
メソッドの手順:
-
aを値からキーへの変換でfirstを渡して得る。例外は再throw。
-
aが「invalid value」または「invalid type」なら、throw "
DataError
"DOMException
。 -
bを値からキーへの変換でsecondを渡して得る。例外は再throw。
-
bが「invalid value」または「invalid type」なら、throw "
DataError
"DOMException
。 -
2つのキーの比較の結果をaとbで返す。
4.4. IDBDatabase
インターフェース
IDBDatabase
インターフェースは接続をデータベースに表現します。
IDBDatabase
オブジェクトは、関連する接続のclose pending flagがfalseで、イベントリスナーが1つ以上登録されていてそのタイプが
abort
、
error
、
versionchange
のいずれかの場合はガベージコレクトされてはなりません。IDBDatabase
オブジェクトがガベージコレクトされた場合、関連する接続は閉じる必要があります。
[Exposed =(Window ,Worker )]interface :
IDBDatabase EventTarget {readonly attribute DOMString name ;readonly attribute unsigned long long version ;readonly attribute DOMStringList objectStoreNames ; [NewObject ]IDBTransaction transaction ((DOMString or sequence <DOMString >),
storeNames optional IDBTransactionMode = "readonly",
mode optional IDBTransactionOptions = {});
options undefined close (); [NewObject ]IDBObjectStore createObjectStore (DOMString ,
name optional IDBObjectStoreParameters = {});
options undefined deleteObjectStore (DOMString ); // Event handlers:
name attribute EventHandler onabort ;attribute EventHandler onclose ;attribute EventHandler onerror ;attribute EventHandler onversionchange ; };enum {
IDBTransactionDurability ,
"default" ,
"strict" };
"relaxed" dictionary {
IDBTransactionOptions IDBTransactionDurability = "default"; };
durability dictionary { (
IDBObjectStoreParameters DOMString or sequence <DOMString >)?=
keyPath null ;boolean =
autoIncrement false ; };
name
ゲッターの手順は、
thisの関連データベースのnameを返すことです。
注:
name
属性は、
thisのclose pending flagがtrueであってもこの名前を返します。つまり、この属性の値はIDBDatabase
インスタンスのライフタイム中は一定です。
version
ゲッターの手順は、
thisのversionを返すことです。
これはデータベースのversionと同じですか?
接続が開いている限り、これは接続されたデータベースのversionと同じです。しかし接続が閉じると、この属性は後のアップグレードトランザクションによる変更を反映しません。- connection .
objectStoreNames
-
データベース内のオブジェクトストアの名前一覧を返します。
- store = connection .
createObjectStore
(name [, options]) -
指定したnameとoptionsで新しいオブジェクトストアを作成し、新しい
IDBObjectStore
を返します。アップグレードトランザクション外で呼び出すと"
InvalidStateError
"DOMException
をthrowします。 - connection .
deleteObjectStore
(name) -
指定したnameのオブジェクトストアを削除します。
アップグレードトランザクション外で呼び出すと"
InvalidStateError
"DOMException
をthrowします。
objectStoreNames
ゲッターの手順:
-
namesをリストとして、名前をオブジェクトストアごとにthisのobject store setから取得する。
-
namesを使い、ソート済み名前リストの作成の結果(
DOMStringList
)を返す。
これはデータベースのオブジェクトストア名前と同じですか?
接続が開いている限り、これは接続されたデータベースのオブジェクトストア名前に一致します。ただし、接続が閉じると、この属性は後のアップグレードトランザクションの変更を反映しません。createObjectStore(name, options)
メソッドの手順:
-
transactionをdatabaseのアップグレードトランザクション(nullでなければ)とし、nullの場合はthrow "
InvalidStateError
"DOMException
。 -
transactionのstateがactiveでなければ、 throw "
TransactionInactiveError
"DOMException
。 -
keyPathをoptionsの
keyPath
メンバー(undefinedまたはnullでなければ)とし、それ以外はnull。 -
keyPathがnullでなく、有効なkey pathでなければ、throw "
SyntaxError
"DOMException
。 -
databaseにnameのオブジェクトストアが既に存在する場合、throw "
ConstraintError
"DOMException
。 -
autoIncrementをoptionsの
autoIncrement
メンバーとする。 -
autoIncrementがtrueで、keyPathが空文字列または任意のシーケンス(空でも可)の場合、throw "
InvalidAccessError
"DOMException
。 -
storeをdatabase内の新しいオブジェクトストアとし、作成したオブジェクトストアのnameをnameに設定。autoIncrementがtrueなら、作成したオブジェクトストアはキー・ジェネレーターを使用する。keyPathがnullでなければ、作成したオブジェクトストアのkey pathをkeyPathに設定。
-
storeおよびtransactionに関連付けられた新しいオブジェクトストアハンドルを返す。
このメソッドは、指定した名前で接続されたデータベースに新しいオブジェクトストアを作成して返します。このメソッドはアップグレードトランザクション内のみで呼び出す必要があります。
このメソッドは、呼び出したobjectStoreNames
プロパティを同期的に変更します。
一部の実装では、createObjectStore()
メソッドが返った後、オブジェクトストア作成タスクをキューした後に問題が発生する場合があります。例えば、新しく作成されたオブジェクトストアのメタデータをデータベースに非同期で挿入する実装や、クォータの理由でユーザーの許可を求める必要がある場合です。
そのような実装でもIDBObjectStore
オブジェクトを作成して返し、作成が失敗した場合は適切なエラー(例えばクォータ理由の場合はQuotaExceededError
)を使ってトランザクションを中止する必要があります。
deleteObjectStore(name)
メソッドの手順:
-
transactionをdatabaseのアップグレードトランザクション(nullでなければ)とし、nullの場合はthrow "
InvalidStateError
"DOMException
。 -
transactionのstateがactiveでなければ、 throw "
TransactionInactiveError
"DOMException
。 -
databaseにnameのオブジェクトストアがなければ、throw "
NotFoundError
"DOMException
。 -
storeをthisのobject store setから削除。
-
storeとtransactionに関連するオブジェクトストアハンドルがあれば、そのindex setのエントリをすべて削除。
-
storeを破棄。
このメソッドは、指定した名前の接続されたデータベース内のオブジェクトストアを破棄します。このメソッドはアップグレードトランザクション内のみで呼び出す必要があります。
このメソッドは、呼び出したobjectStoreNames
プロパティを同期的に変更します。
- transaction = connection .
transaction
(scope [, mode [, options ] ]) -
指定したscope(単一のオブジェクトストア名または複数名の配列)、mode("
readonly
"または"readwrite
")、および追加options(durability
:"default"、"strict"、"relaxed")で新しいトランザクションを返します。modeのデフォルトは"
readonly
"、durability
のデフォルトは"default
"です。 - connection .
close
()
transaction(storeNames, mode, options)
メソッドの手順:
-
この接続に関連付けられたアップグレードトランザクションがライブなら、throw "
InvalidStateError
"DOMException
。 -
thisのclose pending flagがtrueなら、throw "
InvalidStateError
"DOMException
。 -
scopeを、storeNamesがシーケンスなら一意な文字列の集合、そうでなければstoreNamesのみを含む集合とする。
-
scope内のいずれかの文字列が、接続されたデータベースのオブジェクトストア名でなければ、throw "
NotFoundError
"DOMException
。 -
scopeが空なら、throw "
InvalidAccessError
"DOMException
。 -
transactionを新しく作成したトランザクション(接続、mode、optionsの
durability
メンバー、scope内のオブジェクトストアセット)とする。 -
transactionのcleanup event loopを現在のevent loopに設定。
-
transactionを表す
IDBTransaction
オブジェクトを返す。
durability
オプションはこの版で新規追加です。
Chrome 82、Edge 82、Firefox 126、Safari 15でサポートされています。
🚧
注: 作成されたtransactionはライフタイムのルールに従います。
close()
メソッドの手順:
-
この接続でデータベース接続を閉じるを実行する。
注:
接続は、すべての未完了トランザクションが完了するまで実際には閉じません。close()
を複数回呼んでも効果はありません。
onabort
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはabort
です。
onclose
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはclose
です。
onerror
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはerror
です。
onversionchange
属性は、イベントハンドラーIDL属性であり、
イベントハンドラーイベントタイプはversionchange
です。
4.5. IDBObjectStore
インターフェイス
IDBObjectStore
インターフェイスは、オブジェクトストアハンドルを表します。
[Exposed =(Window ,Worker )]interface {
IDBObjectStore attribute DOMString name ;readonly attribute any keyPath ;readonly attribute DOMStringList indexNames ; [SameObject ]readonly attribute IDBTransaction transaction ;readonly attribute boolean autoIncrement ; [NewObject ]IDBRequest put (any ,
value optional any ); [
key NewObject ]IDBRequest add (any ,
value optional any ); [
key NewObject ]IDBRequest delete (any ); [
query NewObject ]IDBRequest clear (); [NewObject ]IDBRequest get (any ); [
query NewObject ]IDBRequest getKey (any ); [
query NewObject ]IDBRequest getAll (optional any ,
queryOrOptions optional [EnforceRange ]unsigned long ); [
count NewObject ]IDBRequest getAllKeys (optional any ,
queryOrOptions optional [EnforceRange ]unsigned long ); [
count NewObject ]IDBRequest getAllRecords (optional IDBGetAllOptions = {}); [
options NewObject ]IDBRequest count (optional any ); [
query NewObject ]IDBRequest openCursor (optional any ,
query optional IDBCursorDirection = "next"); [
direction NewObject ]IDBRequest openKeyCursor (optional any ,
query optional IDBCursorDirection = "next");
direction IDBIndex index (DOMString ); [
name NewObject ]IDBIndex createIndex (DOMString , (
name DOMString or sequence <DOMString >),
keyPath optional IDBIndexParameters = {});
options undefined deleteIndex (DOMString ); };
name dictionary {
IDBIndexParameters boolean =
unique false ;boolean =
multiEntry false ; };dictionary {
IDBGetAllOptions any =
query null ; [EnforceRange ]unsigned long ;
count IDBCursorDirection = "next"; };
direction
- store .
name
-
ストアの名前を返します。
- store .
name
= newName -
ストアの名前をnewNameに更新します。
アップグレードトランザクション内で呼び出されない場合は、"
InvalidStateError
"DOMException
がスローされます。 - store .
keyPath
-
ストアのキー・パスを返します。存在しない場合はnullです。
- store .
indexNames
-
ストア内のインデックス名のリストを返します。
- store .
transaction
-
関連するトランザクションを返します。
- store .
autoIncrement
-
ストアがキー生成器を持つ場合はtrue、そうでない場合はfalseを返します。
これはオブジェクトストアの名前と同じですか?
トランザクションが終了していない限り、 これは関連するオブジェクトストアの 名前と同じです。しかしトランザクションが 終了した後は、 この属性は後のアップグレードトランザクションによる変更を反映しません。name
のsetter手順:
-
nameを与えられた値とする。
-
storeが削除されていた場合、 throw "
InvalidStateError
"DOMException
。 -
transactionがアップグレードトランザクションでない場合、 throw "
InvalidStateError
"DOMException
。 -
transactionの状態がactiveでない場合、 throw "
TransactionInactiveError
"DOMException
。 -
storeの名前がnameと等しい場合、これらの手順を終了する。
-
storeのデータベース内にnameというオブジェクトストア 名がすでに存在する場合、throw "
ConstraintError
"DOMException
。 -
storeの名前をnameに設定する。
keyPath
のgetter手順は、
thisのオブジェクトストアのキー・パスを返し、存在しない場合はnullを返します。キー・パスは
DOMString
(文字列の場合)または
sequence<
(文字列リストの場合)として変換されます。[WEBIDL]参照。
DOMString
>
NOTE:
返される値は、オブジェクトストア作成時に使用されたインスタンスと同じではありません。
しかし、この属性がオブジェクト(特にArray
)を返す場合、
参照するたびに同じオブジェクトインスタンスが返されます。オブジェクトのプロパティを変更しても
オブジェクトストアには影響しません。
indexNames
のgetter手順:
-
結果(
DOMStringList
)として ソート済みの名前リストを作成し、namesで返す。
これはオブジェクトストアの インデックスの 名前リストと同じですか?
トランザクションが終了していない限り、 これは関連するオブジェクトストアの インデックスの 名前リストと同じです。しかし トランザクションが 終了した後は、 この属性は後のアップグレードトランザクションによる変更を反映しません。transaction
のgetter手順は、
thisのトランザクションを返します。
autoIncrement
のgetter手順は、
thisのオブジェクトストアがキー生成器を持つ場合はtrue、そうでない場合はfalseを返します。
ReadOnlyError
"
DOMException
がスローされ、
トランザクションがactiveでない場合は
"TransactionInactiveError
"
DOMException
がスローされます。
- request = store
.
put
(value [, key])- request = store .
add
(value [, key]) - request = store .
-
valueとkeyでストア内にレコードを追加または更新します。
ストアがインラインキーを使用していてkeyが指定された場合、 "
DataError
"DOMException
がスローされます。put()
を使用した場合、同じキーを持つ既存のレコードは置き換えられます。add()
を使用した場合、同じキーを持つ レコードが既に存在すると requestは失敗し、requestのerror
が"ConstraintError
"DOMException
となります。 - request = store .
delete
(query) -
queryで指定したキーまたはキー範囲に該当する レコードをストアから削除します。
成功した場合、requestの
result
はundefined
です。 - request = store .
clear
() -
ストア内のすべてのレコードを削除します。
成功した場合、requestの
result
はundefined
です。
put(value, key)
メソッドの手順は、
追加または更新を
this、value、key、および no-overwrite flag を false
で実行した結果を返します。
add(value, key)
メソッドの手順は、
追加または更新を
this、value、key、および no-overwrite flag を true
で実行した結果を返します。
追加または更新を handle、value、key、no-overwrite flag で実行するには、次の手順を行います:
-
transaction を handle の トランザクション とする。
-
store を handle の オブジェクトストア とする。
-
store が削除されている場合、 throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
transaction が 読み取り専用トランザクション の場合、 throw "
ReadOnlyError
"DOMException
を投げる。 -
store が インラインキー を使用していて key が指定された場合、 throw "
DataError
"DOMException
を投げる。 -
store が アウトオブラインキー を使用していて キー生成器 を持たず key が指定されていない場合、throw "
DataError
"DOMException
を投げる。 -
key が指定された場合、次を行う:
-
r を 値からキーへの変換を key で実行した結果とする。例外は再スローする。
-
r が "invalid value" または "invalid type" の場合、 throw "
DataError
"DOMException
を投げる。 -
key を r とする。
-
-
targetRealm をユーザーエージェント定義の Realm とする。
-
clone を transaction の間に targetRealm 内で value の クローンとする。例外は再スローする。
なぜ値のコピーを作成するのか?
値は保存時にシリアライズされます。ここでコピーとして扱うことで、 この仕様の他のアルゴリズムが ECMAScript の値として扱えますが、 実装は挙動の違いが観測できない場合は最適化してよいです。 -
store が インラインキー を使用している場合、次を行う:
-
kpk を キー・パスで値からキーを抽出を clone と store の キー・パス で実行した結果とする。例外は再スローする。
-
kpk が無効なら、throw "
DataError
"DOMException
を投げる。 -
kpk が失敗でなければ、key を kpk とする。
-
それ以外の場合(kpk が失敗):
-
store が キー生成器を持たない場合、 throw "
DataError
"DOMException
を投げる。 -
値へキーを注入できるか確認を clone と store の キー・パス で実行し false を返した場合、throw "
DataError
"DOMException
を投げる。
-
-
-
operation を レコードをオブジェクトストアに保存を store、clone、key、no-overwrite flag で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を handle と operation で実行した結果を返す。
delete(query)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
transaction が 読み取り専用トランザクション の場合、 throw "
ReadOnlyError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query と true で実行した結果とする。例外は再スローする。
-
operation を オブジェクトストアからレコードを削除を store と range で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を this と operation で実行した結果を返す。
NOTE:
query パラメータは、キー
または キー範囲(IDBKeyRange
)
であり、削除対象の レコード を指定します。
注意: 他のキーやキー範囲を受け取るメソッドと異なり、このメソッドでは nullをキーとして渡すことはできません。これは、些細なバグによってオブジェクトストア全体が消去されるリスクを低減するためです。
clear()
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
transaction が 読み取り専用トランザクション の場合、 throw "
ReadOnlyError
"DOMException
を投げる。 -
operation を オブジェクトストアを空にするを store で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を this と operation で実行した結果を返す。
TransactionInactiveError
"
DOMException
をスローします。
- request = store .
get
(query) -
指定されたquery内のキーまたはキー範囲に一致する 最初のレコードの値を取得します。
成功した場合、requestの
result
は値となります。該当する レコードがなければundefined
となります。 - request = store .
getKey
(query) -
指定されたquery内のキーまたはキー範囲に一致する 最初のレコードのキーを取得します。
成功した場合、requestの
result
はキーとなります。該当する レコードがなければundefined
となります。 - request = store .
getAll
(query [, count])- request = store .
getAll
({query, count, direction}) - request = store .
-
指定されたquery内のキーまたはキー範囲に一致するレコードの値を取得します(countが指定されていれば、その件数まで)。 directionオプションに"
next
"を設定すると最初のcount件の値を取得し、 "prev
"を設定すると最後のcount件の値を返します。 - request = store .
getAllKeys
(query [, count])- request = store .
getAllKeys
({query, count, direction}) - request = store .
-
指定されたquery内のキーまたはキー範囲に一致するレコードのキーを取得します(countが指定されていれば、その件数まで)。 directionオプションに"
next
"を設定すると最初のcount件のキーを取得し、 "prev
"を設定すると最後のcount件のキーを返します。 - request = store .
getAllRecords
({query, count, direction}) -
queryオプションで一致するキーまたはキー範囲を指定します。 countオプションで一致するレコード数を制限できます。 directionオプションに"
next
"を設定すると最初のcount件のレコードを取得し、 "prev
"を設定すると最後のcount件のレコードを返します。 - request = store .
count
(query) -
指定されたquery内のキーまたはキー範囲に一致する レコードの件数を取得します。
成功した場合、requestの
result
は件数となります。
get(query)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query と true で実行した結果とする。例外は再スローする。
-
operation を オブジェクトストアから値を取得を 現在の Realm レコード、store、range で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を this と operation で実行した結果を返す。
注意:
query パラメータは、キー
または キー範囲(IDBKeyRange
)であり、
取得対象のレコード値を指定します。範囲を指定した場合は、その範囲で最初に存在する値を取得します。
注意:
このメソッドは、指定したキーのレコードが存在しない場合と、値がundefined
である場合の結果が同じです。
両者を区別する必要がある場合は、同じキーでopenCursor()
を使用してください。この場合、レコードが存在すれば値がundefined
のカーソルが返され、存在しなければカーソルは返されません。
getKey(query)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query と true で実行した結果とする。例外は再スローする。
-
operation を オブジェクトストアからキーを取得を store と range で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を this と operation で実行した結果を返す。
注意:
query パラメータは、キー
または キー範囲(IDBKeyRange
)であり、
取得対象のレコードキーを指定します。範囲を指定した場合は、その範囲で最初に存在するキーを取得します。
getAll(queryOrOptions, count)
メソッドの手順:
-
複数項目取得リクエストの作成を 現在の Realm レコード、this、"value"、 queryOrOptions、および指定されていれば count で実行した結果を返す。 例外は再スローする。
getAllKeys(queryOrOptions, count)
メソッドの手順:
-
複数項目取得リクエストの作成を 現在の Realm レコード、this、"key"、 queryOrOptions、および指定されていれば count で実行した結果を返す。 例外は再スローする。
getAllRecords(options)
メソッドの手順:
-
複数項目取得リクエストの作成を 現在の Realm レコード、this、"record"、 options で実行した結果を返す。 例外は再スローする。
count(query)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query で実行した結果とする。 例外は再スローする。
-
operation を 範囲内レコード件数取得を store と range で実行するアルゴリズムとする。
-
結果(
IDBRequest
)として、 非同期でリクエストを実行を this と operation で実行した結果を返す。
注意:
query パラメータは、キー
または キー範囲(IDBKeyRange
)であり、
件数取得対象のレコードを指定します。nullまたは未指定の場合は
制限なしのキー範囲が使用されます。
TransactionInactiveError
"
DOMException
をスローします。
- request = store .
openCursor
([query [, direction = "next"]]) -
queryに一致するレコードを directionの順で走査するカーソルを開きます。 queryがnullの場合、store内のすべてのレコードが対象となります。
成功した場合、requestの
result
はIDBCursorWithValue
で、最初の一致するレコードを指します。一致するレコードがない場合はnullです。 - request = store .
openKeyCursor
([query [, direction = "next"]]) -
キーのみフラグを true にした カーソルで queryに一致するレコードを directionの順で走査します。 queryがnullの場合、store内のすべてのレコードが対象となります。
成功した場合、requestの
result
はIDBCursor
で、最初の一致するレコードを指します。一致するレコードがない場合はnullです。
openCursor(query, direction)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query で実行した結果とする。 例外は再スローする。
-
cursor を新しいカーソルとし、 ソースハンドルを thisに設定し、 位置は未定義、 方向をdirection、 値取得フラグはfalse、 キーと値は未定義、 範囲はrange、 キーのみフラグはfalseに設定する。
-
operation を カーソルを反復を 現在の Realm レコードとcursorで実行するアルゴリズムとする。
-
request を 非同期でリクエストを実行を this と operation で実行した結果とする。
-
cursor の request を requestに設定する。
-
request を返す。
注意:
query パラメータは、キー
または キー範囲(IDBKeyRange
)であり、
カーソルの範囲として使用されます。
nullまたは未指定の場合は制限なしのキー範囲が使用されます。
openKeyCursor(query, direction)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
range を 値からキー範囲への変換を query で実行した結果とする。 例外は再スローする。
-
cursor を新しいカーソルとし、 ソースハンドルを thisに設定し、 位置は未定義、 方向をdirection、 値取得フラグはfalse、 キーと値は未定義、 範囲はrange、 キーのみフラグはtrueに設定する。
-
operation を カーソルを反復を 現在の Realm レコードとcursorで実行するアルゴリズムとする。
-
request を 非同期でリクエストを実行を this と operation で実行した結果とする。
-
cursor の request を requestに設定する。
-
request を返す。
注意:
query パラメータは、キー
または キー範囲(IDBKeyRange
)であり、
カーソルの範囲として使用されます。nullまたは未指定の場合は
制限なしのキー範囲が使用されます。
- index = store . index(name)
- index = store .
createIndex
(name, keyPath [, options]) -
store内で指定されたname、keyPath、optionsで新しいインデックスを作成し、新しい
IDBIndex
を返します。 もしkeyPathやoptionsで定義された制約がstore内の既存データで満たせない場合、アップグレードトランザクションは 中断され、 "ConstraintError
"DOMException
がスローされます。アップグレードトランザクション内で呼び出されない場合は、 "
InvalidStateError
"DOMException
がスローされます。 - store .
deleteIndex
(name) -
store内で指定されたnameのインデックスを削除します。
アップグレードトランザクション内で呼び出されない場合は、 "
InvalidStateError
"DOMException
がスローされます。
createIndex(name, keyPath, options)
メソッドの手順:
-
transaction がアップグレードトランザクションでない場合、 throw "
InvalidStateError
"DOMException
を投げる。 -
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
store にnameというインデックスがすでに存在する場合、 throw "
ConstraintError
"DOMException
を投げる。 -
keyPath が有効なキー・パスでない場合、throw "
SyntaxError
"DOMException
を投げる。 -
unique を options の
unique
メンバーとする。 -
multiEntry を options の
multiEntry
メンバーとする。 -
keyPath がシーケンスでmultiEntryがtrueの場合、 throw "
InvalidAccessError
"DOMException
を投げる。 -
index を storeに新しく作成したインデックスとする。 indexの名前にname、 キー・パスにkeyPath、 一意フラグにunique、 multiEntryフラグにmultiEntryを設定する。
-
新しいインデックスハンドルを indexおよびthisに関連付けて返す。
このメソッドは、指定された名前でオブジェクトストアに 新しいインデックスを作成して返します。 このメソッドはアップグレードトランザクションからのみ呼び出す必要があります。
作成するインデックスには、インデックスが参照するオブジェクトストアのデータに対する制約(例えばインデックスの
キー・パスによる値の一意性)を含めることができます。
既に参照先のオブジェクトストアにその制約に違反するデータがある場合でも、
createIndex()
の実装が例外を投げたり動作に影響を与えたりしてはいけません。
必ずIDBIndex
オブジェクトを作成して返し、
データベースタスクをキューして
createIndex()
呼び出しで使用された
アップグレードトランザクションを中断します。
このメソッドは、呼び出したIDBObjectStore
インスタンスのindexNames
プロパティを同期的に変更します。
このメソッドはIDBRequest
オブジェクトは返しませんが、インデックスの作成自体は
アップグレードトランザクション内で非同期リクエストとして処理されます。
一部の実装では、createIndexメソッドの戻り値返却後にインデックス作成で非同期的に問題が発生する場合があります。
例えば新しく作成したインデックスのメタデータを非同期でデータベースに挿入する場合や、クォータの関係でユーザーの許可が必要な場合などです。
その場合でもIDBIndex
オブジェクトは必ず作成・返却され、
作成失敗が判明した際には適切なエラーでトランザクションを中断する手順を実行する必要があります。
例えばインデックス作成がクォータの理由で失敗した場合は
QuotaExceededError
をエラーとして使用し、一意性制約違反の場合は
"ConstraintError
"
DOMException
をエラーとして使用します。
インデックスの非同期作成は以下の例で観察できます:
const request1= objectStore. put({ name: "betty" }, 1 ); const request2= objectStore. put({ name: "betty" }, 2 ); const index= objectStore. createIndex( "by_name" , "name" , { unique: true });
createIndex()
が呼び出された時点では、どちらの
リクエストも実行されていません。2つ目のリクエストが実行されると、重複したnameが作成されます。
インデックス作成は非同期リクエストとみなされるため、インデックスの一意性制約
で2つ目の
リクエストが失敗することはありません。
代わりに、インデックス作成時に制約が失敗した際にトランザクション
が中断されます。
index(name)
メソッドの手順:
-
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が finishedの場合、 throw "
InvalidStateError
"DOMException
を投げる。 -
index を インデックス nameが this の インデックス集合に存在すればそれとし、存在しなければ throw "
NotFoundError
"DOMException
を投げる。 -
indexおよびthisに関連付けた インデックスハンドルを返す。
注意:
同じIDBObjectStore
インスタンスで
同じnameを指定してこのメソッドを呼び出すと、同じIDBIndex
インスタンスが返されます。
注意:
返されるIDBIndex
インスタンスは
このIDBObjectStore
インスタンス専用です。
別のIDBObjectStore
インスタンスで
同じnameを指定して呼び出した場合は、別のIDBIndex
インスタンスが返されます。
deleteIndex(name)
メソッドの手順:
-
transaction がアップグレードトランザクションでない場合、 throw "
InvalidStateError
"DOMException
を投げる。 -
store が削除されている場合、throw "
InvalidStateError
"DOMException
を投げる。 -
transaction の 状態 が active でない場合、 throw "
TransactionInactiveError
"DOMException
を投げる。 -
storeにnameのインデックスが存在すればそれをindexとし、存在しなければ throw "
NotFoundError
"DOMException
を投げる。 -
index を破棄する。
このメソッドは、指定された名前のインデックスを オブジェクトストアから破棄します。 このメソッドはアップグレードトランザクション内からのみ呼び出す必要があります。
このメソッドは、呼び出したIDBObjectStore
インスタンスのindexNames
プロパティを同期的に変更します。
このメソッドはIDBRequest
オブジェクトは返しませんが、インデックスの破棄自体は
アップグレードトランザクション内で非同期リクエストとして処理されます。
4.6. IDBIndex
インターフェイス
IDBIndex
インターフェイスは、インデックスハンドルを表します。
[Exposed =(Window ,Worker )]interface {
IDBIndex attribute DOMString name ; [SameObject ]readonly attribute IDBObjectStore objectStore ;readonly attribute any keyPath ;readonly attribute boolean multiEntry ;readonly attribute boolean unique ; [NewObject ]IDBRequest get (any ); [
query NewObject ]IDBRequest getKey (any ); [
query NewObject ]IDBRequest getAll (optional any ,
queryOrOptions optional [EnforceRange ]unsigned long ); [
count NewObject ]IDBRequest getAllKeys (optional any ,
queryOrOptions optional [EnforceRange ]unsigned long ); [
count NewObject ]IDBRequest getAllRecords (optional IDBGetAllOptions = {}); [
options NewObject ]IDBRequest count (optional any ); [
query NewObject ]IDBRequest openCursor (optional any ,
query optional IDBCursorDirection = "next"); [
direction NewObject ]IDBRequest openKeyCursor (optional any ,
query optional IDBCursorDirection = "next"); };
direction
- index .
name
-
インデックスのnameを返します。
- index .
name
= newName -
ストアのnameをnewNameに更新します。
アップグレードトランザクション内で呼び出されない場合、"
InvalidStateError
"DOMException
がスローされます。 - index .
objectStore
-
インデックスが属している
IDBObjectStore
を返します。 - index . keyPath
-
インデックスのkey pathを返します。
- index . multiEntry
-
インデックスのmultiEntry flagがtrueの場合、trueを返します。
- index . unique
-
インデックスのunique flagがtrueの場合、trueを返します。
name
ゲッターの手順は、thisのnameを返すことです。
これはindexのnameと同じですか?
トランザクションが終了していなければ、 これは関連するindexの nameと同じです。ただし、トランザクションが 終了した後は、 この属性は後のアップグレードトランザクションで行われた変更を反映しません。name
セッターの手順は以下の通りです:
-
nameを与えられた値とする。
-
transactionをthisのtransactionとする。
-
もしtransactionがアップグレードトランザクションでなければ、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしindexまたはindexのオブジェクトストアが 削除されていた場合、throwし、"
InvalidStateError
"DOMException
とする。 -
もしindexのnameが nameと等しければ、これらの手順を終了する。
-
もしindexのオブジェクトストアに nameというindex nameが既に存在する場合、 throwし、"
ConstraintError
"DOMException
とする。 -
indexのnameを nameに設定する。
objectStore
ゲッターの手順は、thisのオブジェクトストアハンドルを返すことです。
keyPath
ゲッターの手順は、thisのindexの
key
pathを返すことです。
key pathは
DOMString
(文字列の場合)または
sequence<
(文字列リストの場合)として変換されます。[WEBIDL]参照。
DOMString
>
NOTE:
返される値は、
index作成時に使用されたインスタンスと同じではありません。ただし、
この属性がオブジェクト(特にArray
)を返す場合、
毎回同じオブジェクトインスタンスが返されます。オブジェクトのプロパティを変更しても
indexには影響しません。
multiEntry
ゲッターの手順は、thisのindexのmultiEntry
flagを返すことです。
unique
ゲッターの手順は、thisのindexのunique flagを返すことです。
TransactionInactiveError
"
DOMException
をスローします。
- request = index .
get
(query) - request = index .
getKey
(query) - request = index .
getAll
(query [, count])- request = index .
getAll
({query, count, direction}) - request = index .
-
queryで指定したキーまたはキー範囲に一致するレコードの値を取得します(countが指定されている場合は最大count件)。 directionオプションに"
next
"を指定すると先頭からcount件の値を取得し、 "prev
"を指定すると末尾からcount件の値を取得します。 "nextunique
"または"prevunique
"を指定すると、重複したインデックスキーのレコードは最初の一致したレコードのみ取得し、それ以降は除外します。 - request = index .
getAllKeys
(query [, count])- request = index .
getAllKeys
({query, count, direction}) - request = index .
-
queryで指定したキーまたはキー範囲に一致するレコードのキーを取得します(countが指定されている場合は最大count件)。 directionオプションに"
next
"を指定すると先頭からcount件のキーを取得し、 "prev
"を指定すると末尾からcount件のキーを取得します。 "nextunique
"または"prevunique
"を指定すると、重複したインデックスキーのレコードは最初の一致したレコードのみ取得し、それ以降は除外します。 - request = index .
getAllRecords
({query, count, direction}) -
queryオプションで一致するキーまたはキー範囲を指定します。 countオプションで一致するレコード数の上限を指定できます。 directionオプションに"
next
"を指定すると先頭からcount件のレコードを取得し、 "prev
"を指定すると末尾からcount件のレコードを取得します。 "nextunique
"または"prevunique
"を指定すると、重複したインデックスキーのレコードは最初の一致したレコードのみ取得し、それ以降は除外します。成功すると、requestの
result
はArray
となり、各要素はIDBRecord
です。 レコードのインデックスキーはIDBRecordのkey
で取得でき、キーはIDBRecordのprimaryKey
で取得できます。指定したquery内のkey またはkey rangeに一致するレコードの数を取得します。
成功すると、requestの
result
は 件数となります。
get(query)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしindexまたはindexのオブジェクトストアが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをqueryとtrueを使って値をキー範囲へ変換するの結果とする。例外があれば再スローする。
-
operationをインデックスから参照値を取得するアルゴリズム(現在のRealmレコード, index, range)で実行するものとする。
-
非同期でリクエストを実行するを thisとoperationで実行した結果(
IDBRequest
)を返す。
注意:
queryパラメータはkeyまたはkey range
(IDBKeyRange
)で、
取得したい参照値を特定します。範囲が指定された場合、その範囲内の最初の既存レコードを取得します。
注意:
このメソッドは、指定したキーにレコードが存在しない場合も、値がundefined
のレコードが存在する場合も、同じ結果を返します。
両者を区別したい場合は、同じキーでopenCursor()
を利用してください。レコードが存在すれば値はundefined
、存在しなければカーソル自体が返りません。
getKey(query)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしindexまたはindexのオブジェクトストアが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをqueryとtrueを使って値をキー範囲へ変換するの結果とする。例外があれば再スローする。
-
operationをインデックスから値を取得するアルゴリズム(index, range)で実行するものとする。
-
非同期でリクエストを実行するを thisとoperationで実行した結果(
IDBRequest
)を返す。
注意:
queryパラメータはkeyまたはkey range
(IDBKeyRange
)で、
取得したいレコードのキーを特定します。範囲が指定された場合、その範囲内の最初の既存キーを取得します。
getAll(queryOrOptions, count)
メソッドの手順は以下の通りです:
-
複数項目を取得するリクエストを作成するを 現在のRealmレコード, this, "value", queryOrOptions, count(指定されていれば)で実行した結果を返す。例外は再スローする。
getAllKeys(queryOrOptions, count)
メソッドの手順は以下の通りです:
-
複数項目を取得するリクエストを作成するを 現在のRealmレコード, this, "key", queryOrOptions, count(指定されていれば)で実行した結果を返す。例外は再スローする。
getAllRecords(options)
メソッドの手順は以下の通りです:
-
複数項目を取得するリクエストを作成するを 現在のRealmレコード, this, "record", optionsで実行した結果を返す。例外は再スローする。
count(query)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしindexまたはindexのオブジェクトストアが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをqueryを使って値をキー範囲へ変換するの結果とする。 例外があれば再スローする。
-
operationを範囲内のレコード数を数えるアルゴリズム(index, range)で実行するものとする。
-
非同期でリクエストを実行するを thisとoperationで実行した結果(
IDBRequest
)を返す。
注意:
queryパラメータはkeyまたはkey range
(IDBKeyRange
)で、
カウント対象のレコードを特定します。nullまたは未指定の場合、無制限キー範囲が使われます。
TransactionInactiveError
"
DOMException
をスローします。
- request = index .
openCursor
([query [, direction = "next"]]) -
queryに一致するレコードをdirectionで並べてカーソルを開きます。 queryがnullの場合、indexのすべてのレコードが対象となります。
成功すると、requestの
result
はIDBCursorWithValue
型、マッチする レコードがなければnullです。 - request = index .
openKeyCursor
([query [, direction = "next"]]) -
queryに一致するレコードをdirectionで並べて key only flagをtrueにして カーソルを開きます。 queryがnullの場合、indexのすべてのレコードが対象となります。
openCursor(query, direction)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしindexまたはindexのオブジェクトストアが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをqueryを使って値をキー範囲へ変換するの結果とする。 例外があれば再スローする。
-
cursorを新しいカーソルとし、 source handleをthisに設定し、 positionを未定義にし、 directionをdirectionに設定し、 got value flagをfalseにし、 keyとvalueを未定義にし、 rangeをrangeに設定し、 key only flagをfalseに設定する。
-
operationをカーソルを反復処理するアルゴリズム(現在のRealmレコード, cursor)で実行するものとする。
-
requestを非同期でリクエストを実行するを thisとoperationで実行した結果とする。
-
cursorのrequestをrequestに設定する。
-
requestを返す。
注意:
queryパラメータはkeyまたはkey range
(IDBKeyRange
)で、
カーソルのrangeとして使います。nullまたは未指定の場合、無制限キー範囲が使われます。
openKeyCursor(query, direction)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしindexまたはindexのオブジェクトストアが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをqueryを使って値をキー範囲へ変換するの結果とする。 例外があれば再スローする。
-
cursorを新しいカーソルとし、 source handleをthisに設定し、 positionを未定義にし、 directionをdirectionに設定し、 got value flagをfalseにし、 keyとvalueを未定義にし、 rangeをrangeに設定し、 key only flagをtrueに設定する。
-
operationをカーソルを反復処理するアルゴリズム(現在のRealmレコード, cursor)で実行するものとする。
-
requestを非同期でリクエストを実行するを thisとoperationで実行した結果とする。
-
cursorのrequestをrequestに設定する。
-
requestを返す。
注意:
queryパラメータはkeyまたはkey range
(IDBKeyRange
)で、
カーソルのrangeとして使います。nullまたは未指定の場合、無制限キー範囲が使われます。
4.7. IDBKeyRange
インターフェイス
IDBKeyRange
インターフェイスは
キー範囲を表します。
[Exposed =(Window ,Worker )]interface {
IDBKeyRange readonly attribute any lower ;readonly attribute any upper ;readonly attribute boolean lowerOpen ;readonly attribute boolean upperOpen ; // Static construction methods: [NewObject ]static IDBKeyRange only (any ); [
value NewObject ]static IDBKeyRange lowerBound (any ,
lower optional boolean =
open false ); [NewObject ]static IDBKeyRange upperBound (any ,
upper optional boolean =
open false ); [NewObject ]static IDBKeyRange bound (any ,
lower any ,
upper optional boolean =
lowerOpen false ,optional boolean =
upperOpen false );boolean includes (any ); };
key
lower
ゲッターの手順は、
キーを値に変換するを
thisの下限に対して呼び出し、nullでなければその結果を、そうでなければundefinedを返します。
upper
ゲッターの手順は、
キーを値に変換するをthisの上限に対して呼び出し、nullでなければその結果を、そうでなければundefinedを返します。
lowerOpen
ゲッターの手順は
thisの下限開放フラグを返します。
upperOpen
ゲッターの手順は
thisの上限開放フラグを返します。
- range =
IDBKeyRange
.only
(key) -
新しい
IDBKeyRange
を作成し、keyのみを範囲に含みます。 - range =
IDBKeyRange
.lowerBound
(key [, open = false]) -
新しい
IDBKeyRange
を作成し、keyから始まり上限はありません。openがtrueの場合、keyは範囲に含まれません。 - range =
IDBKeyRange
.upperBound
(key [, open = false]) -
新しい
IDBKeyRange
を作成し、下限はなくkeyまでの範囲となります。openがtrueの場合、keyは範囲に含まれません。 - range =
IDBKeyRange
.bound
(lower, upper [, lowerOpen = false [, upperOpen = false]]) -
新しい
IDBKeyRange
を作成し、lowerからupperまでの範囲となります。 lowerOpenがtrueの場合、lowerは範囲に含まれません。 upperOpenがtrueの場合、upperは範囲に含まれません。
only(value)
メソッドの手順は以下の通りです:
lowerBound(lower, open)
メソッドの手順は以下の通りです:
upperBound(upper, open)
メソッドの手順は以下の通りです:
bound(lower, upper, lowerOpen, upperOpen)
メソッドの手順は以下の通りです:
-
lowerKeyを値をキーに変換するをlowerに対して呼び出し、その結果とする。例外があれば再スローする。
-
もしlowerKeyが「無効な値」または「無効な型」であれば、throwし、"
DataError
"DOMException
とする。 -
upperKeyを値をキーに変換するをupperに対して呼び出し、その結果とする。例外があれば再スローする。
-
もしupperKeyが「無効な値」または「無効な型」であれば、throwし、"
DataError
"DOMException
とする。 -
もしlowerKeyがupperKeyより大きい場合、throwし、"
DataError
"DOMException
とする。 -
新しいキー範囲を作成し、 下限をlowerKeyに、 下限開放フラグをlowerOpenに、 上限をupperKeyに、 上限開放フラグをupperOpenに設定し、返す。
- range .
includes
(key) -
keyがレンジに含まれていればtrue、そうでなければfalseを返します。
includes(key)
メソッドの手順は以下の通りです:
-
kを値をキーに変換するをkeyに対して呼び出し、その結果とする。例外があれば再スローする。
-
もしkが「無効な値」または「無効な型」であれば、throwし、"
DataError
"DOMException
とする。 -
kがこのレンジに含まれていればtrue、そうでなければfalseを返す。
4.8. IDBRecord
インターフェイス
IDBRecord
インターフェイスはレコードスナップショットを表します。
[Exposed =(Window ,Worker )]interface {
IDBRecord readonly attribute any key ;readonly attribute any primaryKey ;readonly attribute any value ; };
- record .
key
-
レコードのキーを返します。
- record .
primaryKey
-
レコードがインデックスから取得された場合、インデックスの参照オブジェクトストア内でのレコードのキーを返します。
レコードがオブジェクトストアから取得された場合、レコードのキーを返します。これは record.
key
と同じキーです。 - record .
value
-
レコードの値を返します。
key
ゲッターの手順は、キーを値に変換するをthisのkeyに対して呼び出した結果を返します。
primaryKey
ゲッターの手順は、キーを値に変換するをthisのprimary keyに対して呼び出した結果を返します。
4.9. IDBCursor
インターフェイス
カーソルオブジェクトは IDBCursor
インターフェイスを実装します。
ひとつの IDBCursor
インスタンスは、あるカーソルを表すものとして常にひとつだけ存在します。同時に利用できるカーソル数の制限はありません。
[Exposed =(Window ,Worker )]interface {
IDBCursor readonly attribute (IDBObjectStore or IDBIndex )source ;readonly attribute IDBCursorDirection direction ;readonly attribute any key ;readonly attribute any primaryKey ; [SameObject ]readonly attribute IDBRequest request ;undefined advance ([EnforceRange ]unsigned long );
count undefined continue (optional any );
key undefined continuePrimaryKey (any ,
key any ); [
primaryKey NewObject ]IDBRequest update (any ); [
value NewObject ]IDBRequest delete (); };enum {
IDBCursorDirection ,
"next" ,
"nextunique" ,
"prev" };
"prevunique"
- cursor .
source
-
カーソルが開かれた
IDBObjectStore
またはIDBIndex
を返します。 - cursor .
direction
-
カーソルの方向 ("
next
"、 "nextunique
"、 "prev
"、 "prevunique
") を返します。 - cursor .
key
-
カーソルのキーを返します。 カーソルが進行中または終了している場合は"
InvalidStateError
"DOMException
がスローされます。 - cursor .
primaryKey
-
カーソルの実効キーを返します。 カーソルが進行中または終了している場合は"
InvalidStateError
"DOMException
がスローされます。 - cursor .
request
-
このカーソルを取得するために使われたリクエストを返します。
source
ゲッターの手順は、
thisの
source
handleを返します。
注意:
source
属性はnullを返したり例外をスローしたりしません。カーソルが現在反復中、終端を超えた、または
トランザクションが
activeでなくても同じです。
direction
ゲッターの手順は、
thisの
directionを返します。
key
ゲッターの手順は、
カーソルの現在のkeyをキーを値に変換するで変換した結果を返します。
注意:
key
がオブジェクト(例:Date
や
Array
)を返す場合、
カーソルのkeyが変更されるまで毎回同じオブジェクトインスタンスが返されます。
このオブジェクトを変更すると、その変更はカーソル値を参照するすべての利用者に見えますが、データベースの内容は変更されません。
primaryKey
ゲッターの手順は、
カーソルの現在の実効キーをキーを値に変換するで変換した結果を返します。
注意:
primaryKey
がオブジェクト(例:Date
や Array
)を返す場合、
カーソルの実効キーが変更されるまで毎回同じオブジェクトインスタンスが返されます。
このオブジェクトを変更すると、その変更はカーソル値を参照するすべての利用者に見えますが、データベースの内容は変更されません。
request
ゲッターの手順は、
thisの
requestを返します。
request
属性はこの版で新しく追加されました。
Chrome 76、Edge 79、Firefox 77、Safari 15でサポートされています。
🚧
success
イベントが、
カーソルが開かれたときに返された同じIDBRequest
に対して発火されます。
result
は、範囲内にレコードがあれば同じカーソルを、なければundefined
を返します。
カーソルがすでに進行中にこれらのメソッドを呼び出すと、"InvalidStateError
"
DOMException
がスローされます。
以下のメソッドは、トランザクションがactiveでない場合、
"TransactionInactiveError
"
DOMException
がスローされます。
- cursor .
advance
(count) -
範囲内の次のcount件レコードへカーソルを進めます。
- cursor .
continue
() -
範囲内の次のレコードへカーソルを進めます。
- cursor .
continue
(key) -
範囲内でkeyに一致またはそれ以降のレコードへカーソルを進めます。
- cursor .
continuePrimaryKey
(key, primaryKey) -
範囲内でkeyとprimaryKeyに一致またはそれ以降のレコードへカーソルを進めます。sourceがインデックスでない場合は"
InvalidAccessError
"DOMException
がスローされます。
advance(count)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしthisのsourceまたはeffective object storeが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのgot value flagがfalse(カーソルが反復中または終端を超えている場合)なら、 throwし、"
InvalidStateError
"DOMException
とする。 -
thisのgot value flagをfalseに設定する。
-
requestのprocessed flagをfalseに設定する。
-
requestのdone flagをfalseに設定する。
-
operationをカーソルを反復処理するアルゴリズム(現在のRealmレコード, this, count)で実行するものとする。
-
非同期でリクエストを実行するを thisのsource handle, operation, requestで実行する。
注意:
新しいカーソルデータが読み込まれる前(例:同じonsuccessハンドラ内でadvance()
を2回呼ぶなど)にこのメソッドを複数回呼ぶと、
2回目以降は"InvalidStateError
"
DOMException
がスローされます。これはカーソルのgot value flagがfalseになったためです。
continue(key)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしthisのsourceまたは effective object storeが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのgot value flagがfalse(カーソルが反復中または終端を超えている場合)なら、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしkeyが指定されていれば:
-
rを値をキーに変換するをkeyに対して呼び出した結果とする。例外があれば再スローする。
-
もしrが「無効な値」または「無効な型」であれば、throw し、"
DataError
"DOMException
とする。 -
keyをrとする。
-
もしkeyがless thanまたはequal toでthisの position、かつthisのdirectionが "
next
" または"nextunique
"であれば、 throwし、"DataError
"DOMException
とする。 -
もしkeyがgreater thanまたはequal toでthisの position、かつthisのdirectionが "
prev
" または"prevunique
"であれば、 throwし、"DataError
"DOMException
とする。
-
-
thisのgot value flagをfalseに設定する。
-
requestのprocessed flagをfalseに設定する。
-
requestのdone flagをfalseに設定する。
-
operationをカーソルを反復処理するアルゴリズム(現在のRealmレコード, this, key(指定されていれば))で実行するものとする。
-
非同期でリクエストを実行するを thisのsource handle, operation, requestで実行する。
注意:
新しいカーソルデータが読み込まれる前(例:同じonsuccessハンドラ内でcontinue()
を2回呼ぶなど)にこのメソッドを複数回呼ぶと、
2回目以降は"InvalidStateError
"
DOMException
がスローされます。これはカーソルのgot value flagがfalseになったためです。
continuePrimaryKey(key, primaryKey)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしthisのsourceまたはeffective object storeが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのsourceがインデックスでなければ、 throwし、"
InvalidAccessError
"DOMException
とする。 -
もしthisのdirectionが"
next
" または"prev
"でなければ、 throwし、"InvalidAccessError
"DOMException
とする。 -
もしthisのgot value flagがfalse(カーソルが反復中または終端を超えている場合)なら、 throwし、"
InvalidStateError
"DOMException
とする。 -
rを値をキーに変換するをkeyに対して呼び出した結果とする。例外があれば再スローする。
-
もしrが「無効な値」または「無効な型」であれば、throwし、"
DataError
"DOMException
とする。 -
keyをrとする。
-
rを値をキーに変換するをprimaryKeyに対して呼び出した結果とする。例外があれば再スローする。
-
もしrが「無効な値」または「無効な型」であれば、throwし、"
DataError
"DOMException
とする。 -
primaryKeyをrとする。
-
もしkeyがless thanでthisのposition、かつ thisのdirectionが"
next
"であれば、 throwし、"DataError
"DOMException
とする。 -
もしkeyがgreater thanでthisのposition、かつ thisのdirectionが"
prev
"であれば、 throwし、"DataError
"DOMException
とする。 -
もしkeyがequal toでthisのposition、かつ primaryKeyがless thanまたはequal toでthisのobject store position、かつ thisのdirectionが"
next
"であれば、 throwし、"DataError
"DOMException
とする。 -
もしkeyがequal toでthisのposition、かつ primaryKeyがgreater thanまたはequal toでthisの object store position、かつ thisの directionが"
prev
"であれば、 throwし、"DataError
"DOMException
とする。 -
thisのgot value flagをfalseに設定する。
-
requestのprocessed flagをfalseに設定する。
-
requestのdone flagをfalseに設定する。
-
operationをカーソルを反復処理するアルゴリズム(現在のRealmレコード, this, key, primaryKey)で実行するものとする。
-
非同期でリクエストを実行するを thisのsource handle, operation, requestで実行する。
注意:
新しいカーソルデータが読み込まれる前(例:同じonsuccessハンドラ内でcontinuePrimaryKey()
を2回呼ぶなど)にこのメソッドを複数回呼ぶと、
2回目以降は"InvalidStateError
"
DOMException
がスローされます。これはカーソルのgot value flagがfalseになったためです。
ReadOnlyError
"
DOMException
がスローされ、トランザクションがactiveでない場合は
"TransactionInactiveError
"
DOMException
がスローされます。
- request = cursor .
update
(value) -
カーソルが指しているレコードを新しい値で更新します。
effective object storeが in-line keysを使用していて キーが変更される場合、 "
DataError
"DOMException
がスローされます。 - request = cursor .
delete
() -
カーソルが指しているレコードを削除します。
成功した場合、requestの
result
はundefined
となります。
update(value)
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしtransactionが読取専用トランザクションであれば、 throwし、 "
ReadOnlyError
"DOMException
とする。 -
もしthisのsourceまたはeffective object storeが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのgot value flagがfalse(カーソルが反復中または終端を超えている場合)なら、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのkey only flagがtrueであれば、 throwし、"
InvalidStateError
"DOMException
とする。 -
targetRealmをユーザーエージェント定義のRealmとする。
-
cloneをtransaction中にtargetRealm内でvalueのクローンとする。例外があれば再スローする。
なぜ値のコピーを作成するのか?
値は保存時に直列化されます。ここでコピーとして扱うことで、この仕様書内の他のアルゴリズムがそれをECMAScript値として扱えますが、実装は動作の違いが観察されなければ最適化できます。 -
もしthisのeffective object storeがin-line keysを使用している場合:
-
kpkをキー・パスを使って値からキーを抽出するを cloneとkey path(thisのeffective object store)で実行した結果とする。例外があれば再スローする。
-
もしkpkが失敗・無効・equal toでない場合 thisのeffective key、 throwし、 "
DataError
"DOMException
とする。
-
-
operationをオブジェクトストアにレコードを格納するアルゴリズム(thisのeffective object store, clone, thisのeffective key, false)で実行するものとする。
-
非同期でリクエストを実行するを thisとoperationで実行した結果(
IDBRequest
)を返す。
注意: オブジェクトストアにレコードを格納する結果として、 カーソルが移動した後にレコードが削除されていた場合、新しいレコードが作成されます。
delete()
メソッドの手順は以下の通りです:
-
transactionをthisのtransactionとする。
-
もしtransactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
もしtransactionが読取専用トランザクションであれば、 throwし、 "
ReadOnlyError
"DOMException
とする。 -
もしthisのsourceまたはeffective object storeが削除されていた場合、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのgot value flagがfalse(カーソルが反復中または終端を超えている場合)なら、 throwし、"
InvalidStateError
"DOMException
とする。 -
もしthisのkey only flagがtrueであれば、 throwし、"
InvalidStateError
"DOMException
とする。 -
operationをオブジェクトストアからレコードを削除するアルゴリズム(thisのeffective object store, thisのeffective key)で実行するものとする。
-
非同期でリクエストを実行するを thisとoperationで実行した結果(
IDBRequest
)を返す。
カーソルのkey only flag
がfalseの場合は
IDBCursorWithValue
インターフェイスも実装します。
[Exposed =(Window ,Worker )]interface :
IDBCursorWithValue IDBCursor {readonly attribute any value ; };
value
ゲッターの手順は、
thisの
現在の値を返します。
注意:
value
がオブジェクトを返す場合、カーソルの値が変更されるまで毎回同じオブジェクトインスタンスが返されます。
このオブジェクトを変更すると、その変更は値を参照するすべての利用者に見えますが、データベースの内容は変更されません。
4.10. IDBTransaction
インターフェイス
トランザクション オブジェクトは次のインターフェイスを実装します:
[Exposed =(Window ,Worker )]interface :
IDBTransaction EventTarget {readonly attribute DOMStringList objectStoreNames ;readonly attribute IDBTransactionMode mode ;readonly attribute IDBTransactionDurability durability ; [SameObject ]readonly attribute IDBDatabase db ;readonly attribute DOMException ?error ;IDBObjectStore objectStore (DOMString );
name undefined commit ();undefined abort (); // Event handlers:attribute EventHandler onabort ;attribute EventHandler oncomplete ;attribute EventHandler onerror ; };enum {
IDBTransactionMode ,
"readonly" ,
"readwrite" };
"versionchange"
- transaction .
objectStoreNames
-
このトランザクションのスコープ内のオブジェクトストア名のリストを返します。アップグレードトランザクションの場合は、データベース内のすべてのオブジェクトストアです。
- transaction .
mode
-
このトランザクションの作成時のモード("
readonly
" または"readwrite
")、アップグレードトランザクションの場合は"versionchange
"を返します。 - transaction .
durability
-
このトランザクションの作成時の耐久性ヒント("
strict
"、 "relaxed
" )、または"default
"を返します。 - transaction .
db
-
このトランザクションの接続を返します。
- transaction .
error
-
このトランザクションが中断された場合、理由を示すエラー(
DOMException
)を返します。
objectStoreNames
ゲッターの手順:
-
namesでソート済み名リストを作成した結果(
DOMStringList
)を返す。
注意: この属性が返すリストの内容自体は変化しませんが、アップグレードトランザクション中は、オブジェクトストアの新規作成や削除により、呼び出しのたびに異なるリストが返されることがあります。
durability
ゲッターの手順は
thisの
durability hintを返します。
durability
属性はこの版で新しく追加されました。
Chrome 82、Edge 82、Firefox 126、Safari 15でサポートされています。
🚧
db
ゲッターの手順は
thisの
connectionに関連付けられたデータベースを返します。
error
ゲッターの手順は
thisの
error(存在しない場合はnull)を返します。
注意:
このトランザクションが失敗したリクエストにより中断された場合、
この値はそのリクエストのerrorと同じになります。
イベントハンドラ内の未捕捉例外により中断された場合は、"AbortError
"
DOMException
となります。
コミット時のエラーで中断された場合は、失敗理由(例: QuotaExceededError
や"ConstraintError
"、"UnknownError
"
DOMException
)が反映されます。
- transaction .
objectStore
(name) -
このトランザクションのスコープ内にある
IDBObjectStore
を返します。 - transaction .
abort()
-
トランザクションを中断します。保留中のリクエストはすべて "
AbortError
"DOMException
で失敗し、データベースへの変更はすべて元に戻されます。 - transaction .
commit()
-
トランザクションのコミットを試みます。保留中のリクエストはすべて完了させますが、新しいリクエストは受け付けません。 このメソッドは、保留中のリクエストの
success
イベントが発火するのを待たずに、通常のコミット処理を開始するために利用できます。保留中のリクエストが失敗した場合はトランザクションが中断されます(例:制約エラーなど)。成功したリクエストについては
success
イベントが発火しますが、イベントハンドラで例外を投げてもトランザクションは中断されません。同様に、失敗したリクエストのerror
イベントが発火しても、preventDefault()
を呼んでも中断は防げません。
objectStore(name)
メソッドの手順:
-
もしthisのstateがfinishedであれば、 throwし、"
InvalidStateError
"DOMException
とする。 -
storeをthisのオブジェクトストアのうち、nameという名前のものとし、存在しなければ throwし、 "
NotFoundError
"DOMException
とする。 -
storeにthisを関連付けたオブジェクトストアハンドルを返す。
注意:
同じIDBTransaction
インスタンス上で同じ名前でこのメソッドを呼ぶと、同じIDBObjectStore
インスタンスが返されます。
注意:
返されるIDBObjectStore
インスタンスは
このIDBTransaction
に固有です。別のIDBTransaction
で呼び出すと、別のIDBObjectStore
インスタンスが返されます。
abort()
メソッドの手順:
-
もしthisのstateがcommittingまたはfinishedであれば、 throwし、"
InvalidStateError
"DOMException
とする。 -
トランザクションを中断する(this, null)を実行する。
commit()
メソッドの手順:
-
もしthisのstateがactiveでなければ、 throwし、"
InvalidStateError
"DOMException
とする。 -
トランザクションをコミットする(this)を実行する。
commit()
メソッドはこの版で新しく追加されました。
Chrome 76、Edge 79、Firefox 74、Safari 15でサポートされています。
🚧
注意:
通常、commit()
をトランザクションに対して呼び出す必要はありません。
トランザクションは、未処理のリクエストがすべて満たされ、新たなリクエストが作成されていない場合に自動的にコミットされます。
この呼び出しは、未処理のリクエストからイベントが発行されるのを待たずに
コミット処理を開始するために使用できます。
onabort
属性は、イベントハンドラIDL属性であり、
イベントタイプはabort
です。
oncomplete
属性は、イベントハンドラIDL属性であり、
イベントタイプはcomplete
です。
onerror
属性は、イベントハンドラIDL属性であり、
イベントタイプはerror
です。
注意:
トランザクションが正常に完了したかどうかを判定するには、
トランザクションのcomplete
イベントを監視してください。success
イベントは個々のリクエストに対して発火しますが、
トランザクションはその後でも失敗する場合があります。
5. アルゴリズム
5.1. データベース接続のオープン
データベース接続をオープンするには、storageKey(データベースのオープン要求元)、データベースname、データベースversion、requestを使い、次の手順を実行する:
-
queueをstorageKeyとnameに対する接続キューとする。
-
requestをqueueに追加する。
-
queue内のすべての先行リクエストが処理されるまで待機する。
-
versionが未定義の場合、dbがnullならversionを1、そうでなければdbのversionとする。
-
もし db が null であれば、db を新しいデータベース( 名前 name、 バージョン 0(ゼロ)、および オブジェクトストアなし)として作成してください。 これが何らかの理由で失敗した場合、適切なエラー(例:
QuotaExceededError
または "UnknownError
"DOMException
)を返してください。 -
dbのversionがversionより大きい場合、 新しい"
VersionError
"DOMException
を返して処理を中断する。 -
connectionをdbへの新しい接続とする。
-
connectionのversionをversionに設定する。
-
dbのversionがversion未満なら:
-
openConnectionsをdbに関連付けられたすべての接続の集合で、connectionは除外。
-
openConnectionsの各entryでclose pending flagがtrueでないものに対し、 データベースタスクをキューしてversion changeイベント(名前:
versionchange
)を entryにdbのversionとversionで発火する。注意: このイベント発火により、openConnections内の他のオブジェクトの一部が閉じられる場合がある。その場合、すでに閉じられたものにはversionchangeイベントは発火しない。
-
すべてのイベントが発火されるまで待機する。
-
openConnections内でまだ閉じられていない接続があれば、 データベースタスクをキューして version changeイベント(名前:
blocked
)を requestにdbのversionとversionで発火する。 -
データベースをアップグレードする(connection, version, request)を実行する。
-
connectionがclosedなら、 新しい"
AbortError
"DOMException
を返して中断する。 -
requestのerrorがセットされていれば、 データベース接続を閉じる(connection)を実行し、 新しい"
AbortError
"DOMException
を返して中断する。
-
-
connectionを返す。
5.2. データベース接続のクローズ
データベース接続を閉じるには、connectionオブジェクトと、オプションのforced flagを使い、以下の手順を実行する:
-
connectionのclose pending flagをtrueに設定する。
-
forced flagがtrueなら、connectionを使って作成された各transactionについて、 トランザクションを中断する(transaction、新しい"
AbortError
"DOMException
)を実行する。 -
connectionを使って作成されたすべてのトランザクションが完了するまで待機する。完了したらconnectionはclosedとなる。
-
forced flagがtrueなら、イベント発火(名前:
close
)をconnectionに対して行う。注意:
close
イベントは接続が異常終了した場合(例:storage keyのストレージクリアや破損・I/Oエラーなど)にのみ発火される。close()
を明示的に呼んだ場合はイベントは発火しない。
注意: 接続のclose pending flagがtrueになると、新しいトランザクションは 接続を使って作成できなくなる。 トランザクション作成メソッドはまずconnectionのclose pending flagがtrueかどうかを確認し、trueなら例外を投げる。
注意: 接続が閉じられると、データベースアップグレードやデータベース削除の手順(両方が待機)をブロック解除できる。これは、指定されたデータベースへの接続がすべて閉じられるまで待機するため。
5.3. データベース削除
データベースを削除するには、storageKey(削除要求元)、データベースname、requestを使い、次の手順を実行する:
-
queueをstorageKeyとnameに対する接続キューとする。
-
requestをqueueに追加する。
-
queue内のすべての先行リクエストが処理されるまで待機する。
-
openConnectionsをdbに関連付けられたすべての接続の集合とする。
-
openConnectionsの各entryでclose pending flagがtrueでないものに対し、 データベースタスクをキューして version changeイベント(名前:
versionchange
)をentryにdbのversionとnullで発火する。注意: このイベント発火により、openConnections内の他のオブジェクトの一部が閉じられる場合がある。その場合、すでに閉じられたものにはversionchangeイベントは発火しない。
-
すべてのイベントが発火されるまで待機する。
-
openConnections内でまだ閉じられていない接続があれば、 データベースタスクをキューして version changeイベント(名前:
blocked
)を requestにdbのversionとnullで発火する。 -
versionをdbのversionとする。
-
dbを削除する。失敗した場合は、適切なエラー(例:
QuotaExceededError
や"UnknownError
"DOMException
)を返す。 -
versionを返す。
5.4. トランザクションのコミット
トランザクションをコミットするには、コミット対象transactionに対して以下の手順を実行する:
-
transactionのstateをcommittingに設定する。
-
以下の手順を並列で実行する:
-
transactionのrequest listのすべての項目がprocessedになるまで待つ。
-
transactionのstateがcommittingでなくなったら、これらの手順を終了する。
-
transactionが行った未処理の変更をデータベースへ transactionのdurability hintを考慮して書き込む。
-
変更書き込み時にデータベースでエラーが発生した場合、 abort a transaction(transactionとエラー型、例:
QuotaExceededError
や"UnknownError
"DOMException
)を実行し、これらの手順を終了する。 -
データベースタスクをキューして以下の手順を実行:
-
transactionがアップグレードトランザクションなら、 transactionのconnectionに関連付けられたdatabaseの upgrade transactionをnullに設定。
-
イベント発火(名前:
complete
)をtransactionへ。注意: このイベントのハンドラで例外が投げられても、トランザクションはすでにコミットされている。 データベースへの書き込みはイベント発火前に行われるため、イベント後にコミット済みとなる。
-
transactionがアップグレードトランザクションなら、 transactionに関連付けられたrequestのtransactionをnullに設定する。
-
-
5.5. トランザクションの中断
トランザクションを中断するには、中断対象transactionとerrorに対して以下の手順を実行する:
-
transactionがデータベースに行ったすべての変更を元に戻す。アップグレードトランザクションの場合、オブジェクトストアやインデックスの集合、versionの変更も含む。トランザクション中に作成されたオブジェクトストアやインデックスは、他のアルゴリズム上削除されたものとみなす。
-
transactionがアップグレードトランザクションの場合、 アップグレードトランザクションの中断(transaction)を実行する。
注意: この処理でtransactionに関連付けられたconnection、object store handle、index handleインスタンスの状態も巻き戻される。
-
transactionのerrorをerrorに設定。
-
transactionのrequest listの各requestについて 非同期リクエスト実行の手順を中断し、 requestのprocessed flagをtrueに、 データベースタスクをキューして以下の手順を実行:
-
requestのdone flagをtrueに設定。
-
requestのresultをundefinedに設定。
-
requestのerrorを新しい"
AbortError
"DOMException
に設定。 -
イベント発火(名前:
error
)をrequestへ(bubbles
、cancelable
はtrueで初期化)。
注意: この処理で必ずしも
error
イベントが発火するとは限らない。例えばコミット時のエラーや、最後のリクエストのみ失敗した場合は発火しないことがある。 -
-
データベースタスクをキューして以下の手順を実行:
-
transactionがアップグレードトランザクションなら、 transactionのconnectionに関連付けられたdatabaseのupgrade transactionをnullに設定。
-
transactionがアップグレードトランザクションなら:
-
requestをtransactionに関連付けられたopen requestとする。
-
requestのtransactionをnullに設定。
-
requestのresultをundefinedに設定。
-
requestのprocessed flagをfalseに設定。
-
requestのdone flagをfalseに設定。
-
-
5.6. リクエストの非同期実行 request
リクエストを非同期で実行するには、sourceオブジェクト、データベース上で実行するoperation、オプションのrequestを使い、以下の手順を実行する:
これらの手順は、作成されたrequestが属するトランザクションが中断された場合、 トランザクションの中断の手順でいつでも中止可能。
-
transactionをsourceに関連付けられたトランザクションとする。
-
requestをtransactionのrequest listの末尾に追加する。
-
以下の手順を並列で実行する:
-
requestがtransactionのrequest listの 未processed項目の先頭になるまで待つ。
-
operationを実行した結果をresultとする。
-
resultがエラーで、transactionのstateがcommittingなら、 トランザクションの中断(transaction, result)を実行し、これらの手順を終了する。
-
resultがエラーの場合、 operationで行ったすべての変更を巻き戻す。
注意: これはこのリクエストによる変更のみ巻き戻し、トランザクション全体の他の変更は巻き戻さない。
-
requestのprocessed flagをtrueに設定。
-
データベースタスクをキューして以下の手順を実行:
-
-
requestを返す。
5.7. データベースのアップグレード
データベースをアップグレードするには、connection(connection)、新しいversion、requestを使い、以下の手順を実行する:
-
dbをconnectionのdatabaseとする。
-
transactionをconnectionをconnectionとして用いる新しいアップグレードトランザクションとする。
-
transactionのscopeをconnectionのobject store setに設定する。
-
dbのupgrade transactionを transactionに設定する。
-
transactionを開始する。
-
old versionをdbのversionとする。
-
dbのversionをversionに設定する。この変更はトランザクションの一部とみなされるため、トランザクションが中断された場合は巻き戻される。
-
requestのprocessed flagをtrueに設定する。
-
データベースタスクをキューして以下の手順を実行:
-
requestのresultをconnectionに設定する。
-
requestのtransactionをtransactionに設定する。
-
requestのdone flagをtrueに設定する。
-
didThrowをversion changeイベントを発火(名前:
upgradeneeded
、request、old version、version)の結果とする。 -
-
didThrowがtrueなら、トランザクションの中断(transaction、新しい"
AbortError
"DOMException
)を実行する。
-
-
transactionがfinishされるまで待機する。
注意: トランザクションのライフタイム中に呼び出されるアルゴリズム(commit a transactionやabort a transactionの手順)は、アップグレードトランザクション固有の手順も含む。
5.8. アップグレードトランザクションの中断
アップグレードトランザクションの中断には、transactionに対して以下の手順を実行する:
注意: この手順はトランザクションの中断で必要に応じて実行され、データベースの関連するオブジェクトストアやインデックスの集合、およびversionの変更を巻き戻す。
-
connectionをtransactionのconnectionとする。
-
databaseをconnectionのdatabaseとする。
-
connectionのversionを、databaseが以前から存在した場合はそのversion、新規作成の場合は0に設定する。
注意: これは
version
プロパティ(IDBDatabase
オブジェクト)を巻き戻す。 -
connectionのobject store setを、databaseが以前から存在した場合はそのオブジェクトストア集合、そうでなければ空集合に設定する。
注意: これは
objectStoreNames
プロパティ(IDBDatabase
オブジェクト)を巻き戻す。 -
transactionに関連付けられた各object store handle handle(トランザクション中に作成・削除されたものも含む)について:
-
handleのobject storeがトランザクション中に新規作成されたものでなければ、 handleのnameを handleのobject storeのnameに設定する。
-
handleのindex setを、そのobject storeを参照するインデックス集合に設定する。
注意: これは関連する
name
やindexNames
プロパティ(IDBObjectStore
オブジェクト)を巻き戻す。これはどのように観測可能か?
スクリプトはトランザクションが中断された後、IDBTransaction
インスタンスのobjectStore()
メソッド経由でオブジェクトストアへアクセスできないが、IDBObjectStore
インスタンスへの参照は保持できるため、name
やindexNames
プロパティを取得できる。 -
-
transactionに関連付けられた各index handle handle(トランザクション中に作成・削除されたものも含む)について:
注意: これは関連する
name
プロパティ(IDBIndex
オブジェクト)を巻き戻す。これはどのように観測可能か?
スクリプトはトランザクションが中断された後、IDBObjectStore
インスタンスのindex()
メソッド経由でインデックスにアクセスできないが、IDBIndex
インスタンスへの参照は保持できるため、name
プロパティを取得できる。
注意:
name
プロパティ(IDBDatabase
インスタンス)は、
中断されたアップグレードトランザクションが新規データベースを作成した場合でも変更されない。
5.9. 成功イベントの発火
成功イベントを発火するには、requestに対して以下の手順を実行する:
-
eventの
type
属性を"success
"に設定する。 -
eventの
bubbles
およびcancelable
属性をfalseに設定する。 -
transactionをrequestのtransactionとする。
-
legacyOutputDidListenersThrowFlagを初期値falseとする。
-
transactionのstateがinactiveなら、 transactionのstateをactiveに設定する。
-
イベント配送(eventをrequestにlegacyOutputDidListenersThrowFlagで)。
-
-
legacyOutputDidListenersThrowFlagがtrueなら、 トランザクションの中断(transaction、新しい"
AbortError
"DOMException
)を実行する。 -
transactionのrequest listが空なら、 トランザクションのコミット(transaction)を実行する。
5.10. エラーイベントの発火
エラーイベントを発火するには、requestに対して以下の手順を実行する:
-
eventの
type
属性を"error
"に設定する。 -
eventの
bubbles
およびcancelable
属性をtrueに設定する。 -
transactionをrequestのtransactionとする。
-
legacyOutputDidListenersThrowFlagを初期値falseとする。
-
transactionのstateがinactiveなら、 transactionのstateをactiveに設定する。
-
-
legacyOutputDidListenersThrowFlagがtrueなら、 トランザクションの中断(transaction、新しい"
AbortError
"DOMException
)を実行し、これらの手順を終了する。 この処理はeventのcanceled flagがfalseでも行われる。注意: エラーイベント発火時に、どれかのイベントハンドラで例外が投げられた場合、transactionの
error
プロパティはAbortError
にセットされる。これはrequestのerrorでなくても、preventDefault()
が呼ばれなくても同じ。 -
eventのcanceled flagがfalseなら、 トランザクションの中断(transaction、requestのerror)を実行し、これらの手順を終了する。
-
transactionのrequest listが空なら、 トランザクションのコミット(transaction)を実行する。
5.11. 値のクローン
クローンを作成するには、 value、targetRealm、transactionを使い、以下の手順を実行する:
-
transactionのstateをinactiveに設定する。
注意: トランザクションをinactiveにすることで、 クローン操作によって発生するgetterや他の副作用がトランザクションに対して追加リクエストを行えなくなる。
-
serializedを? StructuredSerializeForStorage(value)の結果とする。
-
cloneを? StructuredDeserialize(serialized、targetRealm)の結果とする。
-
cloneを返す。
5.12. 複数アイテム取得リクエストの作成
複数アイテム取得リクエストの作成には、object storeまたはindexから、targetRealm、sourceHandle、kind、queryOrOptions、オプションのcountを使い、以下の手順を実行する:
-
sourceをsourceHandleから取得したindexまたはobject storeとする。 sourceHandleがindex handleの場合はsourceはそのindex handleのindex。 それ以外の場合はsourceはそのobject store handleのobject store。
-
sourceが削除されていれば、throwし、"
InvalidStateError
"DOMException
とする。 -
sourceがindexで、sourceのobject storeが削除されていれば、 throwし、"
InvalidStateError
"DOMException
とする。 -
transactionをsourceHandleのtransactionとする。
-
transactionのstateがactiveでなければ、 throwし、"
TransactionInactiveError
"DOMException
とする。 -
rangeをkey rangeとする。
-
directionをcursor directionとする。
-
is a potentially valid key range(queryOrOptions)の結果がtrueなら:
-
そうでなければ:
-
operationにアルゴリズムを設定する。
-
sourceがindexなら、 operationにインデックスから複数アイテム取得(targetRealm、source、range、kind、direction、count)を設定。
-
そうでなければ、operationにオブジェクトストアから複数アイテム取得(targetRealm、source、range、kind、direction、count)を設定。
-
非同期リクエスト実行(sourceHandle、operation)の結果(
IDBRequest
)を返す。
注意:
rangeはkeyまたはkey range(IDBKeyRange
)であり、取得対象のrecordアイテムを特定する。nullまたは未指定の場合はunbounded key rangeが使われる。
count指定時、範囲内にcountより多くのレコードがある場合は、最初のcount件のみ取得する。
6. データベース操作
この節では、データベース内のオブジェクトストアやインデックスで実行される様々な操作について説明します。 これらの操作は非同期リクエスト実行の手順で実行されます。
注意: 以下の操作手順内で呼び出されるStructuredDeserialize()は、!の接頭辞が示す通り、必ず例外を投げないと断言できます。 これは、必ずStructuredSerializeForStorage()の出力に対してのみ動作するためです。
6.1. オブジェクトストアへの保存操作
オブジェクトストアにレコードを格納するには store、value、(オプション)key、no-overwrite flagを使い、以下の手順を実行する:
-
storeがキージェネレーターを使用している場合:
-
keyが未定義なら:
-
keyをstoreに対してキー生成の結果とする。
-
keyが失敗なら、この操作は"
ConstraintError
"DOMException
で失敗とし、以降の手順を全て中止する。 -
storeがインラインキーも使用している場合は、 キーを値へ注入する をvalue、key、storeのkey pathで実行する。
-
-
そうでなければ、storeに対してkeyでキージェネレーターの更新を行う。
-
-
no-overwrite flagが指定されtrueで、かつstoreにkeyと等しいキーのレコードが既に存在する場合、この操作は"
ConstraintError
"DOMException
で失敗とし、以降の手順を全て中止する。 -
storeにkeyと等しいキーのレコードが既に存在する場合は、 オブジェクトストアからレコード削除でそのレコードを削除する。
-
storeにkeyをキー、StructuredSerializeForStorage(value)を値とするレコードを格納する。レコードはオブジェクトストアのレコードリスト内でキー昇順でソートされて格納される。
-
storeを参照する各indexについて:
-
index keyをキー・パスで値からキーを抽出する(value、indexのkey path、indexのmultiEntry flag)の結果とする。
-
index keyが例外・無効・失敗なら、そのindexについては以降何もせず次のインデックスへ。
注意: この段階で例外が投げられても再スローされません。
-
indexのmultiEntry flagがfalse、またはindex keyが配列キーでない場合、かつindexにindex keyと等しいキーのレコードが既に存在し、かつindexのunique flagがtrueなら、この操作は"
ConstraintError
"DOMException
で失敗とし、以降の手順を全て中止する。 -
indexのmultiEntry flagがtrue、かつindex keyが配列キーの場合、indexにindex keyのsubkeysのいずれかと等しいキーのレコードが既に存在し、かつindexのunique flagがtrueなら、この操作は"
ConstraintError
"DOMException
で失敗とし、以降の手順を全て中止する。 -
indexのmultiEntry flagがfalse、またはindex keyが配列キーでない場合は、indexにindex keyをキー、keyを値とするレコードを格納する。レコードはインデックスのレコードリスト内でキー→値昇順でソートされる。
-
indexのmultiEntry flagがtrue、かつindex keyが配列キーの場合は、index keyのsubkeysそれぞれについて、キー:subkey、値:keyでindexにレコードを格納する。レコードはインデックスのレコードリスト内でキー→値昇順でソートされる。
注意: subkeysが空の場合は、インデックスにレコードは追加されません。
注意: subkeysの要素が配列キーでも、そのままインデックスレコードのキーとなる。ネストした配列キーはフラット化や展開されない。外側の配列キーのみが使われる。
-
-
keyを返す。
6.2. オブジェクトストアの取得操作
オブジェクトストアから値を取得するには
targetRealm、store、rangeを使い、以下の手順を実行する。
返り値はundefined、ECMAScript値、またはエラー(DOMException
):
-
recordが見つからなければundefinedを返す。
-
serializedをrecordの値とする。ストレージから値の読み出し時にエラーが発生した場合は、新しい"
NotReadableError
"DOMException
を返す。 -
StructuredDeserialize(serialized, targetRealm)の結果を返す。
オブジェクトストアからキーを取得する にはstore、rangeを使い、以下の手順を実行する:
オブジェクトストアから複数アイテムを取得する にはtargetRealm、store、range、kind、direction、(オプション)countを使い、以下の手順を実行する:
-
countが未指定または0なら、countを無限大とする。
-
directionが"
next
"または"nextunique
"なら、recordsをstoreのレコードリスト内でrangeに含まれるキーを持つ最初のcount件とする。 -
directionが"
prev
"または"prevunique
"なら、recordsをstoreのレコードリスト内でrangeに含まれるキーを持つ最後のcount件とする。 -
listを空のリストとする。
-
recordsの各recordについてkindで分岐:
- "key"
- "value"
-
-
serializedをrecordの値とする。
-
valueをStructuredDeserialize(serialized, targetRealm)の結果とする。
-
valueをlistに追加。
-
- "record"
-
-
keyをrecordのkeyとする。
-
serializedをrecordの値とする。
-
valueをStructuredDeserialize(serialized, targetRealm)の結果とする。
-
recordSnapshotを、keyをキー、valueを値、keyを主キーとして持つ新しいrecord snapshotとする。
-
recordSnapshotをlistに追加。
-
-
listを返す。
6.3. インデックス取得操作
インデックスから参照値を取得する にはtargetRealm、index、rangeを使い、以下の手順を実行する:
インデックスから値を取得する にはindex、rangeを使い、以下の手順を実行する:
インデックスから複数アイテムを取得する にはtargetRealm、index、range、kind、direction、(オプション)countを使い、以下の手順を実行する:
-
countが未指定または0なら、countを無限大とする。
-
directionで分岐:
- "next"
- "nextunique"
- "prev"
- "prevunique"
-
listを空のリストとする。
-
recordsの各recordについてkindで分岐:
- "key"
- "value"
-
-
serializedをrecordの参照値とする。
-
valueをStructuredDeserialize(serialized, targetRealm)の結果とする。
-
valueをlistに追加。
-
- "record"
-
-
index keyをrecordのキーとする。
-
keyをrecordの値とする。
-
serializedをrecordの参照値とする。
-
valueをStructuredDeserialize(serialized, targetRealm)の結果とする。
-
recordSnapshotを、index keyをキー、valueを値、keyを主キーとして持つ新しいrecord snapshotとする。
-
recordSnapshotをlistに追加。
-
-
listを返す。
6.4. オブジェクトストア削除操作
オブジェクトストアからレコードを削除する にはstore、rangeを使い、以下の手順を実行する:
6.5. レコード数カウント操作
範囲内レコード数を数えるにはsource、rangeを使い、以下の手順を実行する:
-
countをsourceのレコードリスト内でrangeに含まれるキーを持つレコードの数(存在する場合)とする。
-
countを返す。
6.6. オブジェクトストアクリア操作
オブジェクトストアをクリアするにはstoreを使い、以下の手順を実行する:
6.7. カーソル反復操作
カーソルを反復処理するには、targetRealm、cursor、(オプション)key・primaryKey(反復先)、(オプション)countを使い、以下の手順を実行する:
-
sourceをcursorのsourceとする。
-
directionをcursorのdirectionとする。
-
Assert:primaryKeyが指定されていれば、sourceはindexであり、directionは"
next
"または"prev
"であること。 -
recordsをsource内のレコードリストとする。
注意: recordsは常に昇順のキー順でソートされている。 sourceがindexの場合、さらに昇順の値順でセカンダリソートされる(インデックスの値は、参照先レコードのキー)。
-
rangeをcursorのrangeとする。
-
positionをcursorのpositionとする。
-
object store positionをcursorのobject store positionとする。
-
countが未指定なら、countを1とする。
-
countが0より大きい間:
-
directionで分岐:
- "
next
" -
found recordをrecordsのうち、以下すべてを満たす最初のレコードとする:
- "
nextunique
" -
found recordをrecordsのうち、以下すべてを満たす最初のレコードとする:
- "
prev
" -
found recordをrecordsのうち、以下すべてを満たす最後のレコードとする:
- "
prevunique
" -
temp recordをrecordsのうち、以下すべてを満たす最後のレコードとする:
temp recordが定義されていれば、found recordをrecordsのうち、temp recordのkeyに等しい最初のレコードとする。
注意: "
prevunique
"で反復すると、 "nextunique
"と同じレコードを逆順に訪れる。
- "
-
found recordが未定義なら:
-
cursorのkeyをundefinedに設定。
-
sourceがindexなら、cursorのobject store positionをundefinedに設定。
-
cursorのkey only flagがfalseなら、cursorのvalueをundefinedに設定。
-
nullを返す。
-
-
positionをfound recordのキーとする。
-
sourceがindexなら、object store positionをfound recordの値とする。
-
countを1減らす。
-
-
cursorのpositionをpositionに設定。
-
sourceがindexなら、cursorのobject store positionをobject store positionに設定。
-
cursorのkeyをfound recordのキーに設定。
-
cursorのkey only flagがfalseなら:
-
serializedを、sourceがobject storeならfound recordのvalue、 それ以外はfound recordのreferenced valueとする。
-
cursorのvalueをStructuredDeserialize(serialized, targetRealm)の結果に設定。
-
-
cursorのgot value flagをtrueに設定。
-
cursorを返す。
7. ECMAScriptバインディング
この節では、本仕様で定義されたキー値がECMAScript値に変換される方法、 ECMA Script値からキー値への変換方法、 キーパスを使ってECMAScript値から抽出・注入する方法を定義します。 この節はECMAScript言語仕様の型やアルゴリズム、いくつかのアルゴリズム規約を参照します。 [ECMA-262] ここで詳細化されていない変換については[WEBIDL]に定義されています。
7.1. 値からキーを抽出する
キーパスを使って値からキーを抽出する にはvalue、keyPath、(オプション)multiEntry flagを使い、以下の手順を実行します。 これらの手順の結果はキー、invalid、failureのいずれか、あるいは例外を投げる場合があります。
-
rを値上でキーパス評価(value、keyPath)の結果とする。例外は再スロー。
-
rがfailureなら、failureを返す。
-
multiEntry flagがfalseなら値からキーへの変換(r)の結果を、trueなら値からmultiEntryキーへの変換(r)の結果をkeyとする。例外は再スロー。
-
keyが"invalid value"または"invalid type"なら、invalidを返す。
-
keyを返す。
値上でキーパス評価にはvalue、keyPathを使い、以下の手順を実行します。結果はECMAScript値またはfailure、あるいは例外を投げる場合があります。
-
keyPathが文字列のリストなら:
-
resultを新しい
Array
オブジェクト([]
と同じ表現で生成)とする。 -
iを0とする。
-
keyPathの各itemについて:
-
keyを再帰的に値上でキーパス評価(item、value)の結果とする。
-
Assert: keyはabrupt completionではない。
-
keyがfailureなら、全体のアルゴリズムを中止してfailureを返す。
-
statusをCreateDataProperty(result, p, key)とする。
-
Assert: statusはtrue。
-
iを1増やす。
-
-
resultを返す。
注意: この再帰は1段階のみです。キーパスの配列はネストされないためです。
-
-
keyPathが空文字列なら、valueを返し、以降の手順はスキップ。
-
identifiersをstrictly splitting(keyPathをU+002E FULL STOPで分割)の結果とする。
-
identifiersの各identifierについて、該当する分岐へジャンプ:
- もしType(value)がString、かつidentifierが"
length
" -
valueをvalueの要素数に等しいNumberとする。
- valueが
Array
で、identifierが"length
" - valueが
Blob
で、identifierが"size
" -
valueをvalueの
size
に等しいNumberとする。 - valueが
Blob
で、identifierが"type
" -
valueをvalueの
type
に等しいStringとする。 - valueが
File
で、identifierが"name
" -
valueをvalueの
name
に等しいStringとする。 - valueが
File
で、identifierが"lastModified
" -
valueをvalueの
lastModified
に等しいNumberとする。 - その他
-
-
Type(value)がObjectでない場合、failureを返す。
-
hopを! HasOwnProperty(value, identifier)とする。
-
hopがfalseなら、failureを返す。
-
valueがundefinedなら、failureを返す。
-
- もしType(value)がString、かつidentifierが"
-
Assert: valueはabrupt completionでない。
-
valueを返す。
注意: 上記手順でAssertionが可能なのは、このアルゴリズムがStructuredDeserializeの出力値のみを扱い、"own"プロパティしか参照しないためです。
7.2. キーを値へ注入する
注意: この節で使われるキーパスは常に文字列で、シーケンスにはなりません。 キージェネレーターを持ち、かつ キーパスが シーケンスであるオブジェクトストアは作成できないためです。
キーが値に注入可能かを確認するにはvalueとkeyPathを使い、以下の手順を実行します。 結果はtrueまたはfalseです。
-
identifiersをstrictly splitting (keyPathをU+002E FULL STOPで分割)の結果とする。
-
Assert: identifiersは空でない。
-
identifiersの最後のitemを削除する。
-
identifiersの残りの各identifierについて、もしあれば:
注意: 上記手順でAssertionが可能なのは、このアルゴリズムがStructuredDeserializeの出力値のみを扱うためです。
キーパスを使って値にキーを注入する にはvalue、key、keyPathを使い、以下の手順を実行します:
-
identifiersをstrictly splitting (keyPathをU+002E FULL STOPで分割)の結果とする。
-
Assert: identifiersは空でない。
-
lastをidentifiersの最後のitemとし、リストから削除する。
-
identifiersの各identifierについて:
-
hopを! HasOwnProperty(value, identifier)とする。
-
hopがfalseなら:
-
oを新しい
Object
(({})
と同じ式で生成)とする。 -
statusをCreateDataProperty(value, identifier, o)とする。
-
Assert: statusはtrue。
-
-
keyValueをキーを値に変換する(key)の結果とする。
-
statusをCreateDataProperty(value, last, keyValue)とする。
-
Assert: statusはtrue。
注意: 上記手順でAssertionが可能なのは、このアルゴリズムがStructuredDeserializeの出力値のみを扱い、 かつキーが値に注入可能かを確認する手順が実行済みのためです。
7.3. キーを値へ変換する
キーを値に変換するにはkeyを使い、以下の手順を実行します。 ECMAScript値を返します。
-
typeをkeyのtypeとする。
-
valueをkeyのvalueとする。
-
typeで分岐:
- number
-
valueに等しいECMAScript Number値を返す。
- string
-
valueに等しいECMAScript String値を返す。
- date
-
-
dateをECMAScript Dateコンストラクタにvalueを一つだけ引数として渡して実行した結果とする。
-
Assert: dateはabrupt completionではない。
-
dateを返す。
-
- binary
-
-
lenをvalueの長さとする。
-
bufferをECMAScript ArrayBufferコンストラクタにlenを渡して実行した結果とする。
-
Assert: bufferはabrupt completionではない。
-
bufferの[[ArrayBufferData]]内部スロットの内容をvalueのエントリでセットする。
-
bufferを返す。
-
- array
-
-
arrayをECMAScript Arrayコンストラクタを引数なしで実行した結果とする。
-
Assert: arrayはabrupt completionではない。
-
lenをvalueのサイズとする。
-
indexを0とする。
-
indexがlen未満の間:
-
entryをキーを値に変換する(value[index])の結果とする。
-
statusをCreateDataProperty(array, index, entry)とする。
-
Assert: statusはtrue。
-
indexを1増やす。
-
-
arrayを返す。
-
7.4. 値をキーへ変換する
値をキーへ変換するには、ECMAScript値inputと(オプション)setseenを使い、以下の手順を実行します。 結果はキー、"invalid value"、"invalid type"、または例外を投げる場合があります。
-
seenが未指定なら、新しい空のsetとする。
-
seenが含むinputなら、"invalid value"を返す。
-
以下の分岐へジャンプ:
- Type(input)がNumberの場合
- inputが
Date
([[DateValue]]内部スロットを持つ)場合 - Type(input)がStringの場合
- inputがbuffer source typeの場合
-
-
inputがdetachedなら"invalid value"を返す。
-
bytesをバッファソースからバイトコピー取得(input)の結果とする。
-
- inputがArray exotic objectの場合
-
-
Append inputをseenへ追加。
-
keysを新しい空リストとする。
-
indexを0とする。
-
indexがlen未満の間:
-
hopを? HasOwnProperty(input, index)とする。
-
hopがfalseなら"invalid value"を返す。
-
keyを値をキーへ変換する(entry, seen)の結果とする。
-
ReturnIfAbrupt(key)。
-
keyが"invalid value"または"invalid type"なら、これらの手順を中止し"invalid value"を返す。
-
keyをkeysへ追加。
-
indexを1増やす。
-
- その他
-
"invalid type"を返す。
値をmultiEntryキーへ変換するにはECMAScript値inputを使い、以下の手順を実行します。 結果はキー、"invalid value"、"invalid type"、または例外を投げる場合があります。
-
inputがArray exotic objectなら:
-
seenをinputのみを含むsetとする。
-
keysを新しい空のリストとする。
-
indexを0とする。
-
indexがlen未満の間:
-
entryをGet(input, index)とする。
-
entryがabrupt completionでなければ:
-
keyを値をキーへ変換する(entry, seen)の結果とする。
-
keyが"invalid value"、"invalid type"、abrupt completionでなければ、かつkeys内にkeyと等しいitemがなければ、keyをkeysへ追加。
-
-
indexを1増やす。
-
-
それ以外の場合、値をキーへ変換する(input)の結果を返す。例外は再スロー。
注意:
これらの手順は値をキーへ変換するの手順と似ていますが、トップレベル値がArray
の場合、キーに変換できないメンバーは無視され、重複は除去されます。
例:値[10, 20, null, 30, 20]
は、array key(subkeys: 10, 20, 30)へ変換されます。
8. プライバシーに関する考慮事項
この節は規範的ではありません。
8.1. ユーザーの追跡
サードパーティのホスト(または複数のサイトへコンテンツ配信が可能なオブジェクト)は、クライアントサイドデータベースに一意の識別子を保存することで、ユーザーを複数セッションに渡り追跡し、ユーザーの活動履歴のプロフィールを構築できる。ユーザーの実IDオブジェクトを認識しているサイト(例:認証資格情報を要求するECサイトなど)と組み合わせれば、抑圧的な集団が匿名Web利用の世界よりも高精度に個人をターゲットできる可能性がある。
ユーザー追跡リスクを軽減する技術はいくつかある:
- サードパーティストレージのブロック
-
ユーザーエージェントはデータベースオブジェクトへのアクセスを、閲覧コンテキストのトップレベルドキュメントのドメイン発のスクリプトにのみ制限できる。例えば、他ドメインの
iframe
ページからのAPIアクセスを拒否することができる。 - 保存データの有効期限設定
-
ユーザーエージェントは一定期間後に自動で保存データを削除できる。
これにより、サイトはユーザーが認証(例:購入やサービスログイン)した場合のみ複数セッションをまたいだ追跡が可能となり、追跡能力が制限される。
ただし、これによりユーザーのデータが失われるリスクもある。
- 永続ストレージをクッキー同様に扱う
-
ユーザーエージェントはデータベース機能をHTTPセッションクッキーと強く関連付けてユーザーに提示すべきである。 [COOKIES]
これにより、ユーザーがこの種のストレージを慎重に扱うよう促されるかもしれない。
- サイトごとのデータベースアクセスの許可リスト化
-
ユーザーエージェントは、サイトがこの機能を利用する前にユーザーの許可を求めるようにできる。
- サードパーティストレージへの帰属記録
-
ユーザーエージェントは、第三者オリジンがデータ保存を引き起こした場合、そのオリジンを記録できる。
この情報を永続ストレージの表示に利用すれば、ユーザーはどのストレージを削除すべきか判断できる。「このドメインのデータを削除し、今後保存を禁止する」などのブロックリストと組み合わせれば、信頼するサイトのみ永続ストレージの利用を許可できる。
- 共有ブロックリスト
-
ユーザーエージェントは、ユーザーが永続ストレージのドメインブロックリストを共有できるようにすることができる。
これにより、コミュニティ全体でプライバシー保護を強化できる。
これらの提案はAPIの安易なユーザー追跡利用を防ぐが、完全な防止には至らない。同一ドメイン内では、サイトは引き続きセッション内でユーザーを追跡でき、取得した識別情報(氏名、クレジットカード番号、住所など)と共に第三者へ渡すことも可能である。複数サイトが協力すれば、依然としてプロフィールが作成され得る。
ただし、ユーザーエージェントが協力しなくても、URLのセッション識別子などを使ってユーザー追跡はある程度可能である。この技術は元々無害な用途でも利用されているが、簡単に追跡目的に転用できる。こうした情報は他サイトと共有可能であり、訪問者のIPアドレスやその他のユーザー固有データ(User-Agentヘッダや設定など)を使って複数セッションを統合したユーザープロファイルを作成できる。
8.2. クッキーの復活
永続ストレージのユーザーインターフェースで、現行仕様で説明されている永続ストレージとHTTPセッションクッキーのデータを別々に表示した場合、ユーザーは一方のみを削除してしまう可能性がある。これにより、サイトは両機能を相互バックアップとして利用でき、ユーザーのプライバシー保護の試みを無効化できてしまう。
8.3. データの機微性
ユーザーエージェントは、永続的に保存されたデータを機微なものとして扱うべきである。メール、予定表、健康記録などの機密文書がこの仕組みに保存される可能性がある。
したがって、削除時には速やかに基盤ストレージからデータを消去するよう努めるべきである。
9. セキュリティに関する考慮事項
9.1. DNSスプーフィング攻撃
DNSスプーフィング攻撃の可能性があるため、あるドメインから来たと主張するホストが本当にそのドメイン由来かどうかは保証できない。これへの対策として、ページはTLSを利用できる。TLSを使うページは、同じドメインかつTLS証明書によって識別されたページのみがデータベースへアクセスできることを保証できる。
9.2. ディレクトリ横断攻撃
一つのホスト名を複数の著者が共有する場合(例:geocities.comでコンテンツをホストするユーザー)は、すべて同じデータベースセットを共有する。
パス名によるアクセス制限機能は存在しない。共有ホストの著者は、他の著者がデータを読み取ったり上書きしたりするのが容易なため、これらの機能の利用を避けることを推奨する。
注意: 仮にパス制限機能が導入されたとしても、通常のDOMスクリプトのセキュリティモデルによって、この保護を容易に迂回しどのパスからでもデータにアクセスできてしまう。
9.3. 実装上のリスク
永続ストレージを実装する際の主なリスクは、悪意あるサイトが他ドメインの情報を読み取ること、または他ドメインへ書き込むことができてしまうことである。
第三者サイトが本来アクセスできないデータを読み取ると、情報漏洩が生じる。例えば、一つのドメインのショッピングウィッシュリストが他ドメインのターゲット広告に利用されたり、ワープロサイトが保存していた作業中の機密文書が競合会社のサイトで閲覧されるなどの危険がある。
第三者サイトが他ドメインの永続ストレージに書き込みできてしまうと、情報の偽装も同様に危険である。例えば、悪意サイトがユーザーのウィッシュリストにレコードを追加したり、セッションIDを既知のIDに設定してユーザーの行動を追跡したりできる。
したがって、本仕様で定義されたストレージキー分割モデルを厳守することがユーザーの安全のため重要である。
ホスト名やデータベース名をファイルシステムのパス構築に利用する場合、適切にエスケープ処理を施すべきである。そうしないと、攻撃者が相対パス(例:「../
」)を使って他のストレージキーの情報にアクセスできてしまう。
9.4. 永続性のリスク
実際の実装ではデータは不揮発性ストレージへ保存される。データは保存時にシリアライズされ、取得時にデシリアライズされるが、シリアライズ形式の詳細はユーザーエージェント固有である。ユーザーエージェントは時間とともにシリアライズ形式を変更する可能性が高い。例えば新しいデータ型への対応や性能向上のために形式が更新されることがある。本仕様の運用要件を満たすため、実装は古いシリアライズ形式も何らかの方法で扱う必要がある。古いデータの不適切な取り扱いはセキュリティ問題の原因となる。シリアライズされたデータにはユーザーエージェントの新しいバージョンでは有効でない仮定が含まれることもある。
具体例として、RegExp
型がある。
StructuredSerializeForStorage操作ではRegExp
オブジェクトをシリアライズできる。一般的なユーザーエージェントは正規表現を機械語命令へコンパイルし、入力データの渡し方や結果の返し方に関する仮定が含まれる。内部状態がデータベース保存時にシリアライズされてしまうと、後でデシリアライズした際に様々な問題が生じる。例えば、データの渡し方が変わっていたり、コンパイラ出力のバグがエージェント更新で修正されているのに、シリアライズされた内部状態には残っている場合がある。
ユーザーエージェントは古いデータを適切に識別・処理しなければならない。一つの方法として、シリアライズ形式にバージョン識別子を含め、古いデータが検出された場合はスクリプトから見える状態のみから内部状態を再構築する方法がある。
10. アクセシビリティに関する考慮事項
この節は規範的ではありません。
本仕様で規定されたAPIはアクセシビリティへの考慮事項が限られている:
-
コンテンツの視覚的レンダリングや色の制御は提供しない。
-
ユーザー入力を受け付ける機能は提供しない。
-
ユーザーとの対話機能は提供しない。
-
文書のセマンティクスは定義しない。
-
時間ベースの視覚メディアは提供しない。
-
時間制限は許可しない。
-
テキスト、グラフィック、その他非テキストの形態でエンドユーザー向け直接コンテンツは提供しない。
-
伝送プロトコルの定義は行わない。
APIは構造化コンテンツの保存を可能とする。テキストコンテンツは文字列として保存できる。APIには画像や音声といった非テキストコンテンツをBlob
、
File
、
ImageData
オブジェクトとして保存できるサポートがある。動的コンテンツアプリケーションの開発者は、様々な技術やニーズを持つユーザーがコンテンツにアクセス可能であることを確保するべきである。
API自体は特定の仕組みを規定しないが、構造化コンテンツの保存は多言語対応など国際化コンテンツの保存も可能にする。異なる言語の代替をレコードやレコード内の構造で保持できる。
APIはユーザーエージェントに対し、APIとの対話を可能とするユーザーインターフェースの生成を義務付けない。ユーザーエージェントはAPIを支援するUI要素を任意で提供できる。例:追加ストレージ容量が必要な場合のユーザープロンプト、特定Webサイトごとのストレージ利用の監視機能、APIストレージ用のレコード閲覧・編集・削除ツールなど。こうしたUIはアクセシビリティ支援技術を考慮して設計すべきである。例えば、グラフィック表示によるストレージ容量使用率を示すUIでは、同じデータをスクリーンリーダーなどの支援ツールにも提供する必要がある。
11. 改訂履歴
この節は規範的ではありません。
以下は、本仕様の前回公開以降の変更点の情報要約です。完全な改訂履歴はこちらで参照できます。 第一版の履歴はこの文書のRevision History、 第二版の履歴はこの文書のRevision Historyを参照してください。
-
Indexed Databaseトランザクションのクリーンアップアルゴリズムが他仕様との統合のため値を返すようになりました。 (PR #232)
-
WindowOrWorkerGlobalScope
がmixin
となったため、partial interface定義を更新しました。 (PR #238) -
databases()
メソッドを追加。 (issue #31) -
commit()
メソッドを追加。 (issue #234) -
request
属性を追加。 (issue #255) -
File
オブジェクトの非標準lastModifiedDate
プロパティの扱いを削除。 (issue #215) -
includes()
メソッドのエスケープ処理を削除。 (issue #294) -
配列キーをArray exotic objectsに限定(プロキシを禁止)。 (issue #309)
-
クローン操作時にトランザクションを一時的に非アクティブ化するようになりました。 (PR #310)
-
durability
オプションおよびdurability
属性を追加。 (issue #50) -
§ 2.7.2 トランザクションのスケジューリングをより厳密に指定。重複するスコープのread-onlyトランザクションが実行中はread/writeトランザクションの開始を禁止。 (issue #253)
-
アクセシビリティ考慮事項節を追加。 (issue #327)
-
[infra]のリストソート定義を使用。 (issue #346)
-
liveトランザクションの定義を追加。「run an upgrade transaction」をupgrade a databaseへ名称変更し意味を明確化。 (issue #408)
-
基盤ストレージから値取得時の失敗にDOMException型を指定。 (§ 6.2 オブジェクトストア取得操作, issue #423)
-
値をキーへ変換するで切断済みArrayBufferに対しinvalidを返すよう修正。 (issue #417)
-
open()
がリクエストのprocessed flagをtrueに設定するよう修正。 (issue #434) -
作成中のデータベースは
databases()
に含めないよう修正。 (issue #442) -
自動コミットはinactiveなトランザクションのみ対象であることを明確化。 (issue #436)
-
upgrade a database手順で中断されたトランザクションを正しく扱うよう修正。 (issue #436)
-
iterate a cursorの値のシリアライズにおいて、object storeはreferenced valueでなくvalueを使用するよう修正。 (issue #452)
-
source handleをcursorに追加し、内部インデックスやオブジェクトストアをスクリプトに公開しないようにした。 (issue #445)
-
Queue a database taskを定義し、Queue a taskを置換。 (issue #421)
-
databases
()に不足していたparallel手順を追加。 (issue #421) -
カーソル反復条件を明確化。(issue #450)
-
getAllRecords(options)
メソッドをIDBObjectStore
およびIDBIndex
に追加。 (issue #206) -
getAll()
およびgetAllKeys()
にdirectionオプションを追加。IDBObjectStore
およびIDBIndex
対象。 (issue #130) -
QuotaExceededError
の扱いを、例外名からDOMException
派生インターフェースとして更新。 (issue #463) -
errorはnullも有効とし、abort a transactionでnullに設定可能とした。 (issue #433)
-
requestのerrorをチェックするよう修正(upgrade transactionではなく)、open a database connection手順。 (issue #433)
-
abort()
内の冗長なトランザクション状態変更を削除。
12. 謝辞
この節は規範的ではありません。
第一版の原著者Nikunj Mehta氏、追加編集者Jonas Sicking氏、Eliot Graff氏、Andrei Popescu氏、Jeremy Orlow氏に特別な感謝を表します。
Garret Swart氏は本仕様の設計に非常に大きな影響を与えました。
Bikeshed(本仕様作成に用いた著者ツール)を作成・メンテナンスし、著作全般で助言をいただいたTab Atkins, Jr.氏に感謝します。
特別な感謝を Abhishek Shanthkumar, 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, Steffen Larssen, Steve Becker, Tobie Langel, Victor Costan, Xiaoqian Wu, Yannic Bonenberger, Yaron Tausky, Yonathan Randolph, そして Zhiqiang Zhang, 仕様改善につながるフィードバック・提案をくださった皆様に感謝します。