インデックス付きデータベース API 3.0

W3C 作業草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/WD-IndexedDB-3-20250813/
最新の公開バージョン:
https://www.w3.org/TR/IndexedDB/
編集者草案:
https://w3c.github.io/IndexedDB/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/IndexedDB-3/
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/IndexedDB
フィードバック:
GitHub
編集者:
(Microsoft)
以前の編集者:
Ali Alabbas (以前 Microsoft に所属)
Joshua Bell (以前 Google に所属)

概要

この文書は、単純な値および階層構造のオブジェクトを保持する レコードのデータベース用 API を定義します。各レコードはキー と何らかの値で構成されます。さらに、データベースは保存するレコードに対するインデックスを 維持します。アプリケーション開発者は API を直接使用して、 キーまたはインデックスを使用してレコードを検索します。クエリ言語を この API の上に構築できます。インデックス付きデータベースは、 永続的な B-tree データ構造を使用して実装できます。

この文書のステータス

この節では、この文書の公開時点におけるステータスについて説明します。現在の W3C 公開文書の一覧およびこの 技術報告書の最新版は、W3C 標準および草案一覧で確認できます。

この文書は、 Web Applications Working Group によって 勧告 トラックを使用して作業草案として公開されました。 作業草案としての公開は、 W3C およびそのメンバーによる承認を意味するものではありません。

これは草案文書であり、 いつでも更新、置換、 または他の文書によって廃止される可能性があります。 この文書を作業中の文書以外として引用することは適切ではありません。

この文書は、W3C 特許ポリシーの下で活動するグループによって作成されました。W3C は、このグループの成果物に関連して行われた特許開示の公開リストを管理しており、そのページには 特許を開示するための手順も含まれています。ある個人が、必須クレームを含むとその個人が 考える特許について実際の知識を有する場合、その個人はW3C 特許ポリシーの第6節に従ってその情報を開示しなければなりません。

この文書には、 2023年11月3日付 W3C プロセス文書が適用されます。

これは Indexed Database API の第3版です。 単に「Indexed Database API」という題名の第1版は、 2015年1月8日に W3C 勧告となりました。 「Indexed Database API 2.0」という題名の第2版は、 2018年1月30日に W3C 勧告となりました。

Indexed Database API 3.0 は Indexed Database API 2.0 に取って代わることを意図しています。

1. 序論

ユーザーエージェントは、Web アプリケーションのオフラインデータ要件を 満たすために、多数のオブジェクトをローカルに保存する必要があります。[WEBSTORAGE] は、キーとそれに対応する値のペアを保存するのに有用です。 しかし、キーを順序どおりに取得すること、値を効率的に 検索すること、または1つのキーに対して重複する値を保存することはできません。

この仕様は、高度な キーと値のデータ管理を実行するための具体的な API を提供します。これは、ほとんどの高度な クエリプロセッサの中核をなすものです。これは、トランザクションデータベースを使用して キーとそれに対応する値(キーごとに1つ以上)を保存し、 キーを決定論的な順序で走査する手段を提供することで実現されます。これは 多くの場合、挿入および削除だけでなく 非常に多数のデータレコードの順序走査にも効率的とされる永続的な B-tree データ構造の使用によって 実装されます。

次の例では、API を使用して "library" データベースにアクセスします。このデータベースには "books" オブジェクトストアがあり、書籍レコードをその "isbn" プロパティを 主キーとして保存します。

書籍レコードには "title" プロパティがあります。この例では、書籍タイトルが 一意であることを意図的に要求しています。コードは、unique オプションを設定した "by_title" という名前のインデックスを作成することで、これを強制します。 このインデックスはタイトルによって書籍を検索するために使用され、一意でない タイトルを持つ書籍の追加を防止します。

書籍レコードには "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() {
  // すべてのリクエストが成功し、トランザクションがコミットされた。
};

次の例では、インデックスを使用してタイトルによってデータベース内の1冊の書籍を 検索します。

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);
  }
};

次の例は、リクエストが失敗したときにエラーを処理する1つの方法を示します。

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();

将来、データベースが拡張され、他のオブジェクトストアやインデックスを含むようになる可能性があります。次の 例は、古いバージョンからの移行を処理する1つの方法を示します。

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になる。
};
1つのデータベースを複数のクライアント(ページおよびワーカー)が 同時に使用できます — トランザクションによって、読み書きの際に競合しないことが保証されます。 新しいクライアントがデータベースを(upgradeneeded イベントを介して)アップグレードしようとしても、他のすべてのクライアントが 現在のバージョンのデータベースへの接続を閉じるまでは実行できません。

新しいクライアントによるアップグレードを妨げないようにするため、クライアントは versionchange イベントを待ち受けることができます。これは、別のクライアントがデータベースを アップグレードしようとしているときに発火します。これを続行できるようにするには、versionchange イベントに対し、最終的にこのクライアントのデータベースへの接続を閉じることになる 処理を行います。

これを行う1つの方法は、ページを再読み込みすることです。

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. 構成要素

名前は、DOMString と同等の文字列です。 つまり、空文字列を含む、任意の長さの16ビットコード単位の任意のシーケンスです。 名前は常に、 16ビットコード単位の不透明なシーケンスとして比較されます。

注記: その結果、名前の比較は、 大文字と小文字の違いだけでなく、 正規化形式、制御文字の有無、その他の Unicode テキストのわずかな違いにも影響されます。[Charmod-Norm]

実装が任意の文字列をサポートしないストレージ機構を使用する場合、 実装はエスケープ機構 またはそれに類するものを使用して、提供された名前を保存可能な文字列へ マッピングできます。

リスト names からソート済み 名前リストを作成するには、次の手順を実行します。

  1. sorted を、コード単位小なり アルゴリズムによって昇順にソートされた names とします。

  2. sorted に関連付けられた新しい DOMStringList を返します。

詳細 これは、sort() メソッドを Array (要素が String であるもの)に対して使用した場合と一致します。 この順序付けでは、各文字列の16ビットコード単位を比較し、 非常に効率的で、一貫性があり、決定論的な ソート順を生成します。結果のリストは、特定の アルファベット順または辞書順とは一致しません。特に、サロゲートペアで 表されるコードポイントではそうです。

2.1. データベース

各ストレージ キーには、関連付けられたデータベースの集合があります。 データベースには0個以上のオブジェクトストアがあり、 データベースに保存されるデータを保持します。

データベースには、それを 特定のストレージキー内で識別する名前があります。 名前は名前であり、 データベースの存続期間中は一定です。

データベースにはバージョンがあります。データベースが 最初に 作成されたとき、そのバージョン は0(ゼロ)です。

注記: 各データベースは一度に1つのバージョンのみを持ちます。 データベースが 複数のバージョンで同時に存在することはできません。 バージョンを変更する唯一の方法は、アップグレード トランザクションを使用することです。

データベースには、関連付けられた アップグレードトランザクションが最大で1つあり、 これは null またはアップグレードトランザクションのいずれかで、初期値は null です。

2.1.1. データベース接続

スクリプトはデータベースと 直接やり取りしません。代わりに、 スクリプトは接続を介して間接的にアクセスします。 接続オブジェクトは、 そのデータベースのオブジェクトを 操作するために使用できます。また、これは そのデータベースの トランザクションを取得する 唯一の方法でもあります。

データベースを開く操作によって 接続が作成されます。 あるデータベースに対しては、 任意の時点で複数の接続が存在する場合があります。

接続は、その接続が開かれたグローバルスコープの ストレージ キーに関連付けられたデータベースにのみアクセスできます。

注記: これは Document の domain の変更による影響を受けません。

接続にはバージョンがあり、これは 接続が作成されたときに設定されます。 アップグレードが中止される場合を除き、 接続の 存続期間中は一定のままです。その場合、 これはデータベースの以前のバージョンに設定されます。 接続が閉じられた後は、 バージョンは 変更されません。

各接続にはクローズ保留フラグがあり、その初期値は false です。

接続が最初に 作成されたとき、その接続は開いた 状態です。接続は、いくつかの方法で閉じることができます。 接続が作成された実行コンテキストが 破棄された場合(たとえば、ユーザーがその ページから移動したことによる場合)、接続は閉じられます。接続は、 データベース接続を閉じる手順を使用して明示的に閉じることもできます。 接続が閉じられると、まだ true に設定されていない場合、そのクローズ保留フラグは常に true に設定されます。

接続は、例外的な 状況ではユーザーエージェントによって閉じられる場合があります。たとえば、ファイルシステムへのアクセスの喪失、 権限の変更、またはストレージキーの ストレージの消去による場合です。これが発生した場合、 ユーザーエージェントは、接続と forced flag を true に設定して、データベース接続を閉じる手順を実行しなければなりません。

接続にはオブジェクトストア集合があり、これは 接続が作成されたときに、関連付けられた データベース内のオブジェクト ストアの集合で初期化されます。 アップグレードトランザクションが ライブである場合を除き、 集合の内容は一定のままです。

接続の親を取得するアルゴリズムは null を返します。

型が versionchange のイベントは、 データベースをアップグレードまたは削除しようとした場合、 開いている接続に対して 発火されます。これにより、接続には、 アップグレードまたは削除を続行できるように 閉じる機会が与えられます。

型が close のイベントは、接続が異常に 閉じられた場合、接続に対して発火されます。

2.2. オブジェクトストア

オブジェクトストアは、 データベースにデータを 保存するための主要なストレージ機構です。

各データベースにはオブジェクト ストアの集合があります。オブジェクト ストアの集合は変更できますが、それはアップグレード トランザクションを使用する場合に限られます。 すなわち、upgradeneeded イベントへの応答として行います。新しい データベースが作成されたとき、オブジェクトストアは含まれていません。

オブジェクトストアには、 オブジェクトストアに保存されたデータを保持するレコードのリストがあります。各レコードは、 キーと値で構成されます。このリストはキーに従って 昇順にソートされます。 あるオブジェクト ストア内に同じキーを持つ複数のレコードが存在することは決してありません。

オブジェクトストアには名前があり、これは名前です。 どの時点においても、その名前は、 それが属するデータベース内で 一意です。

オブジェクトストアは、任意で キーパスを持ちます。 オブジェクトストアにキーパスがある場合、インラインキーを使用するといいます。 そうでない場合は、アウトオブラインキーを使用するといいます。

オブジェクトストアは、任意で キージェネレーターを持ちます。

オブジェクトストアは、レコードのキーを 次の3つのソースのいずれかから導出できます。

  1. キージェネレーター。 キージェネレーターは、キーが必要になるたびに単調増加する 数値を生成します。

  2. キーはキーパスによって導出できます。

  3. オブジェクトストアに値を保存するときに、 キーを明示的に指定することもできます。

2.2.1. オブジェクトストアハンドル

スクリプトはオブジェクト ストアと直接やり取りしません。代わりに、 トランザクション内で、 スクリプトは オブジェクトストア ハンドルを介して間接的にアクセスします。

オブジェクトストア ハンドルには、関連付けられたオブジェクトストア と、関連付けられたトランザクションがあります。異なる トランザクション内では、 複数のハンドルを同じオブジェクト ストアに関連付けることができますが、 1つのトランザクション内で特定のオブジェクト ストアに関連付けられるオブジェクトストアハンドルは 1つだけでなければなりません。

オブジェクトストア ハンドルにはインデックス集合があり、これは オブジェクトストアハンドルが 作成されたときに、関連付けられた オブジェクトストアを参照するインデックスの集合で 初期化されます。 アップグレード トランザクションがライブである場合を除き、 集合の内容は一定のままです。

オブジェクトストア ハンドルには名前があり、これは オブジェクトストアハンドルが 作成されたときに、関連付けられた オブジェクトストアの名前で 初期化されます。アップグレードトランザクションがライブである場合を除き、名前は一定のままです。

2.3. 値

各レコードには値が関連付けられています。ユーザーエージェントは、 あらゆるシリアライズ可能オブジェクトをサポートしなければなりません。これには、 String プリミティブ値や Date オブジェクトのような単純な型に加えて、 Object および Array インスタンス、File オブジェクト、Blob オブジェクト、ImageData オブジェクトなどが含まれます。レコードの値は、 参照ではなく値によって保存および取得されます。後から値を変更しても、 データベースに保存されたレコードには影響しません。

レコードの値は、 StructuredSerializeForStorage 操作によって出力されるRecordsです。

2.4. キー

インデックス付き データベースに保存されたレコードを効率的に取得するため、各レコードは、 そのキーに従って 整理されます。

キーには、次のいずれかである関連付けられた型があります。 number、 date、 string、 binary、 または array。

キーには、関連付けられた値もあり、 これは 次のいずれかです。 型が number または date の場合は unrestricted double、 型が string の場合は DOMString、 型が binary の場合はバイト シーケンス、 または、型が array の場合は他のキーのリストです。

ECMAScript [ECMA-262] の値は、 値をキーに変換する手順に従ってキーへ 変換できます。

注記: 次の ECMAScript 型は有効なキーです。

その他の ECMAScript 値をキーに 変換しようとすると失敗します。

配列キーとは、キーのうち、型が array であるものです。 配列キーのサブキーとは、 その 配列キーの値の項目です。

a と b の2つの キーを比較するには、次の手順を実行します。

  1. ta を a の型 とします。

  2. tb を b の型 とします。

  3. ta が tb と等しくない場合、次の手順を実行します。

    1. ta が array の場合、1を返します。

    2. tb が array の場合、-1を返します。

    3. ta が binary の場合、1を返します。

    4. tb が binary の場合、-1を返します。

    5. ta が string の場合、1を返します。

    6. tb が string の場合、-1を返します。

    7. ta が date の場合、1を返します。

    8. 表明: tb は date です。

    9. -1を返します。

  4. va を a の値とします。

  5. vb を b の値とします。

  6. ta に応じて切り替えます。

    number
    date
    1. va が vb より大きい場合、1を返します。

    2. va が vb より小さい場合、-1を返します。

    3. 0を返します。

    string
    1. va が vb よりコード 単位小なりである場合、 -1を返します。

    2. vb が va よりコード 単位小なりである場合、 1を返します。

    3. 0を返します。

    binary
    1. va が vb よりバイト小なりである場合、 -1を返します。

    2. vb が va よりバイト小なりである場合、 1を返します。

    3. 0を返します。

    array
    1. length を、va のサイズと vb のサイズのうち小さい方とします。

    2. i を0とします。

    3. i が length より小さい間、次を実行します。

      1. c を、va[i] と vb[i] を用いて再帰的に2つの キーを比較する結果とします。

      2. c が0でない場合、c を返します。

      3. i を1増加させます。

    4. va のサイズが vb のサイズより大きい場合、1を返します。

    5. va のサイズが vb のサイズより小さい場合、-1を返します。

    6. 0を返します。

キー a は、 a と b を用いて2つの キーを比較する結果が1である場合、キー b より大きいです。

キー a は、 a と b を用いて2つの キーを比較する結果が-1である場合、キー b より小さいです。

キー a は、 a と b を用いて2つのキーを比較する 結果が0である場合、キー b と等しいです。

注記: 上記の規則の結果、負の無限大がキーとして可能な 最小値です。 Number キーは date キーより小さくなります。 Date キーは string キーより小さくなります。 String キーは binary キーより小さくなります。 Binary キーは array キーより小さくなります。 キーに可能な最大値はありません。 これは、最大候補となる任意のキーに 別のキーを続けた配列がさらに大きくなるためです。

注記: binary キーの要素は、符号付き byte 値(範囲は -128 から127まで)ではなく、符号なしバイト値 (範囲は0から255まで)として比較されます。

2.5. キーパス

キーパスとは、値から キーを抽出する方法を定義する 文字列または文字列のリストです。有効なキーパスは、次のいずれかです。

注記: キーパス内にスペースを含めることはできません。

キーパスの値は、 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 のレコードが含まれます。

インデックス内のレコードには参照値があるといいます。 これは、インデックスのレコードの値と等しいキーを持つ、 インデックスの参照されるオブジェクトストア内のレコードの値です。そのため、上の例では、 キーが Y、値が X である インデックス内のレコードは、 A という参照 値を持ちます。

前の例では、キー "Alice"、値 123 のインデックス内のレコードは、 { name: "Alice", title: "CEO" } という参照 値を持ちます。

注記: インデックス内の各レコードは、インデックスの参照される オブジェクトストア内の1つ、かつ1つだけのレコードを参照します。ただし、 インデックス内の複数のレコードがオブジェクト ストア内の同じレコードを参照することがあります。また、オブジェクトストア内の あるレコードを参照するレコードがインデックスに1つも存在しない場合もあります。

インデックス内のレコードは、 常にレコードのキーに従って ソートされます。 ただし、オブジェクトストアとは異なり、あるインデックスには 同じキーを持つ複数のレコードを含めることができます。このようなレコードはさらに、 インデックスのレコードの値 (すなわち、参照されるオブジェクトストア内のレコードのキー)に従ってソートされます。

インデックスには名前があり、 これは名前です。 どの時点においても、その名前は インデックスの参照されるオブジェクトストア内で一意です。

インデックスには一意 フラグがあります。このフラグが true の場合、インデックス内の2つのレコードが 同じキーを持たないことをインデックスが強制します。インデックスの参照されるオブジェクト ストア内のレコードを挿入または変更しようとした際に、 レコードの新しい値に対するインデックスのキーパスの評価結果が インデックス内にすでに存在する場合、オブジェクトストアに対する その変更は失敗します。

インデックスにはmultiEntry フラグがあります。このフラグは、 インデックスのキーパスを評価した結果が配列キーになった場合の、 インデックスの動作に影響します。そのmultiEntry フラグが false の場合、キーが配列 キーである単一のレコードがインデックスに追加されます。 そのmultiEntry フラグが true の場合、 サブキーごとに1つのレコードが インデックスに追加されます。

2.6.1. インデックスハンドル

スクリプトはインデックスと直接やり取りしません。代わりに、 トランザクション内で、 スクリプトはインデックス ハンドルを介して間接的にアクセスします。

インデックスハンドルには、関連付けられた インデックスと、 関連付けられたオブジェクトストアハンドルがあります。トランザクションは、 インデックスハンドルに関連付けられたオブジェクト ストアハンドルのトランザクションです。異なるトランザクションでは、 複数のハンドルを同じインデックスに 関連付けることができますが、1つの トランザクション内で特定の インデックスに関連付けられるインデックス ハンドルは1つだけでなければなりません。

インデックスハンドルには名前があり、これは インデックスハンドルが作成されたときに、関連付けられたインデックスの 名前で初期化されます。 アップグレード トランザクションがライブである場合を除き、名前は一定のままです。

2.7. トランザクション

トランザクションは、 データベース内のデータとやり取りするために 使用されます。データベースからデータを読み取る場合、または データベースに書き込む場合は常にトランザクションを使用して行われます。

トランザクションは、 アプリケーションやシステムの障害からある程度保護します。トランザクションは、複数のデータ レコードを保存したり、特定のデータレコードを条件付きで変更したりするために使用できます。 トランザクションは、 原子的かつ永続的なデータアクセス およびデータ変更操作の集合を表します。

すべてのトランザクションは接続を通じて作成され、これが トランザクションの接続です。

トランザクションには スコープがあり、これはトランザクションがやり取りできるオブジェクトストアの集合です。

注記: トランザクションがアップグレードトランザクションでない限り、そのトランザクションのスコープは 固定されたままです。

2つのトランザクションは、 いずれかのオブジェクトストアが両方のトランザクションのスコープに含まれる場合、重複するスコープを持ちます。

トランザクションには、 そのトランザクションで実行できるやり取りの種類を決定するモードがあります。モードは トランザクションの作成時に設定され、トランザクションの存続期間中は 固定されたままです。トランザクションのモードは、次の いずれかです。

"readonly"

トランザクションはデータの読み取りのみが許可されます。この種類のトランザクションでは 変更を行うことはできません。この利点は、 複数の読み取り専用トランザクションが、それらのスコープが重複していても、すなわち 同じオブジェクトストアを 使用していても、同時に開始できることです。 この種類のトランザクションは、データベースが開かれた後は いつでも作成できます。

"readwrite"

トランザクションは、既存のオブジェクトストアからデータを読み取り、変更し、削除することが 許可されます。ただし、オブジェクトストアとインデックスを 追加または削除することはできません。複数の "readwrite" トランザクションは、 それらのスコープが 重複している場合、 トランザクションの途中で互いのデータを変更できることになるため、同時に開始することはできません。 この種類のトランザクションは、 データベースが開かれた後はいつでも作成できます。

"versionchange"

トランザクションは、既存のオブジェクトストアからデータを読み取り、変更し、削除できるほか、 オブジェクトストアとインデックスを作成および削除することもできます。 これを実行できる唯一の種類のトランザクションです。この種類のトランザクションは手動では作成できず、 代わりに upgradeneeded イベントが発火されたときに自動的に作成されます。

トランザクションには 永続性ヒントがあります。これは、トランザクションをコミットするときに パフォーマンスと永続性のどちらを優先するかをユーザーエージェントに示すヒントです。永続性ヒントは、 次のいずれかです。

"strict"

ユーザーエージェントは、すべての未処理の変更が永続ストレージ媒体に 正常に書き込まれたことを確認した後にのみ、トランザクションが正常にコミットされたと見なしてもよいものとします。

