[IndexedDB] Key generation details

Hi All,

Joshua reminded me of another thing which is undefined in the
specification, which is key generation. Here's the details of how we
do it in Firefox:

The key generator for each objectStore starts at 1 and is increased by
1 every time a new key is generated.

Each objectStore has its own key generator. See comments for the
following code example:
store1 = db.createObjectStore("store1", { autoIncrement: true });
store1.put("a"); // Will get key 1
store2 = db.createObjectStore("store2", { autoIncrement: true });
store2.put("a"); // Will get key 1
store1.put("b"); // Will get key 2
store2.put("b"); // Will get key 2

If an insertion fails due to constraint violations or IO error, the
key generator is not updated.
trans.onerror = function(e) { e.preventDefault() };
store = db.createObjectStore("store1", { autoIncrement: true });
index = store.createIndex("index1", "ix", { unique: true });
store.put({ ix: "a"}); // Will get key 1
store.put({ ix: "a"}); // Will fail
store.put({ ix: "b"}); // Will get key 2

Removing items from an objectStore never affects the key generator.
Including when .clear() is called.
store = db.createObjectStore("store1", { autoIncrement: true });
store.put("a"); // Will get key 1
store.delete(1);
store.put("b"); // Will get key 2
store.clear();
store.put("c"); // Will get key 3
store.delete(IDBKeyRange.lowerBound(0));
store.put("d"); // Will get key 4

Inserting an item with an explicit key affects the key generator if,
and only if, the key is numeric and higher than the last generated
key.
store = db.createObjectStore("store1", { autoIncrement: true });
store.put("a"); // Will get key 1
store.put("b", 3); // Will use key 3
store.put("c"); // Will get key 4
store.put("d", -10); // Will use key -10
store.put("e"); // Will get key 5
store.put("f", 6.00001); // Will use key 6.0001
store.put("g"); // Will get key 7
store.put("f", 8.9999); // Will use key 8.9999
store.put("g"); // Will get key 9
store.put("h", "foo"); // Will use key "foo"
store.put("i"); // Will get key 10
store.put("j", [1000]); // Will use key [1000]
store.put("k"); // Will get key 11
// All of these would behave the same if the objectStore used a
keyPath and the explicit key was passed inline in the object

Aborting a transaction rolls back any increases to the key generator
which happened during the transaction. This is to make all rollbacks
consistent since rollbacks that happen due to crash never has a chance
to commit the increased key generator value.
db.createObjectStore("store", { autoIncrement: true });
...
trans1 = db.transaction(["store"]);
store_t1 = trans1.objectStore("store");
store_t1.put("a"); // Will get key 1
store_t1.put("b"); // Will get key 2
trans1.abort();
trans2 = db.transaction(["store"]);
store_t2 = trans2.objectStore("store");
store_t2.put("c"); // Will get key 1
store_t2.put("d"); // Will get key 2

/ Jonas

Received on Wednesday, 25 January 2012 20:25:37 UTC