This specification provides a concrete API to perform advanced key-value data management that is at the heart of most sophisticated query processors. It does so by using transactional databases to store keys and their corresponding values (one or more per key), and providing a means of traversing keys in a deterministic order. This is often implemented through the use of persistent B-tree data structures that are considered efficient for insertion and deletion as well as in-order traversal of very large numbers of data records.

    In the following example, the API is used to access a “library” database that holds books stored by their “isbn” attribute. Additionally, an index is maintained on the “title” attribute of the objects stored in the object store. This index can be used to look up books by title, and enforces a uniqueness constraint. Another index is maintained on the “author” attribute of the objects, and can be used to look up books by author.

    A connection to the database is opened. If the “library” database did not already exist, it is created and an event handler creates the object store and indexes. Finally, the opened connection is saved for use in subsequent examples.

    The following example populates the database using a transaction.

    1. var tx = db.transaction("books", "readwrite");
    2. var store = tx.objectStore("books");
    3.  
    4. store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
    5. store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
    6. store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
    7.  
    8. tx.oncomplete = function() {
    9. // All requests have succeeded and the transaction has committed.
    10. };
    1. var tx = db.transaction("books", "readonly");
    2. var store = tx.objectStore("books");
    3. var index = store.index("by_title");
    4.  
    5. var request = index.get("Bedrock Nights");
    6. request.onsuccess = function() {
    7. var matching = request.result;
    8. if (matching !== undefined) {
    9. // A match was found.
    10. report(matching.isbn, matching.title, matching.author);
    11. } else {
    12. // No match was found.
    13. report(null);
    14. };

    The following example looks up all books in the database by author using an index and a cursor.

    The following example shows how errors could be handled when a request fails.

    1. var tx = db.transaction("books", "readwrite");
    2. var store = tx.objectStore("books");
    3. var request = store.put({title: "Water Buffaloes", author: "Slate", isbn: 987654});
    4. request.onerror = function(event) {
    5. // The uniqueness constraint of the "by_title" index failed.
    6. report(request.error);
    7. // Could call event.preventDefault() to prevent the transaction from aborting.
    8. };
    9. tx.onabort = function() {
    10. // Otherwise the transaction will automatically abort due the failed request.
    11. report(tx.error);
    12. };

    The database connection can be closed when it is no longer needed.

    1. db.close();

    In the future, the database might have grown to contain other object stores and indexes. The following example shows one way to handle migrating from an older version of the database.

    To avoid blocking a new client from upgrading, clients can listen for the version change event. This fires when another client is wanting to upgrade the database. To allow this to continue, react to the “versionchange“ event by doing something that ultimately closes this client’s to the database.

    One way of doing this is to reload the page:

    1. db.onversionchange = function() {
    2. // First, save any unsaved data:
    3. saveUnsavedData().then(function() {
    4. // If the document isn’t being actively used, it could be appropriate to reload
    5. // the page without the user’s interaction.
    6. if (!document.hasFocus()) {
    7. location.reload();
    8. // Reloading will close the database, and also reload with the new JavaScript
    9. // and database definitions.
    10. // If the document has focus, it can be too disruptive to reload the page.
    11. // Maybe ask the user to do it manually:
    12. displayMessage("Please reload this page for the latest version.");
    13. }
    14. });
    15. };
    16.  
    17. function saveUnsavedData() {
    18. // How you do this depends on your app.
    19. }
    20.  
    21. function displayMessage() {
    22. // Show a non-modal message to the user.
    23. }

    Another way is to call the connection‘s method. However, you need to make sure your app is aware of this, as subsequent attempts to access the database will fail.

    1. db.onversionchange = function() {
    2. saveUnsavedData().then(function() {
    3. db.close();
    4. stopUsingTheDatabase();
    5. });
    6. };
    7.  
    8. function stopUsingTheDatabase() {
    9. // Put the app into a state where it no longer uses the database.

    The new client (the one attempting the upgrade) can use the "blocked" event to detect if other clients are preventing the upgrade from happening. The event fires if other clients still hold a connection to the database after their "versionchange" events have fired.