"relaxed"

ユーザーエージェントは、すべての未処理の変更がオペレーティングシステムに書き込まれた時点で、 その後の検証を行わずに、トランザクションが正常にコミットされたと見なしてもよいものとします。

"default"

ユーザーエージェントは、ストレージ バケットについて、その既定の永続性動作を使用すべきです。別途指定されていない場合、 トランザクションではこれが既定値です。

注記: 一般的な実装では、"strict" は、complete イベントが発火される前に、オペレーティングシステムの I/O バッファーをフラッシュするようユーザーエージェントに示すヒントです。 これにより、その後オペレーティングシステムがクラッシュした場合や電源が失われた場合でも変更が永続化される確実性が高まりますが、 バッファーのフラッシュにはかなりの時間がかかり、携帯機器では バッテリーを消費する可能性があります。

Web アプリケーションには、キャッシュや頻繁に変更されるレコードなどの一時的なデータには "relaxed" を使用し、データ損失のリスクを減らすことがパフォーマンスや電力への影響より重要な場合には "strict" を使用することが推奨されます。 実装には、アプリケーションからの永続性ヒントと ユーザーおよび機器への影響を比較衡量することが推奨されます。

トランザクションは任意で クリーンアップイベントループを持ち、 これはイベントループです。

トランザクションには、 そのトランザクションに対して行われた保留中のリクエストのリクエストリストがあります。

トランザクションには、 トランザクションが中止された場合に設定されるエラーがあります。

注記: 実装者は、値 "null" が abort() から設定されるため、エラーと見なされることに留意する必要があります。

トランザクションの親を取得する アルゴリズムは、トランザクションの接続を返します。

読み取り専用トランザクションとは、 モードが "readonly" であるトランザクションです。

読み書きトランザクションとは、 モードが "readwrite" であるトランザクションです。

2.7.1. トランザクションのライフサイクル

トランザクションには 状態があり、これは次の いずれかです。

アクティブ

トランザクションは、最初に作成されたとき、および トランザクションに関連付けられたリクエストからのイベントのディスパッチ中にこの状態になります。

トランザクションがこの状態にあるときは、新しいリクエストを トランザクションに対して行うことができます。

非アクティブ

トランザクションは、作成後に制御がイベント ループへ戻った後、およびイベントがディスパッチされていないときにこの状態になります。

トランザクションがこの状態にあるときは、トランザクションに対してリクエストを行うことはできません。

コミット中

トランザクションに関連付けられたすべてのリクエストが完了すると、 トランザクションはコミットしようとするときにこの状態になります。

トランザクションがこの状態にあるときは、トランザクションに対してリクエストを行うことはできません。

完了

トランザクションがコミットまたは中止されると、この状態になります。

トランザクションがこの状態にあるときは、トランザクションに対してリクエストを行うことはできません。

トランザクションは短期間で終了することが期待されます。これは、以下で説明する 自動 コミット機能によって促進されます。

注記: 作者はトランザクションを長時間ライブに保つこともできますが、 この使用パターンはユーザー体験の低下につながる可能性があるため、 推奨されません。

トランザクションの 存続期間は次のとおりです。

  1. トランザクションはスコープと モードを指定して作成されます。トランザクションが作成されたとき、その 状態は 最初はアクティブです。

  2. 実装が、以下で定義されるトランザクションの スコープおよびモードの制約を 強制できるようになったとき、実装は トランザクションを非同期に開始するため、データベースタスクをキューに入れなければなりません。

    トランザクションが開始されると、実装は トランザクションに対して行われたリクエストの実行を開始できます。 リクエストは、トランザクションに対して行われた順序で 実行されなければなりません。同様に、それらの結果も、特定のトランザクションに対して リクエストが行われた順序で返されなければなりません。異なるトランザクションの リクエストの結果が返される順序については保証されません。

    注記: トランザクションのモードにより、 異なるトランザクションに対して行われた2つの リクエストは、結果としてデータベースに保存されるデータに影響を与えることなく、 任意の順序で実行できます。

  3. トランザクションに関連付けられた各リクエストが処理されると、 success または error イベントが 発火されます。イベントがディスパッチされている間、トランザクションの 状態は アクティブに設定され、 トランザクションに対して追加のリクエストを行えるようになります。 イベントのディスパッチが完了すると、トランザクションの 状態は 再び非アクティブに設定されます。

  4. トランザクションは、完了する前であればいつでも中止できます。 トランザクションが現在アクティブでない場合や、まだ 開始されていない場合でも同様です。

    abort() を明示的に呼び出すと 中止が開始されます。 スクリプトによって処理されなかった 失敗したリクエストの後にも中止が開始されます。

    トランザクションが中止された場合、実装はそのトランザクション中に データベースに加えられた変更をすべて元に戻さなければなりません。 これには、オブジェクトストアの内容に対する変更だけでなく、 オブジェクトストアおよびインデックスの追加と削除も含まれます。

  5. トランザクションに対して行われたすべてのリクエストが 完了し、返された結果が処理され、新しいリクエストが トランザクションに対して行われておらず、かつトランザクションが 中止されていない場合、実装は非アクティブなトランザクションをコミットしようとしなければなりません。

    commit() を明示的に呼び出すと、リクエスト結果がスクリプトによって 処理されるのを待たずにコミットが 開始されます。

    コミット時には、トランザクションの状態が コミット中に設定されます。 実装は、トランザクションに対して行われたリクエストによって データベースに加えられた変更を 原子的に書き込まなければなりません。すなわち、すべての変更が 書き込まれなければならず、またはディスク書き込みエラーなどのエラーが発生した場合には、 実装は変更を一切データベースに書き込んではならず、 トランザクションを 中止する手順に従います。

  6. トランザクションがコミットまたは中止されると、 その状態は 完了に設定されます。

実装は、トランザクションがアクティブであるときは常に、リクエストを トランザクションに対して行うことを許可しなければなりません。 これは、トランザクションがまだ 開始されていない場合でも同様です。 トランザクションが 開始されるまでは、 実装はこれらの リクエストを実行してはなりません。ただし、実装は リクエストとその順序を記録しておかなければなりません。

トランザクションは、 作成されてから、その状態が完了に設定されるまでライブであるといいます。

Indexed Database トランザクションをクリーンアップするには、次の 手順を実行します。 いずれかのトランザクションがクリーンアップされた場合は true を返し、それ以外の場合は false を返します。

  1. 現在の イベントループと一致するクリーンアップイベント ループを持つトランザクションが存在しない場合、false を返します。

  2. 現在のイベント ループと一致するクリーンアップイベント ループを持つ各トランザクション transaction について:

    1. transaction の状態を非アクティブに設定します。

    2. transaction のクリーンアップイベントループをクリアします。

  3. true を返します。

注記: これらの手順は [HTML] によって呼び出されます。これにより、 スクリプトによる transaction() の呼び出しによって作成されたトランザクションが、 スクリプトを呼び出したタスクの完了後に非アクティブ化されることが保証されます。 この手順は各トランザクションについて最大1回実行されます。

型が complete のイベントは、 正常にコミットされたトランザクションに対して発火されます。

型が abort のイベントは、 中止されたトランザクションに対して発火されます。

2.7.2. トランザクションのスケジューリング

次の制約は、トランザクションをいつ開始できるかを定義します。

実装は追加の制約を課してもかまいません。たとえば、実装には、重複しない 読み書きトランザクションを並列に開始することは要求されず、または 開始されたトランザクションの数に制限を課してもかまいません。

注記: これらの制約から、次のことが導かれます。

2.7.3. アップグレードトランザクション

アップグレード トランザクションとは、モードが "versionchange" であるトランザクションです。

接続が データベースに対して開かれた後、 現在のバージョンより大きいバージョンが指定されている場合、 データベースを アップグレードする手順を実行すると、アップグレード トランザクションが自動的に作成されます。このトランザクションは、 upgradeneeded イベント ハンドラー内でアクティブになります。

注記: アップグレード トランザクションにより、データベース内のオブジェクトストアおよび インデックスを作成、名前変更、および 削除できます。

アップグレード トランザクションは排他的です。データベース 接続を開く手順により、アップグレード トランザクションがライブである間は、データベースへの接続が1つだけ 開いていることが保証されます。 upgradeneeded イベントは、同じデータベースへの他のすべての接続が閉じられるまで発火されず、 したがってアップグレード トランザクションも開始されません。これにより、 それ以前のすべてのトランザクションが完了していることが保証されます。

アップグレード トランザクションがライブである限り、 同じデータベースへの追加の 接続を開こうとする試みは遅延され、 同じ接続で transaction() を呼び出して追加の トランザクションを開始しようとすると、 例外がスローされます。これにより、他の トランザクションが同時にライブにならないことが保証され、さらに アップグレード トランザクションがライブである限り、同じデータベースに対して 新しいトランザクションがキューに入れられないことも保証されます。

これによりさらに、アップグレードトランザクションが完了すると、 データベース内のオブジェクトストアおよびインデックスの集合は、その後のすべての接続および トランザクションの存続期間中、一定のままとなることが保証されます。

2.8. リクエスト

データベースに対する各非同期操作は、 リクエストを使用して行われます。各 リクエストは1つの 操作を表します。

リクエストには処理済みフラグがあり、 初期値は false です。 このフラグは、リクエストに関連付けられた操作が実行されたときに true に設定されます。

リクエストは、その処理済みフラグが true のときに処理済みであるといいます。

リクエストには完了フラグがあり、 初期値は false です。 このフラグは、リクエストに関連付けられた操作の結果が利用可能になったときに true に設定されます。

リクエストにはソースオブジェクトがあります。

リクエストには結果とエラーがあり、 どちらもその完了フラグが true になるまではアクセスできません。

リクエストにはトランザクションがあり、 初期値は null です。 これは、リクエストを非同期に実行する手順を使用して、 リクエストがトランザクションに対して行われたときに設定されます。

リクエストが行われると、その完了 フラグが false に設定された新しいリクエストが返されます。 リクエストが正常に完了すると、その 完了フラグは true に設定され、その結果はリクエストの結果に設定され、 型が success のイベントが リクエストに対して発火されます。

操作の実行中にエラーが発生した場合、リクエストの完了フラグは true に設定され、リクエストのエラーは そのエラーに設定され、型が error のイベントがリクエストに対して発火されます。

リクエストの親を取得する アルゴリズムは、リクエストの トランザクションを返します。

注記: リクエストは通常再利用されませんが、例外があります。 カーソルが反復されると、 反復の成功は、カーソルを開くために使用されたのと同じリクエストオブジェクトで報告されます。 また、 アップグレード トランザクションが必要な場合、同じオープンリクエストが、upgradeneeded イベントと、オープン操作自体の最終結果の両方に使用されます。場合によっては、 リクエストの完了 フラグが false に設定され、その後再び true に設定され、 結果が変化したり、代わりにエラーが設定されたりすることがあります。

2.8.1. オープンリクエスト

オープンリクエストは、 接続を開くとき、または データベースを削除するときに使用される特殊な種類のリクエストです。 success および error イベントに加えて、 blocked および upgradeneeded イベントが、 進行状況を示すためにオープン リクエストに対して発火される場合があります。

オープン リクエストのソースは 常に null です。

オープン リクエストのトランザクションは、 upgradeneeded イベントが発火されていない限り null です。

オープン リクエストの親を取得するアルゴリズムは null を返します。

2.8.2. 接続キュー

オープンリクエストは、 接続 キューで処理されます。 このキューには、ある ストレージ キーと名前に関連付けられたすべてのオープンリクエストが含まれます。 接続キューに追加されたリクエストは 順番に処理され、各リクエストは次のリクエストが処理される前に 完了まで実行されなければなりません。オープンリクエストは他の接続によってブロックされる場合があり、 リクエストが完了して 以降のリクエストを処理できるようになるには、それらの 接続を閉じる必要があります。

注記: リクエストは特定の 閲覧コンテキストの外部で処理されるため、接続キューは イベントループに関連付けられたタスクキューではありません。 完了したオープン リクエストへのイベントの配信は、引き続き リクエストが行われたコンテキストのイベント ループに関連付けられたタスク キューを経由します。

2.9. キー範囲

オブジェクト ストアおよびインデックスから、キーまたはキー範囲を使用してレコードを取得できます。キー範囲とは、 キーに使用される何らかのデータ型上の連続区間です。

キー範囲には、関連付けられた下限(null または キー)があります。

キー範囲には、関連付けられた上限(null または キー)があります。

キー範囲には、関連付けられた下限オープンフラグがあります。 別途記載されていない限り false です。

キー範囲には、関連付けられた上限オープンフラグがあります。 別途記載されていない限り false です。

キー範囲は、 上限と等しい下限を持つことができます。 キー範囲は、その上限より大きい下限を 持ってはなりません。

key のみを含むキー範囲は、 下限と 上限の両方が key と等しいものです。

key は、次の両方の 条件が満たされる場合に、range というキー 範囲内にあります。

注記:

境界のないキー 範囲とは、 下限と 上限の両方が null に等しいキー範囲です。すべての キーは境界のないキー範囲内にあります。

value と任意の null disallowed flag を用いて値を キー範囲に変換するには、 次の手順を実行します。

  1. value がキー 範囲である場合、value を返します。

  2. value が undefined または null の場合、null disallowed flag が true なら "DataError" DOMException をスローし、それ以外の場合は 境界のない キー範囲を返します。

  3. key を、value を用いて値をキーに変換する結果とします。 例外があれば再スローします。

  4. key が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  5. key のみを含むキー範囲を返します。

潜在的に 有効なキー範囲とは、キー範囲に変換可能な型を持つ ECMAScript 値です。 特定の値がキー範囲に正常に変換されるかどうか、すなわち、その値を用いて値をキー範囲に 変換すると例外がスローされるかどうかは関係ありません。

注記: たとえば、切り離された BufferSourceは、値をキー 範囲に変換するで使用すると例外をスローする潜在的に有効なキー 範囲です。

ECMAScript value について、値が潜在的に有効なキー範囲であるかどうかを判定するには、 次の手順を実行します。

  1. value がキー 範囲である場合、true を返します。

  2. key を、value を用いて値をキーに変換する結果とします。

  3. key が "invalid type" である場合、false を返します。

  4. それ以外の場合は true を返します。

注記: getAll() および getAllKeys() メソッドは、その第1引数を処理するために潜在的に有効なキー範囲であるを使用します。 引数が潜在的に有効なキー範囲である場合、getAll() および getAllKeys() は、その引数を用いて値をキー範囲に変換するを実行します。 それ以外の場合、第1引数には IDBGetAllOptions が使用されます。

getAll() および getAllKeys() は、値をキーに 変換するで使用したときに "invalid value" を返す Date、 Array、 および ArrayBuffer の第1引数に対して例外をスローします。 たとえば、NaN の Date を第1引数として getAll() を実行すると、既定値を持つ IDBGetAllOptions 辞書を正常に使用するのではなく、例外がスローされます。

2.10. カーソル

カーソルは、 インデックスまたはオブジェクトストア内のレコード範囲を特定の 方向に反復するために使用されます。

カーソルにはソース ハンドルがあり、これはカーソルを開いたインデックス ハンドルまたはオブジェクト ストアハンドルです。

カーソルにはトランザクションがあり、 これはカーソルのソースハンドルのトランザクションです。

カーソルには、 インデックスまたはオブジェクトストア内のレコードの範囲があります。

カーソルにはソースがあり、これは カーソルのソース ハンドルからのインデックスまたはオブジェクトストアです。 カーソルのソースは、 カーソルが反復しているレコードに、 どのインデックスまたは オブジェクトストアが関連付けられているかを示します。 カーソルのソース ハンドルがインデックス ハンドルである場合、 カーソルのソースは インデックス ハンドルに関連付けられたインデックスです。 それ以外の場合、カーソルのソースは、 オブジェクトストアハンドルに関連付けられたオブジェクト ストアです。

カーソルには方向があり、 反復時に レコードのキーに対して単調増加または単調減少のどちらの順序で 移動するか、およびインデックスを反復するときに重複する値をスキップするかどうかを 決定します。カーソルの方向はさらに、 カーソルの初期位置がそのソースの先頭にあるか末尾にあるかも決定します。カーソルの 方向は次の いずれかです。

"next"

この方向では、カーソルは ソースの先頭で開かれます。 反復時、カーソルは 重複を含むすべての レコードをキーの単調増加順に生成すべきです。

"nextunique"

この方向では、カーソルは ソースの先頭で開かれます。 反復時、カーソルは 同じキーを持つレコードを生成すべきではありませんが、それ以外のすべてのレコードを キーの単調増加順に生成すべきです。重複する値を持つ各キーについては、 最初のレコードのみが生成されます。 ソースがオブジェクトストアであるか、または 一意 フラグが true に設定されたインデックスである場合、この方向は "next" とまったく同じ 動作をします。

"prev"

この方向では、カーソルは ソースの末尾で開かれます。 反復時、カーソルは 重複を含むすべての レコードをキーの単調減少順に生成すべきです。

"prevunique"

この方向では、カーソルは ソースの末尾で開かれます。 反復時、カーソルは 同じキーを持つレコードを生成すべきではありませんが、それ以外のすべてのレコードを キーの単調減少順に生成すべきです。重複する値を持つ各キーについては、 最初のレコードのみが生成されます。 ソースがオブジェクトストアであるか、またはインデックスの一意 フラグが true に設定されている場合、この方向は "prev" とまったく同じ動作をします。

カーソルには、その範囲内の位置があります。 カーソルが反復しているレコードのリストは、カーソルの範囲全体が 反復される前に変更される可能性があります。 これを処理するため、カーソルはその位置を インデックスとしてではなく、以前に返された レコードのキーとして保持します。 前方向に反復するカーソルでは、次のレコードへ反復するよう次に要求されたとき、 以前に返されたものより大きい最小のキーを持つレコードを返します。 後方向に反復するカーソルでは逆であり、 以前に返されたものより小さい最大のキーを持つレコードを返します。

インデックスを反復するカーソルでは、複数のレコードが同じキーを持ち、 そのため値によってもソートされるため、状況はやや複雑です。 インデックスを反復するとき、 カーソルにはオブジェクトストア 位置もあり、 これはインデックス内で以前に見つかったレコードの 値を示します。 次の適切なレコードを見つけるときは、位置と オブジェクトストア 位置の両方が使用されます。

カーソルにはキーと値があり、 これらは最後に反復されたレコードの キーと値を表します。

カーソルには値取得 フラグがあります。このフラグが false の場合、 カーソルは次の値を読み込んでいる最中か、 範囲の末尾に到達しています。 true の場合は、 カーソルが現在値を保持しており、次の値へ 反復する準備ができていることを示します。

カーソルのソースが オブジェクトストアである場合、カーソルの 実効オブジェクトストアはそのオブジェクトストアであり、 カーソルの実効キーはカーソルの 位置です。カーソルのソースが インデックスである場合、 カーソルの実効オブジェクトストアは、そのインデックスの 参照されるオブジェクト ストアであり、実効 キーはカーソルの オブジェクト ストア位置です。

カーソルにはリクエストがあり、 これはカーソルを開くために使用されたリクエストです。

カーソルにはキーのみフラグもあり、 カーソルの値が API を介して公開されるかどうかを示します。

2.11. キージェネレーター

オブジェクトストアを作成するとき、 キージェネレーターを使用するよう指定できます。キージェネレーターは、 別途指定されていない場合にオブジェクトストアへ挿入されるレコードのキーを生成するために使用されます。

キージェネレーターには現在値があります。 現在値は常に、253 (9007199254740992) + 1 以下の 正の整数です。キージェネレーターの現在値の初期値は1で、 関連付けられたオブジェクト ストアが作成されたときに設定されます。 現在値はキーが生成されるにつれて増加し、 明示的なキーを使用することによって特定の値に更新される場合があります。

注記: キージェネレーターを使用する各オブジェクトストアは、それぞれ別個の ジェネレーターを使用します。つまり、あるオブジェクトストアとのやり取りが、 他のオブジェクトストアのキージェネレーターに影響することはありません。

キージェネレーターの現在値の変更は、 データベース操作の一部と見なされます。これは、操作が失敗し、 操作が取り消された場合、現在値が 操作の開始前に持っていた値へ戻されることを意味します。これは、 キージェネレーターが使用されたときに現在値が 1増加することによって生じる変更と、 レコードを保存する呼び出しで指定されたキー値を使用して レコードが 保存されることによって生じる変更の両方に適用されます。

同様に、トランザクションが中止された場合、そのトランザクションのスコープ内の各オブジェクト ストアのキージェネレーターの現在値は、 トランザクションが開始される前に 持っていた値へ戻されます。

キージェネレーターの現在値は、データベース操作が取り消された結果を除き、決して減少しません。 オブジェクトストアからレコードを削除しても、 オブジェクトストアのキージェネレーターには影響しません。たとえば clear() メソッドを使用してオブジェクトストアからすべてのレコードを消去しても、 オブジェクトストアのキージェネレーターの現在値には影響しません。

レコードが 保存され、そのレコードを保存する呼び出しでキーが指定されていない場合、 キーが生成されます。

