W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2012

[IndexedDB] Key generation details

From: Jonas Sicking <jonas@sicking.cc>
Date: Wed, 25 Jan 2012 12:24:37 -0800
Message-ID: <CA+c2ei_NpRTw_z7n4eo_Nyz=3QTtSaBnYFg03vUcgMV9UxwLog@mail.gmail.com>
To: Webapps WG <public-webapps@w3.org>
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 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:50 GMT