// This is what our database looks like:

  /* "kids" objectStore:

  [

    { name: "Anna", id: 14 },

    { name: "Betty", id: 26 },

    { name: "Christine", id: 13 },

    // ...

  ]

  */

  /* "candy" objectStore:

  [

    { name: "gum", id: 19 },

    // ...

  ]

  /*

  /* "candySales" objectStore:

  [

    { kidId: 92, candyId: 4, date: "2010-5-12" },

    { kidId: 92, candyId: 6, date: "2010-5-12" },

    { kidId: 92, candyId: 13, date: "2010-5-13" },

    { kidId: 67, candyId: 2, date: "2010-5-14"},

    // ...

  ]

  // has "kidId" index

  */

////////////////////////////////

// Initialize database

  var request = indexedDB.open("CandyDB", "My candy store database");

  request.onsuccess = function(event) {

    var db = event.result;

    if (db.version != "1") {

      // User's first visit, initialize database.

      var createdObjectStoreCount = 0;

      var objectStores = [

        { name: "kids", keyPath: "id", autoIncrement: true },

        { name: "candy", keyPath: "id", autoIncrement: true },

        { name: "candySales", keyPath: "", autoIncrement: true }

      ];

      function objectStoreCreated(event) {

        if (++createdObjectStoreCount == objectStores.length) {

          db.setVersion("1").onsuccess = function(event) {

            loadData(db);

          };

        }

      }

      for (var index = 0; index < objectStores.length; ++index) {

        var params = objectStores[index];

        request = db.createObjectStore(params.name, params.keyPath,

                                       params.autoIncrement);

        request.onsuccess = objectStoreCreated;

      }

    }

    else {

      // User has been here before, no initialization required.

      loadData(db);

    }

  };

  function loadData(db) {

    // Do stuff!

  }

////////////////////////////////

// List kids

  var request = indexedDB.open("CandyDB", "My candy store database");

  request.onsuccess = function(event) {

    // Enumerate the entire object store.

    request = event.result.objectStore("kids").openCursor();

    request.onsuccess = function(event) {

      var cursor = event.result;

      // If cursor is null then we've completed the enumeration.

      if (!cursor) {

        return;

      }

      var element = document.createElement("div");

      element.textContent = cursor.value.name;

      document.getElementById("kidList").appendChild(element);

      cursor.continue();

    };

  };

////////////////////////////////

// Store kids into database

  var kids = [

    { name: "Anna" },

    { name: "Betty" },

    { name: "Christine" },

    // ...

  ];

  var request = indexedDB.open("CandyDB", "My candy store database");

  request.onsuccess = function(event) {

    var objectStore = event.result.objectStore("kids");

    for (var index = 0; index < kids.length; ++index) {

      objectStore.addOrModify(kids[index]).onsuccess = function(event) {

        document.getElementById("display").textContent =

          "Saved record for " + kids[i].name + " with id " + event.result;

      };

    }

  };

////////////////////////////////

// List kids who bought candy, and the number of purchases they made

  candyEaters = [];

  function displayCandyEaters(event) {

    var display = document.getElementById("purchaseList");

    for (var i in candyEaters) {

      display.textContent += ", " + candyEaters[i].name + "bought " +

                             candyEaters[i].count + "pieces";

    }

  };

  indexedDB.open("MyDB", "My database").onsuccess = function(event) {

    var db = event.result;

    var transaction = db.transaction(["kids", "candySales"]);

    transaction.oncomplete = displayCandyEaters;

    var prevKidId = undefined;

    var prevKidRowCount = 0;

    transaction.objectStore("candySales").index("kidId").openObjectCursor()

               .onsuccess = function(event) {

      var cursor = event.result;

      if ((!cursor || prevKidId != cursor.value.kidId) && prevKidId != undefined) {

        var resultIndex = candyEaters.length;

        candyEaters[resultIndex] = { count: prevKidRowCount };

        transaction.objectStore("kids").get(prevKidId).onsuccess = function(event) {

          candyEaters[resultIndex].name = event.result.name;

        };

        prevKidRowCount = 0;

      }

      if (cursor) {

        prevKidId = cursor.value.kidId;

        prevKidRowCount++;

        cursor.continue();

      }

    }

  }

////////////////////////////////

// List all kids and the number of purchases they made (some may have bought 0)

  candyEaters = [];

  indexedDB.open("MyDB", "My database").onsuccess = function(event) {

    var db = event.result;

    var transaction = db.transaction(["kids", "candySales"]);

    transaction.oncomplete = displayCandyEaters;

    var kidCursor;

    var saleCursor;

    var salesLoaded = false;

    var count;

    transaction.objectStore("kids").openCursor().onsuccess = function(event) {

      kidCursor = event.result;

      count = 0;

      attemptWalk();

    }

    transaction.objectStore("candySales").index("kidId").openCursor().onsuccess =

      function(event) {

      saleCursor = event.result;

      salesLoaded = true;

      attemptWalk();

    }

    function attemptWalk() {

      if (!kidCursor || !salesLoaded)

        return;

      if (saleCursor && kidCursor.value.id == saleCursor.kidId) {

        count++;

        saleCursor.continue();

      }

      else {

        candyEaters.push({ name: kidCursor.value.name, count: count });

        kidCursor.continue();

      }

    }

  }