オブジェクトストア store のキーを生成するには、 次の手順を実行します。

  1. generator を store のキージェネレーターとします。

  2. key を generator の現在値とします。

  3. key が 253 (9007199254740992) より大きい場合、失敗を返します。

  4. generator の現在値を1増加させます。

  5. key を返します。

レコードが 保存され、そのレコードを保存する呼び出しでキーが指定されている場合、 関連付けられたキージェネレーターが 更新される場合があります。

key を用いてオブジェクトストア store のキージェネレーターを 必要に応じて更新するには、 次の手順を実行します。

  1. key の型が number でない場合、この手順を中止します。

  2. value を key の値とします。

  3. value を、value と 253 (9007199254740992) の最小値に設定します。

  4. value を、value 以下の最大の整数に設定します。

  5. generator を store のキージェネレーターとします。

  6. value が generator の現在値以上である場合、 generator の現在値を value + 1 に設定します。

注記: キーは、インライン キーを使用するオブジェクトストアでは、オブジェクトストアのキーパスが指す保存値のプロパティを設定することで指定でき、 またアウトオブラインキーを使用するオブジェクトストアでは、 レコードを保存する呼び出しにキー引数を渡すことで指定できます。

型が number である指定されたキーのみが、キージェネレーターの 現在値に影響を与えることができます。 型が date、array(含まれる他のキーに関係なく)、binary、または string(数値として解析できるかどうかに関係なく)であるキーは、 キージェネレーターの現在値に影響を与えません。 型が number で値が1未満のキーは、 常に現在値より小さいため、 キージェネレーターの現在値に影響を与えません。

キージェネレーターの現在値が 253 (9007199254740992) を超えると、 それ以降キージェネレーターを使用して新しいキーを生成しようとする試みは、 "ConstraintError" DOMException になります。 明示的なキーを指定すれば、 レコードを オブジェクトストアに挿入することは引き続き可能ですが、そのようなレコードで 再びキージェネレーターを使用する唯一の方法は、 オブジェクトストアを削除して新しいものを作成することです。

注記: この制限は、9007199254740992 より大きい整数を ECMAScript Number として一意に表現できないために生じます。 例として、ECMAScript では 9007199254740992 + 1 === 9007199254740992 となります。

キージェネレーターを通常の方法で使用する限り、この制限が 問題になることはありません。昼夜を問わず毎秒1000回新しいキーを生成しても、 この制限に達するまで285000年以上かかります。

この実際上の結果として、オブジェクトストアで最初に生成されるキーは 常に1です(より大きい数値キーが先に挿入された場合を除く)。また、 オブジェクトストアで生成されるキーは、常にストア内の最大の数値キーより大きい 正の整数です。トランザクションがロールバックされない限り、 同じオブジェクトストアで同じキーが2回生成されることはありません。

各オブジェクトストアは独自のキージェネレーターを持ちます。

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が割り当てられる

制約違反または I/O エラーによって挿入が失敗した場合、 キージェネレーターは更新されません。

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が割り当てられる

objectStore から項目を削除しても、キージェネレーターには決して影響しません。 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が割り当てられる
// objectStore が 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が割り当てられる

次の例は、インラインキーとキージェネレーターを使用して オブジェクトをオブジェクトストアに保存しようとするときの、 異なる動作を示します。

次の条件が true である場合:

その場合、キー ジェネレーターによって提供される値が キー値の設定に使用されます。下の例では、 オブジェクトストアのキーパスは "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);
};

次の条件が true である場合:

その場合、キーパス プロパティに関連付けられた値が使用されます。自動生成されたキーは 使用されません。下の 例では、オブジェクトストアのキー パスは "foo.bar" です。 実際のオブジェクトでは bar プロパティの値は10です。{ 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" です。実際の オブジェクトには foo プロパティの値がありません。{ zip: {} } です。オブジェクトが オブジェクトストアに保存されると、 foo、bar、および baz プロパティが、foo.bar.baz に値を 割り当てられるようになるまで、それぞれ互いの子として作成されます。 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 });

// キー生成では、このプリミティブ上にキーパス
// プロパティを作成して保存しようとする。
store.put(4); // DataError をスローする

2.12. レコードスナップショット

レコードスナップショットは、 オブジェクトストアレコードまたはインデックスレコードからコピーされたキーと値を含みます。

レコードスナップショットには、 キーであるキーがあります。

レコードスナップショットには、 値である値があります。

注記: インデックス レコードの場合、スナップショットの値は、そのレコードの参照値のコピーです。 オブジェクトストアレコードの場合、スナップショットの値は、 レコードの 値です。

レコードスナップショットには、 キーである主キーもあります。

注記: インデックス レコードの場合、スナップショットの主キーは、そのレコードの値です。これは、インデックスの参照される オブジェクトストア内のレコードのキーです。 オブジェクトストアレコードの場合、スナップショットの主キーとキーは同じキーであり、これはレコードのキーです。

3. 例外

この文書で使用される各例外は、[WEBIDL]で定義されている DOMException または DOMException から派生した インターフェイスです。

次の表は、この 文書で使用される 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;

  // イベントハンドラー:
  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 を返します。 これがオープン リクエストである場合、アップグレード トランザクションがライブである間はそれを返し、それ以外の場合は null を返します。

request . readyState

リクエストが完了するまでは "pending" を返し、 その後は "done" を返します。

result ゲッターの手順は次のとおりです。
  1. this の完了フラグが false の場合、 "InvalidStateError" DOMException をスローします。

  2. this の結果を返し、リクエストで エラーが発生した場合は undefined を返します。

error ゲッターの手順は次のとおりです。
  1. this の完了フラグが false の場合、 "InvalidStateError" DOMException をスローします。

  2. this のエラーを返し、エラーが 発生していない場合は null を返します。

source ゲッターの手順は、 this のソースを返すことです。ソースが設定されていない場合は null を返します。

transaction ゲッターの手順は、 this のトランザクションを返すことです。

注記: transaction ゲッターは、open() から返されるリクエストなど、特定のリクエストでは null を返すことがあります。

readyState ゲッターの手順は、 this の完了フラグが false の場合は "pending" を返し、それ以外の場合は "done" を返すことです。

onsuccess 属性は、イベントハンドラーイベント型が success であるイベントハンドラー IDL 属性です。

onerror 属性は、イベントハンドラーイベント型が error イベントであるイベントハンドラー IDL 属性です。

IDBDatabase 上の、オープン リクエストを返すメソッドは、 blocked および upgradeneeded イベントを待ち受けられるようにするため、 拡張インターフェイスを使用します。

[Exposed=(Window,Worker)]
interface IDBOpenDBRequest : IDBRequest {
  // イベントハンドラー:
  attribute EventHandler onblocked;
  attribute EventHandler onupgradeneeded;
};

onblocked 属性は、イベントハンドラーイベント型が blocked であるイベントハンドラー IDL 属性です。

onupgradeneeded 属性は、イベントハンドラーイベント型が upgradeneeded であるイベントハンドラー IDL 属性です。

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 oldVersion = 0;
  unsigned long long? newVersion = null;
};

oldVersion ゲッターの手順は、 初期化された値を返すことです。これはデータベースの以前のバージョンを表します。

newVersion ゲッターの手順は、 初期化された値を返すことです。これはデータベースの新しいバージョンを表し、 データベースが削除されている場合は null です。データベースをアップグレードする手順を参照してください。

イベントは、DOM § 2.5 イベントの構築で定義されているとおりに構築されます。

oldVersion と newVersion が与えられたとき、target に e という名前のバージョン変更 イベントを発火するには、 次の手順を実行します。

  1. event を、IDBVersionChangeEvent を使用してイベントを 作成する結果とします。

  2. event の type 属性を e に設定します。

  3. event の bubbles および cancelable 属性を false に設定します。

  4. event の oldVersion 属性を oldVersion に設定します。

  5. event の newVersion 属性を newVersion に設定します。

  6. legacyOutputDidListenersThrowFlag を false とします。

  7. legacyOutputDidListenersThrowFlag を指定して、target に event をディスパッチします。

  8. legacyOutputDidListenersThrowFlag を返します。

    注記: このアルゴリズムの戻り値は常に使用されるわけではありません。

4.3. IDBFactory インターフェイス

データベースオブジェクトには、 IDBFactory インターフェイスのメソッドを介してアクセスします。この インターフェイスを実装する単一のオブジェクトが、Indexed DB 操作をサポートする 環境のグローバルスコープに存在します。

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)

指定された名前のデータベースへの 接続を、 現在のバージョンで開こうとします。まだ存在しない場合はバージョン1で開こうとします。 リクエストが成功すると、request の result は接続になります。

request = indexedDB . open(name, version)

指定された version で、指定された名前のデータベースへの 接続を開こうとします。データベースがすでに より低いバージョンで存在し、versionchange イベントに応答して閉じない、開いている接続がある場合、 すべての接続が閉じるまでリクエストは ブロックされ、その後アップグレードが 行われます。データベースがすでにより高い バージョンで存在する場合、リクエストは失敗します。リクエストが 成功した場合、request の result は 接続になります。

request = indexedDB . deleteDatabase(name)

指定された名前のデータベースを削除しようとします。 データベースが すでに存在し、versionchange イベントに応答して閉じない、開いている 接続がある場合、 すべての接続が閉じるまでリクエストは ブロックされます。リクエストが 成功した場合、request の result は null になります。

result = await indexedDB . databases()

ストレージ キー内のデータベースの名前とバージョンのスナップショットを示す オブジェクトのリストに解決される Promise を返します。

この API は、Web アプリケーションがデータベースの使用状況を確認するため、 たとえばサイトコードの以前のバージョンによるデータをクリーンアップするために使用することを意図しています。 結果はスナップショットであることに注意してください。このコンテキストまたは他のコンテキストによる データベースの作成、アップグレード、削除リクエストに対して、 データ収集や応答配信の順序について保証はありません。

open(name, version) メソッドの手順は 次のとおりです。

  1. version が0(ゼロ)の場合、TypeError をスローします。

  2. environment を、this の関連設定オブジェクトとします。

  3. storageKey を、environment を与えてストレージ キーを取得するを実行した結果とします。 failure が返された場合、"SecurityError" DOMException をスローし、 この手順を中止します。

  4. request を新しいオープンリクエストとします。

  5. 次の手順を並列に実行します。

    1. result を、 storageKey、 name、指定されている場合は version、そうでない場合は undefined、 および request を用いてデータベース接続を開く結果とします。

      version が指定されていない場合はどうなりますか? version が指定されておらず、その名前のデータベースが すでに存在する場合、バージョンを変更せずに 接続が開かれます。 version が指定されておらず、その名前のデータベースが 存在しない場合、新しいデータベースが バージョン1で作成されます。
    2. request の処理済みフラグを true に設定します。

    3. 次の手順を実行するためにデータベース タスクをキューに入れます。

      1. result がエラーである場合:

        1. request の結果を undefined に設定します。

        2. request のエラーを result に設定します。

        3. request の完了 フラグを true に設定します。

        4. request に error という名前のイベントを発火し、その bubbles および cancelable 属性を true で初期化します。

      2. それ以外の場合:

        1. request の結果を result に設定します。

        2. request の完了 フラグを true に設定します。

        3. request に success という名前のイベントを発火します。

        注記: 上記の手順によってアップグレード トランザクションが実行された場合、これらの手順は そのトランザクションが完了した後に実行されます。これにより、 別のバージョンアップグレードがまもなく発生する場合でも、 接続上で success イベントが先に発火され、 スクリプトが versionchange イベントのリスナーを登録する機会を得られることが保証されます。

        なぜsuccess イベントを発火するまたは error イベントを発火する手順を使用しないのですか? この時点ではリクエストに関連付けられたトランザクションがないため、 ディスパッチ前に関連付けられたトランザクションをアクティブ化し、 ディスパッチ後にトランザクションを非アクティブ化する それらの手順は適用されません。
  6. request に対する新しい IDBOpenDBRequest オブジェクトを返します。

deleteDatabase(name) メソッドの手順は 次のとおりです。

  1. environment を、this の関連設定オブジェクトとします。

  2. storageKey を、environment を与えてストレージ キーを取得するを実行した結果とします。 failure が返された場合、"SecurityError" DOMException をスローし、 この手順を中止します。

  3. request を新しいオープンリクエストとします。

  4. 次の手順を並列に実行します。

    1. result を、storageKey、 name、および request を用いてデータベースを 削除する結果とします。

    2. request の処理済みフラグを true に設定します。

    3. 次の手順を実行するためにデータベース タスクをキューに入れます。

      1. result がエラーである場合、 request のエラーを result に設定し、 request の完了フラグを true に設定し、 request に error という名前のイベントを発火し、 その bubbles および cancelable 属性を true で初期化します。

      2. それ以外の場合、 request の結果を undefined に設定し、 request の完了フラグを true に設定し、 result と null を用いて、request に success という名前のバージョン変更イベントを発火します。

        なぜsuccess イベントを発火するまたは error イベントを発火する手順を使用しないのですか? リクエストに関連付けられたトランザクションがないため、 ディスパッチ前に関連付けられた トランザクションをアクティブ化し、ディスパッチ後に トランザクションを非アクティブ化するそれらの手順は適用されません。

        また、ここでの success イベントは、 IDBVersionChangeEvent であり、 oldVersion および newVersion の詳細を含みます。

  5. request に対する新しい IDBOpenDBRequest オブジェクトを返します。

databases() メソッドの手順は次のとおりです。

  1. environment を、this の関連設定オブジェクトとします。

  2. storageKey を、environment を与えてストレージ キーを取得するを実行した結果とします。 failure が返された場合、"SecurityError" DOMException で拒否された Promiseを返します。

  3. p を新しい Promiseとします。

  4. 次の手順を並列に実行します。

    1. databases を storageKey 内のデータベースの集合とします。 何らかの理由でこれを判定できない場合、 適切なエラー(たとえば "UnknownError" DOMException)で p を拒否するためにデータベース タスクをキューに入れ、 この手順を終了します。

    2. result を新しいリストとします。

    3. databases の各 db について反復します。

      1. db のバージョンが0の場合、続行します。

      2. info を新しい IDBDatabaseInfo 辞書とします。

      3. info の name 辞書メンバーを db の名前に設定します。

      4. info の version 辞書メンバーを db のバージョンに設定します。

      5. info を result に追加します。

    4. result で p を解決するために、データベース タスクをキューに入れます。

  5. 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 をスローします。

cmp(first, second) メソッドの手順は 次のとおりです。

  1. a を、first を用いて値をキーに変換する結果とします。例外があれば再スローします。

  2. a が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  3. b を、second を用いて値をキーに変換する結果とします。例外があれば再スローします。

  4. b が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  5. a と b を用いて2つのキーを比較する 結果を返します。

4.4. IDBDatabase インターフェイス

IDBDatabase インターフェイスは、データベースへの接続を表します。

IDBDatabase オブジェクトに関連付けられた接続のクローズ 保留フラグが false であり、 型が abort、 error、 または versionchange のいずれかであるイベントリスナーが1つ以上登録されている場合、そのオブジェクトを ガベージコレクションしてはなりません。 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 mode = "readonly",
                                         optional IDBTransactionOptions options = {});
  undefined close();

  [NewObject] IDBObjectStore createObjectStore(
    DOMString name,
    optional IDBObjectStoreParameters options = {});
  undefined deleteObjectStore(DOMString name);

  // イベントハンドラー:
  attribute EventHandler onabort;
  attribute EventHandler onclose;
  attribute EventHandler onerror;
  attribute EventHandler onversionchange;
};

enum IDBTransactionDurability { "default", "strict", "relaxed" };

dictionary IDBTransactionOptions {
  IDBTransactionDurability durability = "default";
};

dictionary IDBObjectStoreParameters {
  (DOMString or sequence<DOMString>)? keyPath = null;
  boolean autoIncrement = false;
};
connection . name

データベースの名前を返します。

connection . version

データベースのバージョンを返します。

name ゲッターの手順は、 this に 関連付けられたデータベースの名前を返すことです。

注記: name 属性は、this のクローズ 保留フラグが true の場合でも、この名前を返します。 つまり、この属性の値は IDBDatabase インスタンスの存続期間中、一定のままです。

version ゲッターの手順は、 this のバージョンを返すことです。

これはデータベースの バージョンと同じですか? 接続が開いている限り、 これは接続されているデータベースのバージョンと同じです。しかし、 接続が閉じられた後は、この 属性には、後のアップグレードトランザクションで行われた変更は 反映されません。
connection . objectStoreNames

データベース内のオブジェクトストアの名前のリストを返します。

store = connection . createObjectStore(name [, options])

指定された name と options を持つ新しいオブジェクト ストアを作成し、新しい IDBObjectStore を返します。

アップグレード トランザクション内で呼び出されなかった場合、 "InvalidStateError" DOMException をスローします。

connection . deleteObjectStore(name)

指定された name を持つオブジェクト ストアを削除します。

アップグレード トランザクション内で呼び出されなかった場合、 "InvalidStateError" DOMException をスローします。

objectStoreNames ゲッターの手順は次のとおりです。
  1. names を、this のオブジェクトストア集合内のオブジェクトストアの名前のリストとします。

  2. names を用いてソート済み 名前リストを作成する結果(DOMStringList)を返します。

これはデータベースの オブジェクトストアの 名前と同じですか? 接続が開いている限り、 これは接続されているデータベースのオブジェクトストアの名前と同じです。 しかし、接続が閉じられた後は、この属性には、 後のアップグレードトランザクションで行われた変更は 反映されません。

createObjectStore(name, options) メソッドの手順は次のとおりです。

  1. database を、this に関連付けられたデータベースとします。

  2. database のアップグレード トランザクションが null でない場合は、それを transaction とします。 そうでない場合は "InvalidStateError" DOMException をスローします。

  3. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  4. options の keyPath メンバーが undefined でも null でもない場合は、それを keyPath とし、それ以外の場合は null とします。

  5. keyPath が null でなく、かつ有効なキーパスでない場合、"SyntaxError" DOMException をスローします。

  6. name という名前のオブジェクトストアが database 内にすでに 存在する場合、"ConstraintError" DOMException をスローします。

  7. autoIncrement を options の autoIncrement メンバーとします。

  8. autoIncrement が true で、keyPath が空文字列または 任意のシーケンス(空かどうかを問わない)である場合、 "InvalidAccessError" DOMException をスローします。

  9. store を database 内の新しいオブジェクトストアとします。作成されたオブジェクトストアの 名前を name に設定します。 autoIncrement が true の場合、作成されたオブジェクトストアはキージェネレーターを使用します。 keyPath が null でない場合、作成されたオブジェクト ストアの キー パスを keyPath に設定します。

  10. store および transaction に関連付けられた新しいオブジェクト ストアハンドルを返します。

このメソッドは、接続されたデータベースに、 指定された名前を持つ新しいオブジェクトストアを作成して返します。このメソッドは、 アップグレードトランザクション内からのみ呼び出さなければならないことに注意してください。

このメソッドは、呼び出された IDBDatabase インスタンス上の objectStoreNames プロパティを同期的に変更します。

一部の実装では、createObjectStore() メソッドが戻った後にオブジェクトストアを作成するタスクをキューに入れた後、 実装が問題に遭遇する可能性があります。たとえば、 新しく作成されたオブジェクトストアに関するメタデータを非同期にデータベースへ挿入する実装や、 クォータ上の理由からユーザーに許可を求める必要がある実装などです。 そのような実装でも、IDBObjectStore オブジェクトを作成して返さなければならず、実装が オブジェクトストアの作成に 失敗したと判定した時点で、適切なエラーを用いてトランザクションを中止する手順によって トランザクションを中止しなければなりません。たとえば、オブジェクトストアの作成が クォータ上の理由で失敗した場合、QuotaExceededError をエラーとして 使用しなければなりません。

deleteObjectStore(name) メソッドの 手順は次のとおりです。

  1. database を、this に関連付けられたデータベースとします。

  2. database のアップグレード トランザクションが null でない場合は、それを transaction とします。 そうでない場合は "InvalidStateError" DOMException をスローします。

  3. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  4. store を、database 内の name という名前のオブジェクト ストアとします。 存在しない場合は "NotFoundError" DOMException をスローします。

  5. store を this のオブジェクトストア集合から削除します。

  6. store と transaction に関連付けられたオブジェクト ストアハンドルがある場合、その インデックス集合からすべてのエントリを削除します。

  7. store を破棄します。

このメソッドは、接続されたデータベース内の 指定された名前のオブジェクト ストアを破棄します。このメソッドは、 アップグレード トランザクション内からのみ呼び出さなければならないことに注意してください。

このメソッドは、呼び出された IDBDatabase インスタンス上の objectStoreNames プロパティを同期的に変更します。

transaction = connection . transaction(scope [, mode [, options ] ])

指定された scope(単一のオブジェクトストアの名前、または名前の配列)、 mode("readonly" または "readwrite")、 および durability ("default"、 "strict" または "relaxed")を含む追加の options を持つ、新しいトランザクションを返します。

既定の mode は "readonly" で、既定の durability は "default" です。

connection . close()

実行中のすべてのトランザクションが 完了した後に接続を閉じます。

transaction(storeNames, mode, options) メソッドの手順は次のとおりです。

  1. ライブなアップグレード トランザクションが接続に関連付けられている場合、 "InvalidStateError" DOMException をスローします。

  2. this のクローズ保留フラグが true の場合、 "InvalidStateError" DOMException をスローします。

  3. scope を、storeNames がシーケンスの場合はその中の一意な文字列の集合、 それ以外の場合は storeNames と等しい1つの文字列を含む集合とします。

  4. scope 内のいずれかの文字列が、接続されたデータベース内のオブジェクトストアの名前でない場合、 "NotFoundError" DOMException をスローします。

  5. scope が空の場合、 "InvalidAccessError" DOMException をスローします。

  6. mode が "readonly" または "readwrite" でない場合、TypeError をスローします。

  7. transaction を、この接続、 mode、options の durability メンバー、および scope で名前が指定されたオブジェクト ストアの集合を持つ、新しく作成されたトランザクションとします。

  8. transaction のクリーンアップイベントループを現在のイベントループに設定します。

  9. transaction を表す IDBTransaction オブジェクトを返します。

🚧 durability オプションはこの版で新たに追加されました。 Chrome 82、Edge 82、Firefox 126、Safari 15 でサポートされています。 🚧

注記: 作成された transaction は存続期間の 規則に従います。

close() メソッドの手順は次のとおりです。

  1. この接続を用いて、データベース接続を閉じるを実行します。

注記: 接続は、未完了のすべてのトランザクションが完了するまで、実際には閉じられません。その後の close() の呼び出しは何の効果もありません。

onabort 属性は、イベントハンドラーイベント型が abort であるイベントハンドラー IDL 属性です。

onclose 属性は、イベントハンドラーイベント型が close であるイベントハンドラー IDL 属性です。

onerror 属性は、イベントハンドラーイベント型が error であるイベントハンドラー IDL 属性です。

onversionchange 属性は、イベントハンドラーイベント型が versionchange であるイベントハンドラー IDL 属性です。

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 direction = "next");
  [NewObject] IDBRequest openKeyCursor(optional any query,
                                       optional IDBCursorDirection direction = "next");

  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 direction = "next";
};
store . name

ストアの名前を返します。

store . name = newName

ストアの名前を newName に更新します。

アップグレードトランザクション内で呼び出されなかった場合、 "InvalidStateError" DOMException をスローします。

store . keyPath

ストアのキー パスを返し、存在しない場合は null を返します。

store . indexNames

ストア内のインデックス名のリストを返します。

store . transaction

関連付けられたトランザクションを返します。

store . autoIncrement

ストアにキージェネレーターがある場合は true を返し、それ以外の場合は false を返します。

name ゲッターの手順は、this の名前を返すことです。

これはオブジェクト ストアの名前と同じですか? トランザクションが完了していない限り、 これは関連付けられたオブジェクト ストアの 名前と同じです。しかし、 トランザクションが 完了すると、この 属性には、後のアップグレード トランザクションで行われた変更は反映されません。

name セッターの手順は次のとおりです。

  1. name を与えられた 値とします。

  2. transaction をthis のトランザクションとします。

  3. store をthis のオブジェクトストアとします。

  4. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. transaction がアップグレードトランザクションでない場合、 "InvalidStateError" DOMException をスローします。

  6. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  7. store の名前が name と等しい場合、 この手順を終了します。

  8. name という名前のオブジェクトストアが store のデータベース内にすでに存在する場合、 "ConstraintError" DOMException をスローします。

  9. store の名前を name に設定します。

  10. this の名前を name に設定します。

keyPath ゲッターの手順は、 this のオブジェクトストアのキーパスを返すことです。 存在しない場合は null を返します。キーパスは、 [WEBIDL]に従い、 文字列の場合は DOMString として、または 文字列のリストの場合は sequence<DOMString> として変換されます。

注記: 返される値は、オブジェクトストアが作成されたときに 使用されたものと同じインスタンスではありません。 ただし、この属性が オブジェクト(具体的には Array)を返す場合、 参照されるたびに同じオブジェクト インスタンスを返します。オブジェクトのプロパティを変更しても、 オブジェクト ストアには影響しません。

indexNames ゲッターの手順は次のとおりです。
  1. names を、this のインデックス集合内のインデックスの名前のリストとします。

  2. names を用いてソート済み名前リストを作成する結果(DOMStringList)を返します。

これはオブジェクト ストアのインデックスの名前のリストと同じですか? トランザクションが完了していない限り、 これは関連付けられたオブジェクト ストアのインデックスの名前のリストと同じです。しかし、 トランザクションが 完了すると、この 属性には、後のアップグレードトランザクションで行われた変更は 反映されません。

transaction ゲッターの手順は、 this のトランザクションを返すことです。

autoIncrement ゲッターの手順は、 this の オブジェクトストアにキージェネレーターがある場合は true を返し、 それ以外の場合は false を返すことです。

次のメソッドは、 読み取り専用トランザクション内で呼び出された場合、"ReadOnlyError" DOMException をスローし、トランザクションがアクティブでないときに 呼び出された場合は "TransactionInactiveError" DOMException をスローします。
request = store . put(value [, key])
request = store . add(value [, key])

指定された value と key を持つレコードを store に追加または更新します。

ストアがインラインキーを使用しており、key が指定されている場合、 "DataError" DOMException がスローされます。

put() を使用した場合、そのキーを持つ既存のレコードは置き換えられます。 add() を使用し、そのキーを持つレコードがすでに存在する場合、 request は失敗し、request の error は "ConstraintError" DOMException に設定されます。

成功した場合、request の result は レコードのキーになります。

request = store . delete(query)

query 内の指定された キーまたは指定されたキー範囲にある、 store 内のレコードを削除します。

成功した場合、request の result は undefined になります。

request = store . clear()

store 内のすべてのレコードを削除します。

成功した場合、request の result は undefined になります。

put(value, key) メソッドの手順は、 this、 value、key、および false の no-overwrite flag を用いて追加または 格納するを実行した結果を返すことです。

add(value, key) メソッドの手順は、 this、 value、key、および true の no-overwrite flag を用いて追加または 格納するを実行した結果を返すことです。

handle、value、key、および no-overwrite flag を用いて追加または格納するには、次の手順を実行します。

  1. transaction を handle の トランザクションとします。

  2. store を handle の オブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. transaction が読み取り専用トランザクションである場合、 "ReadOnlyError" DOMException をスローします。

  6. store がインラインキーを使用しており、key が指定されている場合、 "DataError" DOMException をスローします。

  7. store がアウトオブラインキーを使用し、キージェネレーターを持たず、 かつ key が指定されていない場合、 "DataError" DOMException をスローします。

  8. key が指定されている場合:

    1. r を、key を用いて値を キーに変換する結果とします。例外があれば再スローします。

    2. r が "invalid value" または "invalid type" である場合、 "DataError" DOMException をスローします。

    3. key を r とします。

  9. targetRealm をユーザーエージェントが定義するRealm とします。

  10. clone を、transaction 中の targetRealm における value のクローンとします。 例外があれば再スローします。

    なぜ値のコピーを作成するのですか? 値は保存時にシリアライズされます。ここでコピーとして扱うことで、 この仕様の他のアルゴリズムはこれを ECMAScript 値として扱うことができますが、 動作の違いが観測可能でない場合、実装はこれを 最適化できます。
  11. store がインラインキーを使用する場合:

    1. kpk を、clone と store のキーパスを用いてキーパスを使用して値からキーを 抽出する結果とします。例外があれば 再スローします。

    2. kpk が invalid の場合、 "DataError" DOMException をスローします。

    3. kpk が failure でない場合、key を kpk とします。

    4. それ以外の場合(kpk が failure):

      1. store にキージェネレーターがない場合、 "DataError" DOMException をスローします。

      2. clone と store のキー パスを用いてキーを 値に注入できることを確認するが false を返す場合、"DataError" DOMException をスローします。

  12. operation を、store、clone、key、および no-overwrite flag を用いてレコードを オブジェクトストアに格納するを実行するアルゴリズムとします。

  13. handle と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

delete(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. transaction が読み取り専用トランザクションである場合、 "ReadOnlyError" DOMException をスローします。

  6. range を、query と true を用いて値をキー範囲に変換する結果とします。例外があれば再スローします。

  7. operation を、store と range を用いてオブジェクトストアから レコードを削除するを実行するアルゴリズムとします。

  8. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、削除するレコードを識別するキー またはキー範囲(IDBKeyRange)を指定できます。

注記: キーまたはキー範囲を受け取る他のメソッドとは異なり、このメソッドは キーとして null を指定することを許可しません。これは、 小さなバグによってオブジェクトストア全体が消去されるリスクを 軽減するためです。

clear() メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. transaction が読み取り専用トランザクションである場合、 "ReadOnlyError" DOMException をスローします。

  6. operation を、store を用いてオブジェクトストアを消去する を実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

次のメソッドは、 トランザクションが アクティブでないときに 呼び出された場合、"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})

query 内の指定されたキーまたはキー範囲に一致するレコードの値を取得します (count が指定されている場合は最大 count 件)。 最初の count 個の値を取得するには direction オプションを "next" に設定し、最後の count 個の値を返すには "prev" に設定します。

成功した場合、request の result は値の Array になります。

request = store . getAllKeys(query [, count])
request = store . getAllKeys({query, count, direction})

query 内の指定されたキーまたはキー範囲に一致するレコードのキーを取得します (count が指定されている場合は最大 count 件)。 最初の count 個のキーを取得するには direction オプションを "next" に設定し、最後の count 個のキーを返すには "prev" に設定します。

成功した場合、request の result はキーの Array になります。

request = store . getAllRecords({query, count, direction})

レコードのキーと値を取得します。

query オプションは、一致させるキーまたは キー範囲を指定します。 count オプションは一致するレコード数を制限します。 最初の count 件のレコードを取得するには direction オプションを "next" に設定し、最後の count 件のレコードを返すには "prev" に設定します。

成功した場合、request の result は Array になり、 各メンバーは IDBRecord になります。

request = store . count(query)

query 内の指定されたキーまたはキー範囲に一致するレコードの数を取得します。

成功した場合、request の result はその件数になります。

get(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、query と true を用いて値をキー範囲に変換する結果とします。例外があれば再スローします。

  6. operation を、 現在の Realm レコード、store、および range を用いてオブジェクトストアから 値を取得するを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、取得するレコードの値を識別するキー またはキー範囲(IDBKeyRange)を指定できます。 範囲が指定された場合、このメソッドは その範囲内で最初に存在する値を取得します。

注記: このメソッドは、指定されたキーを持つレコードが 存在しない場合と、レコードは存在するものの値が undefined である場合とで、 同じ結果を生成します。この2つの状況を区別する必要がある場合は、 同じキーで openCursor() を使用できます。レコードが存在する場合は値が undefined の カーソルが返され、そのようなレコードが存在しない場合はカーソルが返されません。

getKey(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、query と true を用いて値をキー範囲に変換する結果とします。例外があれば再スローします。

  6. operation を、store と range を用いてオブジェクトストアから キーを取得するを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、取得するレコードのキーを識別するキー またはキー範囲(IDBKeyRange)を指定できます。 範囲が指定された場合、このメソッドは その範囲内で最初に存在するキーを取得します。

getAll(queryOrOptions, count) メソッドの手順は次のとおりです。

  1. 現在の Realm レコード、this、"value"、 queryOrOptions、および指定されている場合は count を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

getAllKeys(queryOrOptions, count) メソッドの手順は次のとおりです。

  1. 現在の Realm レコード、this、"key"、 queryOrOptions、および指定されている場合は count を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

getAllRecords(options) メソッドの 手順は次のとおりです。

  1. 現在の Realm レコード、this、"record"、および options を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

count(query) メソッドの 手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. operation を、store と range を用いて範囲内の レコードを数えるを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: 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"]])

query に一致する レコード上で、キーのみ フラグを true に設定したカーソルを direction に従って順序付けて開きます。 query が null の場合、store 内のすべてのレコードが一致します。

成功した場合、request の result は、最初に一致するレコードを指す IDBCursor になり、一致するレコードがない場合は null になります。

openCursor(query, direction) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. cursor を新しいカーソルとし、 その ソース ハンドルをthis に、 位置を undefined に、 方向を direction に、 値取得 フラグを false に、 キーおよび値を undefined に、 範囲を range に、そして キーのみ フラグを false に設定します。

  7. operation を、現在の Realm レコードと cursor を用いてカーソルを反復するを実行するアルゴリズムとします。

  8. request を、this と operation を用いてリクエストを非同期に 実行するを実行した結果とします。

  9. cursor のリクエストを request に設定します。

  10. request を返します。

注記: query パラメーターには、カーソルの範囲として使用するキー またはキー範囲(IDBKeyRange)を指定できます。 null または未指定の場合、境界のないキー範囲が使用されます。

openKeyCursor(query, direction) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. cursor を新しいカーソルとし、 その ソース ハンドルをthis に、 位置を undefined に、 方向を direction に、 値取得 フラグを false に、 キーおよび値を undefined に、 範囲を range に、そして キーのみ フラグを true に設定します。

  7. operation を、現在の Realm レコードと cursor を用いてカーソルを反復するを実行するアルゴリズムとします。

  8. request を、this と operation を用いてリクエストを非同期に 実行するを実行した結果とします。

  9. cursor のリクエストを request に設定します。

  10. request を返します。

注記: query パラメーターには、カーソルの範囲として使用するキー またはキー範囲(IDBKeyRange)を指定できます。null または未指定の場合、境界のない キー範囲が使用されます。

index = store . index(name)

store 内の name という名前のインデックスに対する IDBIndex を返します。

index = store . createIndex(name, keyPath [, options])

指定された name、 keyPath、および options を持つ新しいインデックスを store 内に作成し、新しい IDBIndex を返します。 keyPath と options が、store にすでに存在するデータでは 満たせない制約を定義している場合、アップグレードトランザクションは "ConstraintError" DOMException で中止されます。

アップグレードトランザクション内で呼び出されなかった場合、 "InvalidStateError" DOMException をスローします。

store . deleteIndex(name)

store 内の指定された name のインデックスを 削除します。

アップグレードトランザクション内で呼び出されなかった場合、 "InvalidStateError" DOMException をスローします。

createIndex(name, keyPath, options) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. transaction がアップグレードトランザクションでない場合、 "InvalidStateError" DOMException をスローします。

  4. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  6. name という名前のインデックスが store 内にすでに存在する場合、 "ConstraintError" DOMException をスローします。

  7. keyPath が有効なキーパスでない場合、 "SyntaxError" DOMException をスローします。

  8. unique を options の unique メンバーとします。

  9. multiEntry を options の multiEntry メンバーとします。

  10. keyPath がシーケンスで、multiEntry が true の場合、"InvalidAccessError" DOMException をスローします。

  11. index を store 内の新しいインデックスとします。 index の名前を name に、キー パスを keyPath に、 一意 フラグを unique に、そして multiEntry フラグを multiEntry に設定します。

  12. index をthis のインデックス集合に追加します。

  13. 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番目のリクエストが実行されると、 重複する名前が作成されます。インデックスの作成は非同期のリクエストと見なされるため、 インデックスの一意性 制約によって 2番目のリクエストが失敗することはありません。 代わりに、インデックスが作成されて制約の評価が 失敗したとき、トランザクションが 中止されます。

index(name) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態が完了である場合、 "InvalidStateError" DOMException をスローします。

  5. index を、存在する場合はthis の インデックス集合内の name という名前のインデックスとし、 存在しない場合は "NotFoundError" DOMException をスローします。

  6. index とthis に関連付けられたインデックス ハンドルを返します。

注記: 同じ IDBObjectStore インスタンスで同じ名前を指定してこのメソッドを呼び出すたびに、 同じ IDBIndex インスタンスが返されます。

注記: 返される IDBIndex インスタンスは、この IDBObjectStore インスタンスに固有です。このメソッドが、 同じ名前を持つ別の IDBObjectStore インスタンスで呼び出された場合、 別の IDBIndex インスタンスが返されます。

deleteIndex(name) メソッドの手順は 次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. store をthis のオブジェクトストアとします。

  3. transaction がアップグレードトランザクションでない場合、 "InvalidStateError" DOMException をスローします。

  4. store が削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  6. index を、存在する場合は store 内の name という名前のインデックスとし、 存在しない場合は "NotFoundError" DOMException をスローします。

  7. index をthis のインデックス集合から削除します。

  8. 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 direction = "next");
  [NewObject] IDBRequest openKeyCursor(optional any query,
                                       optional IDBCursorDirection direction = "next");
};
index . name

インデックスの名前を 返します。

index . name = newName

ストアの名前を newName に更新します。

アップグレードトランザクション内で呼び出されなかった場合、"InvalidStateError" DOMException をスローします。

index . objectStore

インデックスが属する IDBObjectStore を返します。

index . keyPath

インデックスのキーパスを 返します。

index . multiEntry

インデックスのmultiEntry フラグが true の場合、true を返します。

index . unique

インデックスの一意フラグが true の場合、true を返します。

name ゲッターの手順は、 this の名前を返すことです。

これはインデックスの 名前と同じですか? トランザクションが完了していない限り、 これは関連付けられたインデックスの 名前と同じです。しかし、トランザクションが 完了すると、この 属性には、後のアップグレード トランザクションで行われた変更は反映されません。

name セッターの手順は次のとおりです。

  1. name を与えられた 値とします。

  2. transaction をthis のトランザクションとします。

  3. index をthis のインデックスとします。

  4. transaction がアップグレードトランザクションでない場合、 "InvalidStateError" DOMException をスローします。

  5. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  6. index または index のオブジェクトストアが 削除されている場合、"InvalidStateError" DOMException をスローします。

  7. index の名前が name と 等しい場合、この手順を終了します。

  8. name という名前のインデックスが index のオブジェクトストア内にすでに存在する場合、 "ConstraintError" DOMException をスローします。

  9. index の名前を name に設定します。

  10. this の名前を name に設定します。

objectStore ゲッターの手順は、 this のオブジェクトストアハンドルを返すことです。

keyPath ゲッターの手順は、 this のインデックスの キーパスを返すことです。 キーパスは、 文字列の場合は DOMString として、または 文字列のリストの場合は sequence<DOMString> として、[WEBIDL] に従って変換されます。

注記: 返される値は、 インデックスが作成されたときに使用されたものと同じインスタンスではありません。ただし、 この属性が オブジェクト(具体的には Array)を返す場合、 参照されるたびに同じオブジェクト インスタンスを返します。オブジェクトのプロパティを変更しても、 インデックスには影響しません。

multiEntry ゲッターの手順は、 this のインデックスのmultiEntry フラグを返すことです。

unique ゲッターの手順は、 this のインデックスの一意フラグを返すことです。

次のメソッドは、トランザクションが アクティブでないときに 呼び出された場合、"TransactionInactiveError" DOMException をスローします。
request = index . get(query)

query 内の指定されたキーまたはキー範囲に一致する最初の レコードの値を取得します。

成功した場合、request の result はその 値になり、一致する レコードがなかった場合は undefined になります。

request = index . getKey(query)

query 内の指定されたキーまたはキー範囲に一致する最初のレコードのキーを取得します。

成功した場合、request の result はその キーになり、一致する レコードがなかった場合は undefined になります。

request = index . getAll(query [, count])
request = index . getAll({query, count, direction})

query 内の指定されたキーまたはキー範囲に一致するレコードの値を取得します (count が指定されている場合は最大 count 件)。 最初の count 個の値を取得するには direction オプションを "next" に設定し、最後の count 個の値を返すには "prev" に設定します。 最初の重複インデックスキーを持つレコードを取得した後に、重複するインデックスキーを持つレコードを除外するには、direction オプションを "nextunique" または "prevunique" に設定します。

成功した場合、request の result は値の Array になります。

request = index . getAllKeys(query [, count])
request = index . getAllKeys({query, count, direction})

query 内の指定されたキーまたはキー範囲に一致するレコードのキーを取得します (count が指定されている場合は最大 count 件)。 最初の count 個のキーを取得するには direction オプションを "next" に設定し、最後の count 個のキーを返すには "prev" に設定します。 最初の重複インデックスキーを持つレコードを取得した後に、重複するインデックスキーを持つレコードを除外するには、direction オプションを "nextunique" または "prevunique" に設定します。

成功した場合、request の result はキーの Array になります。

request = index . getAllRecords({query, count, direction})

レコードのキー、値、およびインデックスのキーを取得します。

query オプションは、一致させるキーまたは キー範囲を指定します。 count オプションは一致するレコード数を制限します。 最初の count 件のレコードを取得するには direction オプションを "next" に設定し、最後の count 件のレコードを返すには "prev" に設定します。 最初の重複インデックスキーを持つレコードを取得した後に、重複するインデックスキーを持つレコードを除外するには、direction オプションを "nextunique" または "prevunique" に設定します。

成功した場合、request の result は Array になり、 各メンバーは IDBRecord になります。 レコードのインデックスキーを取得するには IDBRecord’s key を使用します。レコードのキーを取得するには IDBRecord’s primaryKey を使用します。

request = index . count(query)

query 内の指定されたキー またはキー範囲に一致するレコードの数を取得します。

成功した場合、request の result はその 件数になります。

get(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. index をthis のインデックスとします。

  3. index または index のオブジェクトストアが 削除されている場合、"InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、query と true を用いて値をキー範囲に変換する結果とします。例外があれば再スローします。

  6. operation を、現在の Realm レコード、index、および range を用いてインデックスから参照値を取得するを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、取得する参照値を識別するキー またはキー範囲(IDBKeyRange)を指定できます。 範囲が指定された場合、このメソッドは その範囲内で最初に存在するレコードを取得します。

注記: このメソッドは、指定されたキーを持つレコードが 存在しない場合と、レコードは存在するものの値が undefined である場合とで、 同じ結果を生成します。この2つの状況を区別する必要がある場合は、 同じキーで openCursor() を使用できます。レコードが存在する場合は値が undefined の カーソルが返され、そのようなレコードが存在しない場合はカーソルが返されません。

getKey(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. index をthis のインデックスとします。

  3. index または index のオブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、query と true を用いて値をキー範囲に変換する結果とします。例外があれば再スローします。

  6. operation を、index と range を用いてインデックスから 値を取得するを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、取得するレコードのキーを識別するキー またはキー範囲(IDBKeyRange)を指定できます。 範囲が指定された場合、このメソッドはその範囲内で最初に存在するキーを 取得します。

getAll(queryOrOptions, count) メソッドの手順は次のとおりです。

  1. 現在の Realm レコード、this、"value"、 queryOrOptions、および指定されている場合は count を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

getAllKeys(queryOrOptions, count) メソッドの手順は次のとおりです。

  1. 現在の Realm レコード、this、"key"、 queryOrOptions、および指定されている場合は count を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

getAllRecords(options) メソッドの手順は 次のとおりです。

  1. 現在の Realm レコード、this、"record"、および options を用いて複数の項目を取得する リクエストを作成する結果を返します。 例外があれば再スローします。

count(query) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. index をthis のインデックスとします。

  3. index または index のオブジェクトストアが 削除されている場合、"InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. operation を、index と range を用いて範囲内の レコードを数えるを実行するアルゴリズムとします。

  7. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: query パラメーターには、数えるレコードを 識別するキー またはキー範囲(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 に一致する レコード上で、キーのみ フラグを true に設定したカーソルを、 direction に従って順序付けて開きます。 query が null の場合、index 内のすべてのレコードが一致します。

成功した場合、request の result は IDBCursor になり、一致するレコードがない場合は null になります。

openCursor(query, direction) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. index をthis のインデックスとします。

  3. index または index のオブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. cursor を新しいカーソルとし、 その ソース ハンドルをthis に、 位置を undefined に、 方向を direction に、 値取得 フラグを false に、 キーおよび値を undefined に、 範囲を range に、そして キーのみ フラグを false に設定します。

  7. operation を、現在の Realm レコードと cursor を用いてカーソルを反復するを実行するアルゴリズムとします。

  8. request を、this と operation を用いてリクエストを非同期に 実行するを実行した結果とします。

  9. cursor のリクエストを request に設定します。

  10. request を返します。

注記: query パラメーターには、カーソルの範囲として使用するキー またはキー範囲(IDBKeyRange)を指定できます。null または未指定の場合、境界のない キー範囲が使用されます。

openKeyCursor(query, direction) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. index をthis のインデックスとします。

  3. index または index のオブジェクトストアが 削除されている場合、"InvalidStateError" DOMException をスローします。

  4. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  5. range を、 query を用いて値をキー範囲に変換する結果とします。 例外があれば再スローします。

  6. cursor を新しいカーソルとし、 その ソース ハンドルをthis に、 位置を undefined に、 方向を direction に、 値取得 フラグを false に、 キーおよび値を undefined に、 範囲を range に、そして キーのみ フラグを true に設定します。

  7. operation を、現在の Realm レコードと cursor を用いてカーソルを反復するを実行するアルゴリズムとします。

  8. request を、this と operation を用いてリクエストを非同期に 実行するを実行した結果とします。

  9. cursor のリクエストを request に設定します。

  10. request を返します。

注記: query パラメーターには、カーソルの範囲として使用するキー またはキー範囲(IDBKeyRange)を指定できます。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;

  // 静的構築メソッド:
  [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);
};
range . lower

範囲の下限を返し、存在しない場合は undefined を返します。

range . upper

範囲の上限を返し、存在しない場合は undefined を返します。

range . lowerOpen

範囲の下限オープンフラグを返します。

range . upperOpen

範囲の上限オープンフラグを返します。

lower ゲッターの手順は、 this の下限が null でない場合、それを用いてキーを値に変換する結果を返し、 それ以外の場合は undefined を返すことです。

upper ゲッターの手順は、 this の上限が null でない場合、それを用いてキーを値に変換する結果を返し、 それ以外の場合は undefined を返すことです。

lowerOpen ゲッターの手順は、 this の下限 オープンフラグを返すことです。

upperOpen ゲッターの手順は、 this の上限 オープンフラグを返すことです。

range = IDBKeyRange . only(key)

key のみを範囲とする新しい IDBKeyRange を返します。

range = IDBKeyRange . lowerBound(key [, open = false])

key から始まり、上限のない新しい IDBKeyRange を返します。open が true の場合、key は 範囲に含まれません。

range = IDBKeyRange . upperBound(key [, open = false])

下限がなく、 key で終わる新しい IDBKeyRange を返します。open が true の場合、key は範囲に含まれません。

range = IDBKeyRange . bound(lower, upper [, lowerOpen = false [, upperOpen = false]])

lower から upper までの範囲を持つ新しい IDBKeyRange を返します。 lowerOpen が true の場合、lower は範囲に含まれません。 upperOpen が true の場合、upper は範囲に含まれません。

only(value) メソッドの手順は次のとおりです。

  1. key を、value を用いて値をキーに変換する結果とします。例外があれば再スローします。

  2. key が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  3. key のみを含む新しいキー 範囲を作成して返します。

lowerBound(lower, open) メソッドの手順は次のとおりです。

  1. lowerKey を、lower を用いて値をキーに変換する結果とします。例外があれば再スローします。

  2. lowerKey が invalid の場合、"DataError" DOMException をスローします。

  3. 下限を lowerKey に、下限オープンフラグを open に、 上限を null に、そして上限オープンフラグを true に設定した新しいキー 範囲を作成して返します。

upperBound(upper, open) メソッドの手順は次のとおりです。

  1. upperKey を、upper を用いて値をキーに変換する結果とします。例外があれば再スローします。

  2. upperKey が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  3. 下限を null に、下限オープンフラグを true に、上限を upperKey に、そして上限オープンフラグを open に設定した新しいキー 範囲を作成して返します。

bound(lower, upper, lowerOpen, upperOpen) メソッドの手順は次のとおりです。

  1. lowerKey を、lower を用いて値をキーに変換する結果とします。例外があれば再スローします。

  2. lowerKey が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  3. upperKey を、upper を用いて値をキーに変換する結果とします。例外があれば再スローします。

  4. upperKey が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  5. lowerKey が upperKey より大きい場合、 "DataError" DOMException をスローします。

  6. 下限を lowerKey に、下限オープンフラグを lowerOpen に、 上限を upperKey に、そして上限オープン フラグを upperOpen に設定した新しいキー 範囲を作成して返します。

range . includes(key)

key が範囲に含まれる場合は true を返し、それ以外の場合は false を返します。

includes(key) メソッドの手順は次のとおりです。

  1. k を、key を用いて値をキーに変換する結果とします。 例外があれば再スローします。

  2. k が "invalid value" または "invalid type" である場合、"DataError" DOMException をスローします。

  3. 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 のキーを用いてキーを 値に変換する結果を返すことです。

primaryKey ゲッターの手順は、this の主キーを用いてキーを 値に変換する結果を返すことです。

value ゲッターの手順は、this の値を返すことです。

4.9. IDBCursor インターフェイス

カーソルオブジェクトは IDBCursor インターフェイスを実装します。ある カーソルを表す IDBCursor インスタンスは常に1つだけです。同時に 使用できるカーソルの数に制限はありません。

[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 属性は、カーソルが現在反復中である場合、末尾を越えて反復済みである場合、またはその トランザクションが アクティブでない場合でも、 null を返したり例外をスローしたりすることはありません。

direction ゲッターの手順は、 this の 方向を返すことです。

key ゲッターの手順は、 カーソルの現在のキーを用いてキーを値に変換する結果を返すことです。

注記: key がオブジェクト(たとえば Date または Array)を返す場合、 カーソルのキーが 変更されるまで、参照されるたびに同じオブジェクトインスタンスを返します。これは、 オブジェクトが変更された場合、その変更がカーソルの値を参照する すべての人から見えることを意味します。ただし、このような オブジェクトを変更してもデータベースの内容は変更されません。

primaryKey ゲッターの手順は、 カーソルの現在の実効キーを用いてキーを値に変換する結果を返すことです。

注記: primaryKey がオブジェクト(たとえば Date または Array)を返す場合、 カーソルの実効 キーが変更されるまで、参照されるたびに同じオブジェクトインスタンスを返します。これは、 オブジェクトが変更された場合、その変更がカーソルの値を 参照するすべての人から見えることを意味します。ただし、このようなオブジェクトを 変更してもデータベースの内容は変更されません。

request ゲッターの手順は、 this の リクエストを返すことです。

🚧 request 属性はこの版で新たに追加されました。 Chrome 76、Edge 79、Firefox 77、および Safari 15 でサポートされています。 🚧
次のメソッドはカーソルを前進させます。 カーソルが 前進すると、カーソルを開いたときに返された同じ IDBRequest に対して success イベントが発火されます。 範囲内にレコードが あった場合、result は同じカーソルになり、それ以外の場合は undefined になります。

カーソルがすでに前進中に呼び出された場合、"InvalidStateError" DOMException がスローされます。

次のメソッドは、トランザクションが アクティブでないときに 呼び出された場合、"TransactionInactiveError" DOMException をスローします。

cursor . advance(count)

範囲内の次の count 個のレコードを通過して カーソルを前進させます。

cursor . continue()

カーソルを範囲内の次のレコードへ前進させます。

cursor . continue(key)

カーソルを、範囲内で key に一致するか それ以降の次のレコードへ前進させます。

cursor . continuePrimaryKey(key, primaryKey)

カーソルを、範囲内で key と primaryKey に一致するかそれ以降の次のレコードへ前進させます。ソースが インデックスでない場合、 "InvalidAccessError" DOMException をスローします。

advance(count) メソッドの手順は次のとおりです。

  1. count が0(ゼロ)の場合、TypeError をスローします。

  2. transaction をthis のトランザクションとします。

  3. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  4. this のソースまたは実効 オブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. this の値取得フラグが false の場合、これは カーソルが反復中であるか、末尾を越えて反復済みであることを示すため、 "InvalidStateError" DOMException をスローします。

  6. this の値取得フラグを false に設定します。

  7. request をthis のリクエストとします。

  8. request の処理済みフラグを false に設定します。

  9. request の完了フラグを false に設定します。

  10. operation を、現在の Realm レコード、this、および count を用いてカーソルを反復するを実行するアルゴリズムとします。

  11. this のソースハンドル、 operation、および request を用いてリクエストを非同期に実行するを実行します。

注記: 新しいカーソルデータが読み込まれる前にこのメソッドを複数回 呼び出すと、たとえば同じ onsuccess ハンドラーから advance() を2回呼び出すと、 2回目の呼び出しでは、カーソルの値取得フラグが false に設定されているため、"InvalidStateError" DOMException がスローされます。

continue(key) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  3. this のソースまたは 実効オブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. this の値取得フラグが false の場合、これは カーソルが反復中であるか、末尾を越えて反復済みであることを示すため、 "InvalidStateError" DOMException をスローします。

  5. key が指定されている場合:

    1. r を、key を用いて値を キーに変換する結果とします。例外があれば再スローします。

    2. r が "invalid value" または "invalid type" である場合、 "DataError" DOMException をスローします。

    3. key を r とします。

    4. key がthis の 位置より小さいか等しく、かつthis の方向が "next" または "nextunique" の場合、"DataError" DOMException をスローします。

    5. key がthis の 位置より大きいか等しく、かつthis の方向が "prev" または "prevunique" の場合、"DataError" DOMException をスローします。

  6. this の値取得フラグを false に設定します。

  7. request をthis のリクエストとします。

  8. request の処理済みフラグを false に設定します。

  9. request の完了フラグを false に設定します。

  10. operation を、現在の Realm レコード、this、および key(指定されている場合)を用いてカーソルを反復するを実行するアルゴリズムとします。

  11. this のソースハンドル、 operation、および request を用いてリクエストを非同期に実行するを実行します。

注記: 新しいカーソルデータが読み込まれる前にこのメソッドを複数回 呼び出すと、たとえば同じ onsuccess ハンドラーから continue() を2回呼び出すと、 2回目の呼び出しでは、カーソルの 値取得フラグが false に設定されているため、"InvalidStateError" DOMException がスローされます。

continuePrimaryKey(key, primaryKey) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  3. this のソースまたは実効 オブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. this のソースが インデックスでない場合、 "InvalidAccessError" DOMException をスローします。

  5. this の方向が "next" または "prev" でない場合、 "InvalidAccessError" DOMException をスローします。

  6. this の値取得フラグが false の場合、これは カーソルが反復中であるか、末尾を越えて反復済みであることを示すため、 "InvalidStateError" DOMException をスローします。

  7. r を、key を用いて値をキーに変換する結果とします。 例外があれば再スローします。

  8. r が "invalid value" または "invalid type" である場合、 "DataError" DOMException をスローします。

  9. key を r とします。

  10. r を、primaryKey を用いて値をキーに変換する結果とします。 例外があれば再スローします。

  11. r が "invalid value" または "invalid type" である場合、 "DataError" DOMException をスローします。

  12. primaryKey を r とします。

  13. key がthis の 位置より小さく、かつ this の方向が "next" の場合、 "DataError" DOMException をスローします。

  14. key がthis の 位置より大きく、かつ this の方向が "prev" の場合、 "DataError" DOMException をスローします。

  15. key がthis の位置と等しく、 primaryKey がthis の オブジェクトストア位置より小さいか等しく、かつthis の方向が "next" の場合、 "DataError" DOMException をスローします。

  16. key がthis の位置と等しく、 primaryKey がthis の オブジェクトストア位置より大きいか等しく、かつthis の 方向が "prev" の場合、 "DataError" DOMException をスローします。

  17. this の値取得フラグを false に設定します。

  18. request をthis のリクエストとします。

  19. request の処理済みフラグを false に設定します。

  20. request の完了フラグを false に設定します。

  21. operation を、現在の Realm レコード、this、key、 および primaryKey を用いてカーソルを反復するを実行するアルゴリズムとします。

  22. this のソースハンドル、 operation、および request を用いてリクエストを非同期に実行するを実行します。

注記: 新しいカーソルデータが読み込まれる前にこのメソッドを複数回 呼び出すと、たとえば同じ onsuccess ハンドラーから continuePrimaryKey() を2回 呼び出すと、2回目の呼び出しでは、カーソルの値取得フラグが false に設定されているため、"InvalidStateError" DOMException がスローされます。

次のメソッドは、 読み取り専用トランザクション内で呼び出された場合、"ReadOnlyError" DOMException をスローし、トランザクションがアクティブでないときに 呼び出された場合は "TransactionInactiveError" DOMException をスローします。
request = cursor . update(value)

カーソルが指すレコードを新しい値で更新します。

実効オブジェクトストアが インラインキーを使用しており、キーが変更されることになる場合、 "DataError" DOMException をスローします。

成功した場合、request の result は レコードのキーになります。

request = cursor . delete()

新しい値を持つカーソルが指すレコードを削除します。

成功した場合、request の result は undefined になります。

update(value) メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  3. transaction が読み取り専用トランザクションである場合、 "ReadOnlyError" DOMException をスローします。

  4. this のソースまたは実効 オブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. this の値取得フラグが false の場合、これは カーソルが反復中であるか、末尾を越えて反復済みであることを示すため、 "InvalidStateError" DOMException をスローします。

  6. this のキーのみフラグが true の場合、 "InvalidStateError" DOMException をスローします。

  7. targetRealm をユーザーエージェントが定義するRealm とします。

  8. clone を、transaction 中の targetRealm における value のクローンとします。 例外があれば再スローします。

    なぜ値のコピーを作成するのですか? 値は保存時にシリアライズされます。ここでコピーとして扱うことで、 この仕様の他のアルゴリズムはこれを ECMAScript 値として扱うことができますが、 動作の違いが観測可能でない場合、実装はこれを 最適化できます。
  9. this の実効 オブジェクトストアがインラインキーを使用する場合:

    1. kpk を、 clone とthis の実効オブジェクト ストアのキーパスを用いてキーパスを使用して 値からキーを抽出する結果とします。 例外があれば再スローします。

    2. kpk が failure、invalid、またはthis の実効 キーと等しくない場合、 "DataError" DOMException をスローします。

  10. operation を、this の実効 オブジェクトストア、clone、this の実効キー、および false を用いてレコードを オブジェクトストアに格納するを実行するアルゴリズムとします。

  11. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: レコードをオブジェクトストアに格納する結果として、 カーソルがレコードへ移動した後にそのレコードが削除されていた場合、 新しいレコードが作成されます。

delete() メソッドの手順は次のとおりです。

  1. transaction をthis のトランザクションとします。

  2. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  3. transaction が読み取り専用トランザクションである場合、 "ReadOnlyError" DOMException をスローします。

  4. this のソースまたは実効 オブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  5. this の値取得フラグが false の場合、これは カーソルが反復中であるか、末尾を越えて反復済みであることを示すため、 "InvalidStateError" DOMException をスローします。

  6. this のキーのみフラグが true の場合、 "InvalidStateError" DOMException をスローします。

  7. operation を、this の実効 オブジェクトストアとthis の実効キーを用いてオブジェクトストアから レコードを削除するを実行するアルゴリズムとします。

  8. this と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

カーソルのキーのみフラグが false に設定されている場合、そのカーソルは IDBCursorWithValue インターフェイスも実装します。

[Exposed=(Window,Worker)]
interface IDBCursorWithValue : IDBCursor {
  readonly attribute any value;
};
cursor . 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();

  // イベントハンドラー:
  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 ゲッターの手順は次のとおりです。

  1. names を、this のスコープ内のオブジェクトストアの名前のリストとします。

  2. names を用いてソート済み名前リストを作成する結果(DOMStringList)を返します。

注記: この属性によって返される各リストの内容は 変化しませんが、アップグレードトランザクション中にこの属性を後で呼び出すと、 オブジェクトストアが作成または 削除されるため、異なる内容のリストが返されることがあります。

mode ゲッターの手順は、 this の モードを返すことです。

durability ゲッターの手順は、this の耐久性 ヒントを返すことです。

🚧 durability 属性はこの版で新たに追加されました。 Chrome 82、Edge 82、Firefox 126、および Safari 15 でサポートされています。 🚧

db ゲッターの手順は、 this の 接続に 関連付けられたデータベースを返すことです。

error ゲッターの手順は、 this の エラーを返し、存在しない場合は null を返すことです。

注記: このトランザクションが失敗した リクエストによって 中止された場合、これはリクエストの エラーと同じになります。このトランザクションが イベントハンドラー内の捕捉されなかった例外によって 中止された場合、エラーは "AbortError" DOMException になります。 トランザクションが コミット中のエラーによって中止された場合は、 失敗の理由(たとえば QuotaExceededError、 "ConstraintError" または "UnknownError" DOMException)を反映します。

transaction . objectStore(name)

トランザクションのスコープ内の IDBObjectStore を返します。

transaction . abort()

トランザクションを中止します。すべての保留中のリクエストは "AbortError" DOMException で失敗し、データベースに加えられたすべての変更は 元に戻されます。

transaction . commit()

トランザクションのコミットを試みます。すべての保留中のリクエストは完了できますが、 新しいリクエストは受け付けられません。これは、通常のコミットを試みる前に 保留中のリクエストが success イベントを発火するのを待たずに、トランザクションを迅速に完了させるために使用できます。

保留中のリクエストが、たとえば制約エラーによって失敗した場合、トランザクションは中止されます。 成功したリクエストの success イベントは引き続き発火されますが、イベントハンドラーで例外をスローしても トランザクションは中止されません。同様に、失敗したリクエストの error イベントも引き続き発火されますが、preventDefault() を呼び出しても トランザクションの中止を防ぐことはできません。

objectStore(name) メソッドの手順は 次のとおりです。

  1. this の状態が完了である場合、 "InvalidStateError" DOMException をスローします。

  2. store を、this の スコープ内の name という名前のオブジェクト ストアとし、存在しない場合は "NotFoundError" DOMException をスローします。

  3. store とthis に関連付けられたオブジェクト ストアハンドルを返します。

注記: 同じ IDBTransaction インスタンスで同じ名前を指定してこのメソッドを呼び出すたびに、 同じ IDBObjectStore インスタンスが返されます。

注記: 返される IDBObjectStore インスタンスは、この IDBTransaction に固有です。 このメソッドが別の IDBTransaction で呼び出された場合、別の IDBObjectStore インスタンスが 返されます。

abort() メソッドの手順は次のとおりです。

  1. this の状態がコミット中 または完了である場合、 "InvalidStateError" DOMException をスローします。

  2. this と null を用いてトランザクションを 中止するを実行します。

commit() メソッドの手順は次のとおりです。

  1. this の状態がアクティブでない場合、 "InvalidStateError" DOMException をスローします。

  2. this を用いてトランザクションを コミットするを実行します。

🚧 commit() メソッドはこの版で新たに追加されました。 Chrome 76、Edge 79、Firefox 74、および Safari 15 でサポートされています。 🚧

注記: 通常、トランザクションに対して commit() を呼び出す必要はありません。 トランザクションは、未処理のすべてのリクエストが完了し、新しい リクエストが行われなくなると、自動的にコミットされます。この呼び出しを使用すると、 未処理のリクエストからのイベントが ディスパッチされるのを待たずに、コミット処理を 開始できます。

onabort 属性は、イベントハンドラーイベント型が abort であるイベントハンドラー IDL 属性です。

oncomplete 属性は、イベントハンドラーイベント型が complete であるイベントハンドラー IDL 属性です。

onerror 属性は、イベントハンドラーイベント型が error であるイベントハンドラー IDL 属性です。

注記: トランザクションが正常に完了したかどうかを判断するには、 特定のリクエストの success イベントではなく、トランザクションの complete イベントを待ち受けてください。これは、 success イベントが発火した後でも、トランザクションが 失敗する可能性があるためです。

5. アルゴリズム

5.1. データベース接続を開く

開くよう要求されたデータベースの storageKey、データベースの name、 データベースの version、および request を用いてデータベース 接続を開くには、次の手順を実行します。

  1. queue を、storageKey と name の接続キューとします。

  2. request を queue に追加します。

  3. queue 内の以前のすべてのリクエストが処理されるまで待ちます。

  4. db を、storageKey 内の name という名前のデータベースとし、 それ以外の場合は null とします。

  5. version が undefined の場合、db が null なら version を1とし、 それ以外の場合は db のバージョンとします。

  6. db が null の場合、db を、 名前が name、バージョンが0(ゼロ)で、 オブジェクトストアを持たない新しいデータベースとします。 何らかの理由で失敗した場合は、適切な エラー(たとえば QuotaExceededError、 または "UnknownError" DOMException)を返します。

  7. db のバージョンが version より大きい場合、 新しく作成された "VersionError" DOMException を返し、この手順を中止します。

  8. connection を db への新しい接続とします。

  9. connection のバージョンを version に設定します。

  10. db のバージョンが version より小さい場合:

    1. openConnections を、db に関連付けられた connection を除くすべての接続の集合とします。

    2. openConnections の各 entry のうち、 クローズ保留フラグが true に設定されていないものについてそれぞれ、 entry に versionchange という名前のバージョン変更イベントを発火するためにデータベースタスクを キューに入れます。その際、 db のバージョンと version を使用します。

      注記: このイベントを発火すると、openConnections 内の他の オブジェクトの1つ以上が閉じられる可能性があります。その場合、 それらのオブジェクトでは、まだ実行されていなくても versionchange イベントは発火されません。

    3. すべてのイベントが発火されるまで待ちます。

    4. openConnections 内のいずれかの接続がまだ 閉じられていない場合、request に blocked という名前のバージョン変更 イベントを発火するためにデータベースタスクをキューに入れます。 その際、db のバージョンと version を使用します。

    5. openConnections 内のすべての 接続が 閉じられるまで待ちます。

    6. connection、version、および request を使用してデータベースを アップグレードするを実行します。

    7. connection が閉じられた場合、 新しく作成された "AbortError" DOMException を返し、この手順を中止します。

    8. request のエラーが設定されている場合、 connection を用いてデータベース接続を閉じる手順を実行し、 新しく作成された "AbortError" DOMException を返し、この手順を中止します。

  11. connection を返します。

5.2. データベース接続を閉じる

connection オブジェクトと、任意の forced flag を用いてデータベース 接続を閉じるには、次の手順を実行します。

  1. connection のクローズ保留フラグを true に設定します。

  2. forced flag が true の場合、connection を使用して作成された各 transaction について、 transaction と新しく作成された "AbortError" DOMException を用いてトランザクションを 中止するを実行します。

  3. connection を使用して作成されたすべてのトランザクションが完了するまで待ちます。 それらが完了すると、connection は閉じられます。

  4. forced flag が true の場合、connection に close という名前のイベントを発火します。

    注記: close イベントは、接続が異常に閉じた場合、たとえばストレージ キーのストレージが消去された場合、または破損や I/O エラーがある場合にのみ発火します。 close() が明示的に呼び出された場合、 このイベントは発火しません。

注記: 接続のクローズ 保留フラグが true に設定されると、その 接続を使用して新しい トランザクションを作成 することはできません。トランザクションを 作成する すべてのメソッドは、まず接続の クローズ 保留フラグを確認し、 true の場合は例外をスローします。

注記: 接続が閉じられると、 指定されたデータベースへの 接続が閉じられるまで 待つデータベースをアップグレードする手順と、 同じく待つデータベースを 削除する手順のブロックが解除され、処理を続行できます。

5.3. データベースを削除する

削除するよう要求されたデータベースの storageKey、データベースの name、および request を用いてデータベースを 削除するには、次の手順を実行します。

  1. queue を、storageKey と name の接続キューとします。

  2. request を queue に追加します。

  3. queue 内の以前のすべてのリクエストが処理されるまで待ちます。

  4. db を、存在する場合は storageKey 内の name という名前のデータベースとします。それ以外の場合は0(ゼロ)を返します。

  5. openConnections を、db に関連付けられたすべての 接続の集合とします。

  6. openConnections の各 entry のうち、 クローズ保留フラグが true に設定されていないものについてそれぞれ、 entry に versionchange という名前のバージョン変更イベントを発火するためにデータベース タスクをキューに入れます。その際、 db のバージョン と null を使用します。

    注記: このイベントを発火すると、openConnections 内の他のオブジェクトの 1つ以上が閉じられる可能性があります。その場合、 それらのオブジェクトでは、まだ実行されていなくても versionchange イベントは発火されません。

  7. すべてのイベントが発火されるまで待ちます。

  8. openConnections 内のいずれかの接続がまだ閉じられていない場合、 request に blocked という名前のバージョン変更 イベントを発火するためにデータベース タスクをキューに入れます。その際、db の バージョンと null を使用します。

  9. openConnections 内のすべての 接続が 閉じられるまで 待ちます。

  10. version を db のバージョンとします。

  11. db を削除します。何らかの理由で失敗した場合は、適切な エラー(たとえば QuotaExceededError、 または "UnknownError" DOMException)を返します。

  12. version を返します。

5.4. トランザクションをコミットする

コミットする transaction を用いてトランザクションを コミットするには、次の手順を実行します。

  1. transaction の状態をコミット中に設定します。

  2. 次の手順を並列に実行します。

    1. transaction のリクエスト リスト内のすべての項目が処理済みになるまで待ちます。

    2. transaction の状態がもはやコミット中でない場合、 この手順を終了します。

    3. transaction の耐久性ヒントを考慮しながら、 transaction によって行われた未書き込みの変更をデータベースに 書き込むことを試みます。

    4. 変更をデータベースに書き込んでいる間にエラーが発生した場合、 transaction と、そのエラーに適した型、たとえば QuotaExceededError または "UnknownError" DOMException を用いてトランザクションを 中止するを実行し、 この手順を終了します。

    5. 次の手順を実行するためにデータベース タスクをキューに入れます。

      1. transaction がアップグレード トランザクションである場合、 transaction の接続に関連付けられたデータベースの アップグレードトランザクションを null に設定します。

      2. transaction の状態を完了に設定します。

      3. transaction に complete という名前のイベントを発火します。

        注記: このイベントのイベントハンドラーの1つから例外がスローされた場合でも、 データベースの変更の書き込みはイベントが発生する前に行われるため、 トランザクションは引き続きコミットされます。 トランザクションが正常に書き込まれた後にのみ、 complete イベントが発火されます。

      4. transaction がアップグレード トランザクションである場合、 request を transaction に関連付けられたリクエストとし、 request のトランザクションを null に設定します。

5.5. トランザクションを中止する

中止する transaction と error を用いてトランザクションを 中止するには、次の手順を実行します。

  1. transaction の状態が完了である場合、この 手順を中止します。

  2. トランザクションによってデータベースに 加えられたすべての変更を元に戻します。アップグレードトランザクションの場合、これには オブジェクト ストアおよびインデックスの集合への変更、 ならびにバージョンの変更も含まれます。 トランザクション中に作成されたすべてのオブジェクトストアおよび インデックスは、 他のアルゴリズムの目的上、削除されたものと見なされます。

  3. transaction がアップグレードトランザクションである場合、 transaction を用いてアップグレードトランザクションを中止する手順を実行します。

    注記: これにより、transaction に関連付けられたすべての接続、オブジェクトストアハンドル、および インデックスハンドル インスタンスへの変更が元に戻されます。

  4. transaction の状態を完了に設定します。

  5. transaction のエラーを error に設定します。

  6. transaction のリクエストリストの各 request についてそれぞれ、 request に対するリクエストを非同期に実行する手順を中止し、 request の処理済みフラグを true に設定し、 次の手順を実行するためにデータベース タスクをキューに入れます。

    1. request の完了フラグを true に設定します。

    2. request の結果を undefined に設定します。

    3. request のエラーを、新しく 作成された "AbortError" DOMException に設定します。

    4. request に error という名前のイベントを発火し、 その bubbles および cancelable 属性を true で初期化します。

    注記: これによって常に error イベントが発火されるわけではありません。 たとえば、トランザクションのコミット中のエラーによってトランザクションが中止された場合や、 失敗したリクエストが最後に残っていたリクエストである場合です。

  7. 次の手順を実行するためにデータベース タスクをキューに入れます。

    1. transaction がアップグレードトランザクションである場合、 transaction の 接続に関連付けられたデータベースのアップグレード トランザクションを null に設定します。

    2. transaction に abort という名前のイベントを発火し、 その bubbles 属性を true で初期化します。

    3. transaction がアップグレードトランザクションである場合:

      1. request を transaction に関連付けられたオープン リクエストとします。

      2. request のトランザクションを null に設定します。

      3. request の結果を undefined に設定します。

      4. request の処理済みフラグを false に設定します。

      5. request の完了フラグを false に設定します。

5.6. リクエストを非同期に実行する

データベース上で実行する operation を持つ source オブジェクトと、任意の request を用いてリクエストを非同期に実行するには、次の手順を実行します。

作成されたリクエストが属するトランザクションがトランザクションを 中止する手順を使用して中止された場合、 これらの手順は任意の時点で中止できます。

  1. transaction を source に関連付けられたトランザクションとします。

  2. 表明: transaction の状態はアクティブです。

  3. request が指定されていない場合、request を、ソースが source である新しいリクエストとします。

  4. request を transaction のリクエストリストの末尾に追加します。

  5. 次の手順を並列に実行します。

    1. request が、transaction のリクエストリスト内で 処理済みでない最初の項目になるまで待ちます。

    2. result を operation を実行した結果とします。

    3. result がエラーであり、transaction の状態がコミット中である場合、 transaction と result を用いてトランザクションを 中止するを実行し、 この手順を終了します。

    4. result がエラーの場合、 operation によって行われたすべての変更を元に戻します。

      注記: これは、このリクエストによって行われた変更のみを元に戻し、 トランザクションによって行われた他の変更は元に戻しません。

    5. request の処理済みフラグを true に設定します。

    6. 次の手順を実行するためにデータベース タスクをキューに入れます。

      1. request を transaction のリクエストリストから削除します。

      2. request の完了フラグを true に設定します。

      3. result がエラーの場合:

        1. request の結果を undefined に設定します。

        2. request のエラーを result に設定します。

        3. request にerror イベントを発火するを実行します。

      4. それ以外の場合:

        1. request の結果を result に設定します。

        2. request のエラーを undefined に設定します。

        3. request にsuccess イベントを発火するを実行します。

  6. request を返します。

5.7. データベースをアップグレードする

connection(接続)、新しい version、および request を用いてデータベースを アップグレードするには、次の手順を実行します。

  1. db を connection のデータベースとします。

  2. transaction を、connection を接続として使用する新しいアップグレードトランザクションとします。

  3. transaction のスコープを connection のオブジェクトストア集合に設定します。

  4. db のアップグレードトランザクションを transaction に設定します。

  5. transaction の状態を非アクティブに設定します。

  6. transaction を開始します。

    注記: このトランザクションが完了するまで、 同じデータベースへの 他の接続を 開くことはできないことに注意してください。

  7. old version を db のバージョンとします。

  8. db のバージョンを version に設定します。この変更は トランザクションの一部と見なされるため、 トランザクションが中止された場合、この変更は元に戻されます。

  9. request の処理済みフラグを true に設定します。

  10. 次の手順を実行するためにデータベース タスクをキューに入れます。

    1. request の結果を connection に設定します。

    2. request のトランザクションを transaction に設定します。

    3. request の完了フラグを true に設定します。

    4. transaction の状態をアクティブに設定します。

    5. didThrow を、 request に upgradeneeded という名前のバージョン変更イベントを発火する結果とし、 old version と version を使用します。

    6. transaction の状態がアクティブである場合:

      1. transaction の状態を非アクティブに設定します。

      2. didThrow が true の場合、transaction と新しく 作成された "AbortError" DOMException を用いてトランザクションを 中止するを実行します。

  11. transaction が完了するまで待ちます。

    注記: トランザクションの 存続期間中に呼び出されるアルゴリズムの一部、 たとえばトランザクションを コミットする手順やトランザクションを中止する手順には、 アップグレードトランザクションに固有の手順が含まれます。

5.8. アップグレードトランザクションを中止する

transaction を用いてアップグレード トランザクションを中止するには、次の手順を実行します。

注記: これらの手順は、データベースへの変更、 関連付けられたオブジェクト ストアとインデックスの集合、および バージョンへの変更を元に戻す、 トランザクションを中止する手順によって必要に応じて実行されます。

  1. connection を transaction の接続とします。

  2. database を connection のデータベースとします。

  3. database が以前から存在していた場合は、 connection のバージョンを database の バージョンに設定し、 database が新しく作成された場合は0(ゼロ)に設定します。

    注記: これにより、IDBDatabase オブジェクトによって返される version の値が元に戻されます。

  4. database が以前から存在していた場合は、 connection のオブジェクトストア集合を database 内のオブジェクトストアの集合に設定し、 database が新しく作成された場合は空集合に設定します。

    注記: これにより、IDBDatabase オブジェクトによって返される objectStoreNames の値が元に戻されます。

  5. transaction に関連付けられた各オブジェクト ストアハンドル handle について、transaction 中に 作成または削除されたオブジェクトストアのものも含めて:

    1. handle のオブジェクトストアが transaction 中に新しく作成されたものでない場合、 handle の名前を、その オブジェクトストアの名前に設定します。

    2. handle のインデックス集合を、その オブジェクトストアを参照するインデックスの集合に設定します。

    注記: これにより、関連する IDBObjectStore オブジェクトによって返される name および indexNames の値が元に戻されます。

    これはどのように観測できますか? スクリプトは、トランザクションが 中止された後、IDBTransaction インスタンスの objectStore() メソッドを使用してオブジェクトストアにアクセスすることはできませんが、 name および indexNames プロパティを照会できる IDBObjectStore インスタンスへの参照を保持している可能性があります。
  6. transaction に関連付けられた各インデックス ハンドル handle について、 transaction 中に作成または削除されたインデックスのものも含めて:

    1. handle のインデックスが transaction 中に新しく作成されたものでない場合、 handle の名前を、 そのインデックスの名前に設定します。

    注記: これにより、関連する IDBIndex オブジェクトによって返される name の値が元に戻されます。

    これはどのように観測できますか? スクリプトは、トランザクションが 中止された後、IDBObjectStore インスタンスの index() メソッドを使用してインデックスにアクセスすることはできませんが、 name プロパティを照会できる IDBIndex インスタンスへの参照を保持している可能性があります。

注記: 中止されたアップグレードトランザクションが 新しいデータベースを作成していた場合でも、 IDBDatabase インスタンスの name プロパティは変更されません。

5.9. 成功 イベントを発火する

request にsuccess イベントを発火するには、次の手順を実行します。

  1. event を、Event を使用してイベントを 作成する結果とします。

  2. event の type 属性を "success" に設定します。

  3. event の bubbles および cancelable 属性を false に設定します。

  4. transaction を request のトランザクションとします。

  5. legacyOutputDidListenersThrowFlag を最初は false とします。

  6. transaction の状態が非アクティブである場合、 transaction の状態をアクティブに設定します。

  7. legacyOutputDidListenersThrowFlag を指定して、 request に event をディスパッチします。

  8. transaction の状態がアクティブである場合:

    1. transaction の状態を非アクティブに設定します。

    2. legacyOutputDidListenersThrowFlag が true の場合、 transaction と新しく作成された "AbortError" DOMException を用いてトランザクションを 中止するを実行します。

    3. transaction のリクエストリストが空の場合、 transaction を用いてトランザクションを コミットするを実行します。

5.10. エラー イベントを発火する

request にerror イベントを発火するには、次の手順を実行します。

  1. event を、Event を使用してイベントを 作成する結果とします。

  2. event の type 属性を "error" に設定します。

  3. event の bubbles および cancelable 属性を true に設定します。

  4. transaction を request のトランザクションとします。

  5. legacyOutputDidListenersThrowFlag を最初は false とします。

  6. transaction の状態が非アクティブである場合、 transaction の状態をアクティブに設定します。

  7. legacyOutputDidListenersThrowFlag を指定して、 request に event をディスパッチします。

  8. transaction の状態がアクティブである場合:

    1. transaction の状態を非アクティブに設定します。

    2. legacyOutputDidListenersThrowFlag が true の場合、 transaction と新しく作成された "AbortError" DOMException を用いてトランザクションを 中止するを実行し、この手順を終了します。 これは、event のキャンセル済みフラグが false の場合でも行われます。

      注記: これは、error イベントが発火され、いずれかのイベント ハンドラーが例外をスローした場合、transaction の error プロパティが、request のエラーではなく AbortError に設定されることを意味します。これは、preventDefault() が一度も呼び出されなかった場合でも同様です。

    3. event のキャンセル済みフラグが false の場合、 transaction とrequest の エラーを用いてトランザクションを 中止するを実行し、この手順を終了します。

    4. transaction のリクエストリストが空の場合、 transaction を用いてトランザクションを コミットするを実行します。

5.11. 値をクローンする

transaction 中の targetRealm における value のクローンを作成するには、 次の手順を実行します。

  1. 表明: transaction の状態はアクティブです。

  2. transaction の状態を非アクティブに設定します。

    注記: クローン操作によってトリガーされるゲッターやその他の副作用が トランザクションに対して追加のリクエストを行えないようにするため、 トランザクションを 非アクティブにします。

  3. serialized を ? StructuredSerializeForStorage(value) とします。

  4. clone を ? StructuredDeserialize(serialized, targetRealm) とします。

  5. transaction の状態をアクティブに設定します。

  6. clone を返します。

5.12. 複数の項目を取得するリクエストを作成する

targetRealm、sourceHandle、kind、queryOrOptions、および任意の count を用いて、オブジェクトストアまたはインデックスから複数の項目を取得するリクエストを作成するには、次の手順を実行します。

  1. source を、sourceHandle から得られるインデックスまたはオブジェクトストアとします。 sourceHandle がインデックスハンドルである場合、source はインデックス ハンドルに関連付けられたインデックスです。 それ以外の場合、source はオブジェクトストアハンドルに関連付けられたオブジェクト ストアです。

  2. source が削除されている場合、 "InvalidStateError" DOMException をスローします。

  3. source がインデックスであり、source のオブジェクトストアが削除されている場合、 "InvalidStateError" DOMException をスローします。

  4. transaction を sourceHandle のトランザクションとします。

  5. transaction の状態がアクティブでない場合、 "TransactionInactiveError" DOMException をスローします。

  6. range をキー 範囲とします。

  7. direction をカーソル方向とします。

  8. queryOrOptions を用いて潜在的に有効なキー範囲であるを実行した結果が true の場合:

    1. range を、queryOrOptions を用いて値をキー範囲に変換する結果に設定します。 例外があれば再スローします。

    2. direction を "next" に設定します。

  9. それ以外の場合:

    1. range を、queryOrOptions["query"] を用いて値をキー範囲に変換する結果に設定します。 例外があれば再スローします。

    2. count を queryOrOptions["count"] に設定します。

    3. direction を queryOrOptions["direction"] に設定します。

  10. operation を実行するアルゴリズムとします。

  11. source がインデックスである場合、operation を、 targetRealm、source、range、kind、 direction、および指定されている場合は count を用いてインデックスから 複数の項目を取得するに設定します。

  12. それ以外の場合、operation を、 targetRealm、source、range、 kind、direction、および指定されている場合は count を用いてオブジェクトストアから複数の項目を 取得するに設定します。

  13. sourceHandle と operation を用いてリクエストを非同期に実行するを実行した 結果(IDBRequest)を返します。

注記: range には、取得するレコード項目を識別するキーまたはキー範囲(IDBKeyRange)を指定できます。 null または未指定の場合、境界のないキー 範囲が使用されます。 count が指定されていて、範囲内に count 件を超えるレコードがある場合、 最初の count 件だけが取得されます。

6. データベース操作

この節では、データベース内の オブジェクトストアおよびインデックス内のデータに対して行われるさまざまな操作について説明します。 これらの操作は、リクエストを非同期に実行する手順によって実行されます。

注記: 以下の操作手順における StructuredDeserialize() の呼び出しは、(! 接頭辞で示されるように)スローしないと表明できます。 これは、それらが以前の StructuredSerializeForStorage() の出力に対してのみ動作するためです。

6.1. オブジェクトストア格納操作

store、value、任意の key、および no-overwrite flag を用いてレコードを オブジェクトストアに格納するには、 次の手順を実行します。

  1. store がキー ジェネレーターを使用する場合:

    1. key が undefined の場合:

      1. key を、 store のためにキーを生成する結果とします。

      2. key が failure の場合、この操作は "ConstraintError" DOMException で失敗します。 これ以上の手順を実行せず、この アルゴリズムを中止します。

      3. store がインラインキーも使用する場合、 value、key、および store のキーパスを用いてキーパスを使用してキーを値に注入する を実行します。

    2. それ以外の場合、store と key を用いてキージェネレーターを更新する可能性がある を実行します。

  2. no-overwrite flag がこれらの手順に与えられていて true であり、 レコードがすでに store 内に存在し、その キーが key と等しい場合、 この操作は "ConstraintError" DOMException で失敗します。 これ以上の手順を実行せず、このアルゴリズムを中止します。

  3. レコードが store 内にすでに存在し、その キーが key と等しい場合、 オブジェクトストアからレコードを削除するを使用して、 レコードを store から削除します。

  4. store に、key をキーとして含み、 ! StructuredSerializeForStorage(value) を値として含むレコードを格納します。レコードは、オブジェクトストアの レコード リストに、レコードのキーに従って昇順にソートされるように格納されます。

  5. store を参照する各 index について:

    1. index key を、 value、index のキーパス、および index の multiEntry フラグを用いてキーパスを使用して値からキーを抽出する結果とします。

    2. index key が例外、invalid、または failure の場合、 index に対してそれ以上の操作を行わず、 次のインデックスについてこれらの手順を続行します。

      注記: この手順でスローされた例外は再スローされません。

    3. index のmultiEntry フラグが false であるか、index key が配列 キーでなく、かつ index がすでに レコードを含み、その キーが index key と等しく、かつ index の一意フラグが true の場合、この 操作は "ConstraintError" DOMException で失敗します。 これ以上の手順を実行せず、この アルゴリズムを中止します。

    4. index のmultiEntry フラグが true で、index key が 配列キーであり、 index がすでに レコードを含み、その キーが index key のいずれかのサブキーと等しく、かつ index の一意フラグが true の場合、この操作は "ConstraintError" DOMException で失敗します。 これ以上の手順を実行せず、このアルゴリズムを 中止します。

    5. index のmultiEntry フラグが false であるか、index key が配列 キーでない場合、index に、 index key をキーとして、key を値として含むレコードを格納します。 レコードは index のレコード リストに、 第一にレコードのキー、第二にレコードの値によって、昇順にソートされるように格納されます。

    6. index のmultiEntry フラグが true で、index key が 配列キーである場合、 index key の サブキーの各 subkey について、subkey をキーとして、key を値として含むレコードを index に格納します。 レコードは index のレコード リストに、第一に レコードのキー、第二にレコードの値によって、 昇順に ソートされるように格納されます。

      注記: サブキーが存在しないことも有効です。この場合、 インデックスにはレコードが追加されません。

      注記: サブキーのいずれかのメンバー自体が 配列 キーであっても、 そのメンバーはインデックスレコードのキーとして直接使用されます。 ネストされた配列キーは、 複数の行を生成するために平坦化または「展開」されません。対象となるのは最も外側の配列キーだけです。

  6. key を返します。

6.2. オブジェクトストア取得操作

targetRealm、store、および range を用いてオブジェクトストアから値を取得するには、 次の手順を実行します。 これらは undefined、ECMAScript 値、またはエラー(DOMException)を返します。

  1. record を、存在する場合、store の レコード リスト内で、そのキーが range 内にある最初のレコードとします。

  2. record が見つからなかった場合、undefined を返します。

  3. serialized を record の値とします。基盤ストレージから値を読み取る際にエラーが発生した場合、 新しく作成された "NotReadableError" DOMException を返します。

  4. ! StructuredDeserialize(serialized, targetRealm) を返します。

store と range を用いてオブジェクトストアから キーを取得するには、 次の手順を実行します。

  1. record を、存在する場合、store の レコード リスト内で、そのキーが range 内にある最初のレコードとします。

  2. record が見つからなかった場合、undefined を返します。

  3. record のキーを用いてキーを値に変換する結果を返します。

targetRealm、store、range、kind、direction、 および任意の count を用いてオブジェクトストアから複数の項目を取得するには、 次の手順を実行します。

  1. count が指定されていないか0(ゼロ)の場合、count を infinity とします。

  2. records をレコードの空のリストとします。

  3. direction が "next" または "nextunique" の場合、 records を、store のレコードリスト内で キーが range 内にある最初の count 件に設定します。

  4. direction が "prev" または "prevunique" の場合、 records を、store のレコードリスト内で キーが range 内にある最後の count 件に設定します。

  5. list を空のリストとします。

  6. records の各 record についてそれぞれ、kind に応じて:

    "key"
    1. key を、record のキーを用いてキーを値に変換する結果とします。

    2. key を list に追加します。

    "value"
    1. serialized を record の値とします。

    2. value を ! StructuredDeserialize(serialized, targetRealm) とします。

    3. value を list に追加します。

    "record"
    1. key を record のキーとします。

    2. serialized を record の値とします。

    3. value を ! StructuredDeserialize(serialized, targetRealm) とします。

    4. recordSnapshot を新しいレコードスナップショットとし、 そのキーを key に、値を value に、そして 主キーを key に設定します。

    5. recordSnapshot を list に追加します。

  7. list を返します。

6.3. インデックス取得操作

targetRealm、index、および range を用いてインデックスから参照値を取得するには、 次の手順を実行します。

  1. record を、存在する場合、index のレコードリスト内で、 キーが range 内にある最初のレコードとします。

  2. record が見つからなかった場合、undefined を返します。

  3. serialized を record の参照値とします。

  4. ! StructuredDeserialize(serialized, targetRealm) を返します。

index と range を用いてインデックスから 値を取得するには、 次の手順を実行します。

  1. record を、存在する場合、index のレコードリスト内で、 キーが range 内にある最初のレコードとします。

  2. record が見つからなかった場合、undefined を返します。

  3. record の値を用いてキーを値に変換する結果を返します。

targetRealm、index、range、kind、direction、 および任意の count を用いてインデックスから複数の項目を取得するには、 次の手順を実行します。

  1. count が指定されていないか0(ゼロ)の場合、count を infinity とします。

  2. records をレコードの空のリストとします。

  3. direction に応じて:

    "next"
    1. records を、index のレコードリスト内で、そのキーが range 内にある最初の count 件に設定します。

    "nextunique"
    1. rangeRecords を、index のレコードリスト内で、そのキーが range 内にあるレコードを含むリストとします。

    2. rangeRecordsLength を rangeRecords のサイズとします。

    3. i を0とします。

    4. i が rangeRecordsLength より小さい間:

      1. i を1増加させます。

      2. record のサイズが count と等しい場合、 中断します。

      3. |rangeRecords[i]| と |rangeRecords[i-1]| のキーを用いて2つのキーを比較する結果が等しい場合、 続行します。

      4. それ以外の場合、|rangeRecords[i]| を records に追加します。

    "prev"
    1. records を、index のレコードリスト内で、そのキーが range 内にある最後の count 件に設定します。

    "prevunique"
    1. rangeRecords を、index のレコードリスト内で、そのキーが range 内にあるレコードを含むリストとします。

    2. rangeRecordsLength を rangeRecords のサイズとします。

    3. i を0とします。

    4. i が rangeRecordsLength より小さい間:

      1. i を1増加させます。

      2. record のサイズが count と等しい場合、 中断します。

      3. |rangeRecords[i]| と |rangeRecords[i-1]| のキーを用いて2つのキーを比較する結果が等しい場合、 続行します。

      4. それ以外の場合、|rangeRecords[i]| を records の先頭に追加します。

  4. list を空のリストとします。

  5. records の各 record についてそれぞれ、kind に応じて:

    "key"
    1. key を、record の値を用いてキーを値に変換する結果とします。

    2. key を list に追加します。

    "value"
    1. serialized を record の参照値とします。

    2. value を ! StructuredDeserialize(serialized, targetRealm) とします。

    3. value を list に追加します。

    "record"
    1. index key を record のキーとします。

    2. key を record の値とします。

    3. serialized を record の参照値とします。

    4. value を ! StructuredDeserialize(serialized, targetRealm) とします。

    5. recordSnapshot を新しいレコードスナップショットとし、 そのキーを index key に、値を value に、そして 主キーを key に設定します。

    6. recordSnapshot を list に追加します。

  6. list を返します。

6.4. オブジェクトストア削除操作

store と range を用いてオブジェクトストアから レコードを削除するには、 次の手順を実行します。

  1. store のレコード リストから、キーが range 内にあるすべてのレコードを、存在する場合は削除します。

  2. store を参照する各 index について、 index のレコード リストから、その値が range 内にあるすべてのレコードを、存在する場合は削除します。

  3. undefined を返します。

6.5. レコード計数操作

source と range を用いて範囲内の レコードを数えるには、次の手順を実行します。

  1. count を、source のレコードリスト内でキーが range 内にあるレコードの数とします。

  2. count を返します。

6.6. オブジェクトストア消去操作

store を用いてオブジェクト ストアを消去するには、次の手順を実行します。

  1. store からすべてのレコードを削除します。

  2. store を参照する すべてのインデックスから、 すべての レコードを削除します。

  3. undefined を返します。

6.7. カーソル反復操作

targetRealm、cursor、反復先となる任意の key と primaryKey、および任意の count を用いてカーソルを 反復するには、次の 手順を実行します。

  1. source を cursor のソースとします。

  2. direction を cursor の方向とします。

  3. 表明: primaryKey が指定されている場合、source は インデックスであり、 direction は "next" または "prev" です。

  4. records を source 内のレコードのリストとします。

    注記: records は常にキーの昇順でソートされています。 source がインデックスである場合、records はさらに値の昇順で二次的にソートされます (インデックス内の値は、 参照されるオブジェクトストア内の レコードの キーです)。

  5. range を cursor の範囲とします。

  6. position を cursor の位置とします。

  7. object store position を cursor のオブジェクトストア 位置とします。

  8. count が指定されていない場合、count を1とします。

  9. count が0より大きい間:

    1. direction に応じて:

      "next"

      found record を、records 内で 次の要件をすべて満たす最初のレコードとします。

      • key が定義されている場合:

      • primaryKey が定義されている場合:

        • レコードのキーが key と等しく、 レコードの値が primaryKey より大きいか等しいものとします。

        • レコードのキーが key より大きいものとします。

      • position が定義され、source がオブジェクトストアである場合:

        • レコードのキーが position より大きいものとします。

      • position が定義され、source がインデックスである場合:

        • レコードのキーが position と等しく、 レコードの値が object store position より大きいものとします。

        • レコードのキーが position より大きいものとします。

      • レコードのキーが range 内にあるものとします。

      "nextunique"

      found record を、records 内で 次の要件をすべて満たす最初のレコードとします。

      • key が定義されている場合:

      • position が定義されている場合:

        • レコードのキーが position より大きいものとします。

      • レコードのキーが range 内にあるものとします。

      "prev"

      found record を、records 内で 次の要件をすべて満たす最後のレコードとします。

      • key が定義されている場合:

      • primaryKey が定義されている場合:

        • レコードのキーが key と等しく、 レコードの値が primaryKey より小さいか等しい ものとします。

        • レコードのキーが key より小さいものとします。

      • position が定義され、source がオブジェクトストアである場合:

        • レコードのキーが position より小さいものとします。

      • position が定義され、source がインデックスである場合:

        • レコードのキーが position と等しく、 レコードの値が object store position より小さいものとします。

        • レコードのキーが position より小さいものとします。

      • レコードのキーが range 内にあるものとします。

      "prevunique"

      temp record を、 records 内で次の要件をすべて満たす最後のレコードとします。

      • key が定義されている場合:

      • position が定義されている場合:

        • レコードのキーが position より小さいものとします。

      • レコードのキーが range 内にあるものとします。

      temp record が定義されている場合、found record を、 records 内でキーが temp record のキーと等しい最初のレコードとします。

      注記: "prevunique" での反復は、 "nextunique" と同じレコードを逆順で訪れます。

    2. found record が定義されていない場合:

      1. cursor のキーを undefined に設定します。

      2. source がインデックスである場合、cursor の オブジェクトストア位置を undefined に設定します。

      3. cursor のキーのみフラグが false の場合、 cursor の 値を undefined に設定します。

      4. null を返します。

    3. position を found record のキーとします。

    4. source がインデックスである場合、object store position を found record の値とします。

    5. count を1減少させます。

  10. cursor の位置を position に設定します。

  11. source がインデックスである場合、cursor のオブジェクトストア 位置を object store position に設定します。

  12. cursor のキーを found record のキーに設定します。

  13. cursor のキーのみフラグが false の場合:

    1. serialized を、source がオブジェクト ストアの場合は found record の値とし、それ以外の場合は found record の参照 値とします。

    2. cursor の値を ! StructuredDeserialize(serialized, targetRealm) に設定します。

  14. cursor の値取得フラグを true に設定します。

  15. cursor を返します。

7. ECMAScript バインディング

この節では、この仕様で定義されるキー値が ECMAScript 値との間でどのように変換されるか、またキーパスを使用して ECMAScript 値からどのように抽出され、ECMAScript 値へどのように注入されるかを定義します。この節では ECMAScript 言語仕様の 型およびアルゴリズムを参照し、そのアルゴリズム規約の一部を使用します。 [ECMA-262] ここで詳述されていない変換は [WEBIDL] で定義されています。

7.1. 値からキーを抽出する

value、keyPath、および任意の multiEntry flag を用いてキーパスを使用して値からキーを抽出するには、 次の手順を実行します。これらの手順の結果はキー、 invalid、または failure であり、手順が例外をスローする場合もあります。

  1. r を、value と keyPath を用いて値に対してキーパスを評価する結果とします。 例外があれば再スローします。

  2. r が failure の場合、failure を返します。

  3. multiEntry flag が false の場合、key を r を用いて値をキーに変換する結果とし、それ以外の場合は r を用いて値を multiEntry キーに変換する 結果とします。例外があれば再スローします。

  4. key が "invalid value" または "invalid type" の場合、invalid を返します。

  5. key を返します。

value と keyPath を用いて値に対して キーパスを評価するには、次の手順を実行します。これらの手順の結果は ECMAScript 値または failure であり、手順が例外をスローする場合もあります。

  1. keyPath が文字列のリストである場合:

    1. result を、 式 [] によって作成されたかのような新しい Array オブジェクトとします。

    2. i を0とします。

    3. keyPath の各 item についてそれぞれ:

      1. key を、item と value を用いて再帰的に 値に対してキーパスを評価する結果とします。

      2. 表明: key は中途完了ではありません。

      3. key が failure の場合、アルゴリズム全体を中止して failure を返します。

      4. p を ! ToString(i) とします。

      5. status を CreateDataProperty(result, p, key) とします。

      6. 表明: status は true です。

      7. i を1増加させます。

    4. result を返します。

      注記: キーパスのシーケンスはネストできないため、 これは1階層だけ「再帰」します。

  2. keyPath が空文字列の場合、value を返し、 残りの手順をスキップします。

  3. identifiers を、 keyPath を U+002E FULL STOP 文字 (.) で厳密に分割する結果とします。

  4. identifiers の各 identifier についてそれぞれ、 以下の適切な手順へ進みます。

    Type(value) が String で、 identifier が "length" の場合

    value を、value 内の要素数と等しい Number とします。

    value が Array で、identifier が "length" の場合

    value を ! ToLength(! Get(value, "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 とします。

    それ以外の場合
    1. Type(value) が Object でない場合、failure を返します。

    2. hop を ! HasOwnProperty(value, identifier) とします。

    3. hop が false の場合、failure を返します。

    4. value を ! Get(value, identifier) とします。

    5. value が undefined の場合、failure を返します。

  5. 表明: value は中途完了ではありません。

  6. value を返します。

注記: 上記の手順で表明できるのは、このアルゴリズムが StructuredDeserialize の出力である値にのみ適用され、 「自身の」プロパティにのみアクセスするためです。

7.2. 値にキーを注入する

注記: この節で使用されるキーパスは 常に文字列であり、 シーケンスではありません。これは、キージェネレーターを持ち、かつ シーケンスであるキーパスも持つ オブジェクトストアを作成することはできないためです。

value と keyPath を用いてキーを値に注入できることを確認するには、次の手順を実行します。 これらの手順の結果は true または false です。

  1. identifiers を、keyPath を U+002E FULL STOP 文字 (.) で厳密に 分割する結果とします。

  2. 表明: identifiers は空ではありません。

  3. identifiers の最後の項目を削除します。

  4. identifiers の残りの各 identifier について、存在する場合それぞれ:

    1. value が Object または Array でない場合、false を返します。

    2. hop を ! HasOwnProperty(value, identifier) とします。

    3. hop が false の場合、true を返します。

    4. value を ! Get(value, identifier) とします。

  5. value が Object または Array の場合は true を返し、それ以外の場合は false を返します。

注記: 上記の手順で表明できるのは、このアルゴリズムが StructuredDeserialize の出力である値にのみ適用されるためです。

value、key、および keyPath を用いてキーパスを使用してキーを値に注入するには、次の手順を実行します。

  1. identifiers を、keyPath を U+002E FULL STOP 文字 (.) で厳密に 分割する結果とします。

  2. 表明: identifiers は空ではありません。

  3. last を identifiers の最後の項目とし、 リストから削除します。

  4. identifiers の残りの各 identifier についてそれぞれ:

    1. 表明: value は Object または Array です。

    2. hop を ! HasOwnProperty(value, identifier) とします。

    3. hop が false の場合:

      1. o を、 式 ({}) によって作成されたかのような新しい Object とします。

      2. status を CreateDataProperty(value, identifier, o) とします。

      3. 表明: status は true です。

    4. value を ! Get(value, identifier) とします。

  5. 表明: value は Object または Array です。

  6. keyValue を key を用いてキーを値に変換する結果とします。

  7. status を CreateDataProperty(value, last, keyValue) とします。

  8. 表明: status は true です。

注記: 上記の手順で表明できるのは、このアルゴリズムが StructuredDeserialize の出力である値にのみ適用され、 キーを値に注入できることを確認する手順が 実行済みであるためです。

7.3. キーを値に変換する

key を用いてキーを 値に変換するには、次の手順を実行します。 この手順は ECMAScript 値を返します。

  1. type を key の型とします。

  2. value を key の値とします。

  3. type に応じて:

    number

    value と等しい ECMAScript Number 値を返します。

    string

    value と等しい ECMAScript String 値を返します。

    date
    1. date を、単一の引数 value で ECMAScript Date コンストラクターを実行した結果とします。

    2. 表明: date は中途 完了ではありません。

    3. date を返します。

    binary
    1. len を value の長さとします。

    2. buffer を、len を指定して ECMAScript ArrayBuffer コンストラクターを実行した結果とします。

    3. 表明: buffer は中途 完了ではありません。

    4. buffer の [[ArrayBufferData]] 内部スロットのエントリを value のエントリに設定します。

    5. buffer を返します。

    array
    1. array を、引数なしで ECMAScript Array コンストラクターを実行した結果とします。

    2. 表明: array は中途 完了ではありません。

    3. len を value のサイズとします。

    4. index を0とします。

    5. index が len より小さい間:

      1. entry を、 value[index] を用いてキーを値に 変換する結果とします。

      2. status を CreateDataProperty(array, index, entry) とします。

      3. 表明: status は true です。

      4. index を1増加させます。

    6. array を返します。

7.4. 値をキーに変換する

ECMAScript 値 input と、任意の 集合 seen を用いて値を キーに変換するには、次の手順を実行します。 これらの手順の結果はキー、 "invalid value"、"invalid type" のいずれかであり、または 手順が例外をスローする場合があります。

  1. seen が指定されていない場合、seen を新しい空の集合とします。

  2. seen が input を含む場合、"invalid value" を返します。

  3. 以下の適切な手順へ進みます。

    Type(input) が Number の場合
    1. input が NaN の場合、"invalid value" を返します。

    2. それ以外の場合、キーを新しく作成して返します。その 型を number、値を input とします。

    input が Date ([[DateValue]] 内部スロットを持つ)の場合
    1. ms を input の [[DateValue]] 内部スロットの値とします。

    2. ms が NaN の場合、"invalid value" を返します。

    3. それ以外の場合、キーを新しく作成して返します。その型を date、値を ms とします。

    Type(input) が String の場合
    1. キーを新しく作成して返します。その 型を string、 値を input とします。

    input がバッファ ソース型の場合
    1. input が切り離されている場合、"invalid value" を返します。

    2. bytes を、 input のバッファソースが保持するバイトのコピーを取得する結果とします。

    3. キーを新しく作成して返します。その 型を binary、値を bytes とします。

    input がArray exotic object の場合
    1. len を ? ToLength( ? Get(input, "length")) とします。

    2. input を seen に追加します。

    3. keys を新しい空のリストとします。

    4. index を0とします。

    5. index が len より小さい間:

      1. hop を ? HasOwnProperty(input, index) とします。

      2. hop が false の場合、"invalid value" を返します。

      3. entry を ? Get(input, index) とします。

      4. key を、引数 entry および seen を用いて値を キーに変換する結果とします。

      5. ReturnIfAbrupt(key)。

      6. key が "invalid value" または "invalid type" の場合、 これらの手順を中止して "invalid value" を返します。

      7. key を keys に追加します。

      8. index を1増加させます。

    6. 配列キーを新しく作成して返し、その 値を keys とします。

    それ以外の場合

    "invalid type" を返します。

ECMAScript 値 input を用いて値を multiEntry キーに変換するには、次の手順を実行します。 これらの手順の結果はキー、 "invalid value"、"invalid type" のいずれかであり、または手順が例外をスローする場合があります。

  1. input がArray exotic object の場合:

    1. len を ? ToLength( ? Get(input, "length")) とします。

    2. seen を input のみを含む新しい集合とします。

    3. keys を新しい空のリストとします。

    4. index を0とします。

    5. index が len より小さい間:

      1. entry を Get(input, index) とします。

      2. entry が中途 完了でない場合:

        1. key を、 引数 entry および seen を用いて値を キーに変換する結果とします。

        2. key が "invalid value"、"invalid type"、または中途 完了ではなく、 かつ keys 内に key と等しい 項目がない場合、 key を keys に追加します。

      3. index を1増加させます。

    6. 配列 キーを新しく作成して返し、その値を keys に設定します。

  2. それ以外の場合、引数 input を用いて値をキーに変換する結果を返します。 例外があれば再スローします。

注記: これらの手順は値をキーに変換する手順と似ていますが、 最上位の値が Array である場合、 キーに変換できないメンバーは無視され、重複は削除されます。

たとえば、値 [10, 20, null, 30, 20] は、 サブキー 10、20、30 を持つ配列キーに変換されます。

8. プライバシーに関する 考慮事項

この節は非規範的です。

8.1. ユーザー追跡

サードパーティホスト(または複数のサイトに配布されるコンテンツを取得できる任意のオブジェクト)は、 クライアント側データベースに保存された一意な識別子を使用して、 複数のセッションにわたってユーザーを追跡し、 ユーザーの活動のプロファイルを構築できる可能性があります。 ユーザーの実際の識別情報を把握しているサイト (たとえば認証資格情報を要求する電子商取引サイト)と組み合わせると、 純粋に匿名で Web を利用する世界よりも高い精度で、 抑圧的な集団が個人を標的にできる可能性があります。

ユーザー追跡のリスクを軽減するために使用できる手法はいくつかあります。

サードパーティストレージをブロックする

ユーザーエージェントは、データベースオブジェクトへのアクセスを、 閲覧コンテキストの最上位文書のドメインをオリジンとするスクリプトに制限し、 たとえば別のドメインのページが iframe 内で実行されている場合に API へのアクセスを拒否してもよいです。

保存されたデータを期限切れにする

ユーザーエージェントは、一定期間後に保存されたデータを 自動的に削除してもよいです。

これにより、サイトがユーザーを追跡する能力を制限できます。 その場合、サイト自身でユーザーが認証されたとき (たとえば購入したりサービスへログインしたりした場合)にのみ、 複数のセッションにわたってユーザーを追跡できるためです。

ただし、これはユーザーのデータを危険にさらすことにもなります。

永続ストレージを Cookie と同様に扱う

ユーザーエージェントは、データベース機能を HTTP セッション Cookie と 強く関連付ける形でユーザーに提示するべきです。[COOKIES]

これにより、ユーザーがそのようなストレージに対して健全な 警戒心を持つよう促せる可能性があります。

サイトごとのデータベースアクセス許可リスト

ユーザーエージェントは、サイトがこの機能を使用できるようになる前に、 データベースへのアクセスをユーザーに許可させてもよいです。

サードパーティストレージの帰属

ユーザーエージェントは、データの保存を引き起こしたサードパーティのオリジンからのコンテンツを含んでいたサイトのオリジンを記録してもよいです。

その情報を使用して、現在永続ストレージに保存されているデータを 表示すれば、ユーザーは永続ストレージのどの部分を 削除するかについて、情報に基づいた判断を行えます。 ブロックリスト(「このデータを削除し、このドメインが今後二度と データを保存できないようにする」)と組み合わせることで、ユーザーは 永続ストレージの使用を信頼するサイトに制限できます。

共有ブロックリスト

ユーザーエージェントは、ユーザーが永続ストレージの ドメインブロックリストを共有できるようにしてもよいです。

これにより、コミュニティが協力して プライバシーを保護できます。

これらの提案は、この API を使った単純なユーザー追跡を防ぎますが、 完全に阻止するものではありません。単一のドメイン内では、 サイトはセッション中にユーザーを追跡し続けることができ、 その後、サイトが取得した識別情報 (名前、クレジットカード番号、住所)とともに、 その情報をすべてサードパーティへ渡すことができます。 サードパーティが複数のサイトと協力して そのような情報を取得すれば、依然としてプロファイルを 作成できます。

ただし、ユーザーエージェントからの協力がまったくなくても、 ある程度のユーザー追跡は可能です。たとえば URL 内の セッション識別子を使用する方法です。この手法はすでに無害な目的で 一般的に使用されていますが、ユーザー追跡に簡単に転用できます (過去に遡って行うことさえ可能です)。この情報はその後、訪問者の IP アドレスや その他のユーザー固有データ (たとえば user-agent ヘッダーや構成設定)を使用して別々のセッションを 一貫したユーザープロファイルに統合し、他のサイトと共有できます。

永続ストレージのユーザーインターフェイスで、この仕様で説明する 永続ストレージ機能内のデータと HTTP セッション Cookie 内のデータを 別々に表示すると、ユーザーは一方のデータだけを削除し、 他方を削除しない可能性が高くなります。これによりサイトは、2つの 機能を互いの冗長なバックアップとして使用し、 ユーザーがプライバシーを保護しようとする試みを無効化できます。

8.3. データの機密性

ユーザーエージェントは、永続的に保存されたデータを潜在的に 機密性の高いものとして扱うべきです。この仕組みには、電子メール、予定表の予定、 医療記録、その他の機密文書が保存される可能性があります。

このため、ユーザーエージェントはデータを削除するとき、 基盤ストレージからも速やかに削除されることを保証するべきです。

9. セキュリティに関する考慮事項

9.1. DNS スプーフィング攻撃

DNS スプーフィング攻撃の可能性があるため、特定のドメインに属すると 主張するホストが実際にそのドメインに属していることを保証することはできません。 これを軽減するため、ページは TLS を使用できます。TLS を使用するページは、 同じドメインに属することを示す証明書を持ち、TLS を使用するページだけが 自身のデータベースへアクセスできることを保証できます。

9.2. ディレクトリ間攻撃

1つのホスト名を共有する異なる作成者、たとえば geocities.com 上でコンテンツをホストするユーザーは、すべて1つのデータベース集合を共有します。

パス名によるアクセスを制限する機能はありません。そのため 共有ホスト上の作成者には、これらの機能を使用しないことが推奨されます。 他の作成者がデータを読み取り、 上書きすることは容易だからです。

注記: パス制限機能が提供された場合でも、通常の DOM スクリプティングセキュリティモデルでは、この保護を回避して 任意のパスからデータへアクセスすることは容易です。

9.3. 実装上のリスク

これらの永続ストレージ機能を実装する際の主な2つのリスクは、 悪意のあるサイトに他のドメインから情報を読み取らせることと、 悪意のあるサイトに、後で他のドメインから読み取られる情報を 書き込ませることです。

サードパーティサイトに、そのドメインから読み取られるべきでないデータを 読み取らせることは、情報漏えいを引き起こします。たとえば、 あるドメイン上のユーザーの買い物用ウィッシュリストが、別の ドメインによるターゲティング広告に使用されたり、 ワープロサイトに保存されたユーザーの作業中の機密文書を、 競合企業のサイトが調査したりする可能性があります。

サードパーティサイトに他のドメインの永続ストレージへデータを書き込ませると、 同様に危険な情報スプーフィングを引き起こす可能性があります。 たとえば、悪意のあるサイトがユーザーのウィッシュリストへレコードを追加したり、 悪意のあるサイトがユーザーのセッション識別子を既知の ID に設定し、 それを使って被害サイト上でのユーザーの行動を 追跡したりする可能性があります。

したがって、この仕様で説明されるストレージキーのパーティショニングモデルに 厳密に従うことは、ユーザーのセキュリティにとって重要です。

ホスト名またはデータベース名を使用してファイルシステムへの永続化用パスを 構築する場合、攻撃者が "../" のような相対パスを使って 他のストレージキーの 情報へアクセスすることを防ぐため、適切にエスケープしなければなりません。

9.4. 永続化のリスク

実際の実装では、データを不揮発性ストレージ媒体に永続化します。 データは保存時にシリアライズされ、取得時にデシリアライズされますが、 シリアライズ形式の詳細はユーザーエージェント固有です。 ユーザーエージェントは時間の経過とともにシリアライズ形式を変更する可能性があります。 たとえば、新しいデータ型を扱うため、または性能を向上させるために 形式が更新される可能性があります。この仕様の運用要件を満たすため、 実装は古いシリアライズ形式を何らかの方法で扱わなければなりません。 古いデータの不適切な処理はセキュリティ上の問題につながる可能性があります。 基本的なシリアライズ上の懸念に加えて、シリアライズされたデータには、 新しいバージョンのユーザーエージェントでは有効でない前提が エンコードされている可能性があります。

その実用的な例が RegExp 型です。 StructuredSerializeForStorage 操作は、 RegExp オブジェクトのシリアライズを許可します。一般的なユーザーエージェントは、 入力データの渡し方や結果の返し方に関する前提の下で、 正規表現をネイティブマシン命令へコンパイルします。 この内部状態がデータベースへ保存されるデータの一部として シリアライズされた場合、後で内部表現をデシリアライズするときに さまざまな問題が発生する可能性があります。たとえば、コードへデータを 渡す方法が変更されている可能性があります。コンパイラー出力の セキュリティバグがユーザーエージェントの更新で特定され修正されても、 シリアライズされた内部状態には残っている可能性があります。

ユーザーエージェントは古いデータを識別し、適切に処理しなければなりません。 1つの方法は、シリアライズ形式にバージョン識別子を含め、 古いデータが見つかった場合に、スクリプトから見える状態から 内部状態を再構築することです。

10. アクセシビリティに関する考慮事項

この節は非規範的です。

この仕様で説明する API のアクセシビリティに関する考慮事項は限定的です。

この API は構造化コンテンツの保存を許可します。テキストコンテンツは文字列として保存できます。 開発者が画像や音声などの代替非テキストコンテンツを Blob、 File、 または ImageData オブジェクトとして保存するためのサポートも API に存在します。API を使用して動的コンテンツアプリケーションを作成する開発者は、 さまざまな技術やニーズを持つユーザーがコンテンツへアクセスできるようにするべきです。

API 自体はそのための特定の仕組みを定義していませんが、構造化コンテンツの保存により、 開発者は国際化されたコンテンツも保存できます。異なるレコードやレコード内の構造を使用して、 言語ごとの代替コンテンツを保持できます。

API は、API と対話するためのユーザーインターフェイスをユーザーエージェントが生成することを定義も要求もしません。 ユーザーエージェントは、API をサポートするユーザーインターフェイス要素を任意に提供してもよいです。例として、 追加のストレージクォータが必要な場合のユーザーへのプロンプト、特定の Web サイトが使用しているストレージを確認する機能、 またはレコードの検査、変更、削除など API のストレージに特化したツールがあります。 そのようなユーザーインターフェイス要素は、アクセシビリティツールを考慮して設計しなければなりません。たとえば、 使用済みストレージクォータの割合をグラフィカルに提示するユーザーインターフェイスは、 スクリーンリーダーなどのツールにも同じデータを提供しなければなりません。

11. 改訂履歴

この節は非規範的です。

以下は、この仕様の前回の公開以降の変更を情報提供目的でまとめたものです。 完全な改訂履歴は こちらにあります。 初版の改訂履歴については、その文書の改訂 履歴を参照してください。 第2版の改訂履歴については、その文書の改訂履歴を参照してください。

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 に感謝します。 これらすべての方々のフィードバックと提案により、この 仕様は改善されました。

適合性

文書の 規約

適合性要件は、 記述的な表明と RFC 2119 の用語を組み合わせて表現されます。 この文書の規範的な部分における「しなければならない」、「してはならない」、「要求される」、「しなければならない」、「してはならない」、「するべきである」、「するべきではない」、「推奨される」、 「してもよい」、および「任意」 というキーワードは、 RFC 2119 に記載されているとおりに解釈されます。 ただし、可読性のため、 この仕様ではこれらの語はすべて大文字では表記されません。

明示的に非規範的と記されている節、例、および注記を除き、 この仕様のすべての文章は規範的です。[RFC2119]

この仕様の例は、「たとえば」という語で導入されるか、 規範的な文章から class="example" を使用して、 次のように区別されます。

これは情報提供的な例の一例です。

情報提供的な注記は「注記」という語で始まり、 規範的な文章から class="note" を使用して、 次のように区別されます。

注記、これは情報提供的な注記です。

適合する アルゴリズム

アルゴリズムの一部として命令形で記述された要件 (「先頭の空白文字をすべて取り除く」 または「false を返し、これらの手順を中止する」など)は、 アルゴリズムを導入する際に使用されたキーワード (「しなければならない」、「するべきである」、「してもよい」など) の意味で解釈されます。

アルゴリズムまたは特定の手順として表現された適合性要件は、 最終的な結果が同等である限り、 どのような方法で実装してもかまいません。 特に、この仕様で定義されるアルゴリズムは、 理解しやすいことを意図したものであり、 高性能であることを意図したものではありません。 実装者には最適化が推奨されます。

索引

この仕様で定義される 用語

参照によって定義される 用語

参考文献

規範的参考文献

[DOM]
Anne van Kesteren. DOM 標準. 現行標準. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript 言語仕様. URL: https://tc39.es/ecma262/multipage/
[FileAPI]
Marijn Kruisselbrink. File API. 2024年12月4日. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML 標準. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. 現行標準. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. 要件レベルを 示すために RFC で使用するキーワード. 1997年3月. 現行のベストプラクティス. URL: https://datatracker.ietf.org/doc/html/rfc2119
[STORAGE]
Anne van Kesteren. Storage 標準. 現行 標準. URL: https://storage.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. 現行 標準. URL: https://webidl.spec.whatwg.org/

参考情報

[Charmod-Norm]
Addison Phillips; et al. World Wide Web の文字モデル: 文字列照合. 2021年8月11日. NOTE. URL: https://www.w3.org/TR/charmod-norm/
[COOKIES]
A. Barth. HTTP 状態管理メカニズム. 2011年4月. 標準化提案. URL: https://httpwg.org/specs/rfc6265.html
[WEBSTORAGE]
Ian Hickson. Web Storage(第2版). 2021年1月28日. REC. URL: https://www.w3.org/TR/webstorage/

IDL 索引

[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"
};

[Exposed=(Window,Worker)]
interface IDBOpenDBRequest : IDBRequest {
  // Event handlers:
  attribute EventHandler onblocked;
  attribute EventHandler onupgradeneeded;
};

[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 oldVersion = 0;
  unsigned long long? newVersion = null;
};

partial interface mixin WindowOrWorkerGlobalScope {
  [SameObject] readonly attribute IDBFactory 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;
};

[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 mode = "readonly",
                                         optional IDBTransactionOptions options = {});
  undefined close();

  [NewObject] IDBObjectStore createObjectStore(
    DOMString name,
    optional IDBObjectStoreParameters options = {});
  undefined deleteObjectStore(DOMString name);

  // Event handlers:
  attribute EventHandler onabort;
  attribute EventHandler onclose;
  attribute EventHandler onerror;
  attribute EventHandler onversionchange;
};

enum IDBTransactionDurability { "default", "strict", "relaxed" };

dictionary IDBTransactionOptions {
  IDBTransactionDurability durability = "default";
};

dictionary IDBObjectStoreParameters {
  (DOMString or sequence<DOMString>)? keyPath = null;
  boolean autoIncrement = false;
};

[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 direction = "next");
  [NewObject] IDBRequest openKeyCursor(optional any query,
                                       optional IDBCursorDirection direction = "next");

  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 direction = "next";
};

[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 direction = "next");
  [NewObject] IDBRequest openKeyCursor(optional any query,
                                       optional IDBCursorDirection direction = "next");
};

[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);
};

[Exposed=(Window,Worker)]
interface IDBRecord {
  readonly attribute any key;
  readonly attribute any primaryKey;
  readonly attribute any value;
};

[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"
};

[Exposed=(Window,Worker)]
interface IDBCursorWithValue : IDBCursor {
  readonly attribute any value;
};

[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"
};

✔MDN

IDBCursor/advance

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/continue

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/continuePrimaryKey

In all current engines.

Firefox10+Safari10.1+Chrome58+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android51+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/delete

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/direction

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/key

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/primaryKey

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/request

In all current engines.

Firefox77+Safari15+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/source

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor/update

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursor

In all current engines.

Firefox16+Safari8+Chrome24+
Opera44+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile43+
✔MDN

IDBCursorWithValue/value

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBCursorWithValue

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBDatabase/close

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/close_event

In all current engines.

Firefox50+Safari10.1+Chrome30+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/close_event

In all current engines.

Firefox50+Safari10.1+Chrome30+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/createObjectStore

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/deleteObjectStore

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/name

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/objectStoreNames

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/transaction

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/version

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/versionchange_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase/versionchange_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBDatabase

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBFactory/cmp

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

IDBFactory/databases

FirefoxNoneSafari14+Chrome72+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBFactory/deleteDatabase

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBFactory/open

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBFactory

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBIndex/count

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/get

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/getAll

In all current engines.

Firefox44+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/getAllKeys

In all current engines.

Firefox44+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/getKey

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/keyPath

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/multiEntry

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/name

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/objectStore

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/openCursor

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/openKeyCursor

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex/unique

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBIndex

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBKeyRange/bound_static

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/includes

In all current engines.

Firefox47+Safari10.1+Chrome52+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/lower

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/lowerBound_static

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/lowerOpen

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/only_static

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/upper

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/upperBound_static

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange/upperOpen

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBKeyRange

In all current engines.

Firefox16+Safari8+Chrome24+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBObjectStore/add

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/autoIncrement

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)?IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/clear

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/count

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/createIndex

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/delete

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/deleteIndex

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/get

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/getAll

In all current engines.

Firefox44+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android48+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/getAllKeys

In all current engines.

Firefox44+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android48+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/getKey

In all current engines.

Firefox51+Safari10.1+Chrome48+
Opera45+Edge79+
Edge (Legacy)?IENone
Firefox for Android58+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile43+
✔MDN

IDBObjectStore/index

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/indexNames

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/keyPath

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/name

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/openCursor

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/openKeyCursor

In all current engines.

Firefox44+Safari10.1+Chrome23+
Opera?Edge79+
Edge (Legacy)?IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/put

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore/transaction

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBObjectStore

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBOpenDBRequest/blocked_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBOpenDBRequest/upgradeneeded_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBOpenDBRequest

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBRequest/error

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/error_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

IDBTransaction/error_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/readyState

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/result

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/source

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/success_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest/transaction

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBRequest

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android25+Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBTransaction/abort

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/abort_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/commit

In all current engines.

Firefox74+Safari15+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/complete_event

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/db

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

IDBTransaction/durability

FirefoxNoneSafari15+Chrome83+
Opera70+Edge83+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/error

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/mode

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/objectStore

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction/objectStoreNames

In all current engines.

Firefox10+Safari10.1+Chrome48+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBTransaction

In all current engines.

Firefox16+Safari8+Chrome24+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile14+
✔MDN

IDBVersionChangeEvent/IDBVersionChangeEvent

In all current engines.

Firefox25+Safari10+Chrome41+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBVersionChangeEvent/newVersion

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBVersionChangeEvent/oldVersion

In all current engines.

Firefox10+Safari8+Chrome23+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
✔MDN

IDBVersionChangeEvent

In all current engines.

Firefox16+Safari8+Chrome24+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView4.4+Samsung Internet?Opera Mobile?
✔MDN

indexedDB

In all current engines.

Firefox16+Safari8+Chrome24+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android22+iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?