We looked at the spec to see what it would take to be able to support
multi-column keys on primary keys & indexes and we found some inconsistencies
that need to be addressed. Below is our proposal/assumptions on how to
constrain the problem and what needs to be updated in the spec to support this:
. Cursors are automatically sorted in ascending order but they can be retrieved
in descending order depending on the value passed to the
IDBObjectStore.createIndex. In other words, all of the attributes that make up
the index or the primary key will share the same direction. The default
direction will match the single index case.
. KeyRanges will act on the first element of the compound key (i.e. the first
column).
. IDBObjectStore.get and IDBIndex.get will be able to take in an array value.
Each value in the array will be mapped against the compound key defined in the
IDBObjectStore and the record will be queried using all of the compound key
values specified in the array. If using an IDBKeyRange, the range will only be
able to act on the first element of the compound key. Because the current type
of the get method parameter is an any, this will automatically support both
single and array values. For example,
---When retrieving the record of a single key index they do this:
var request = index.get("Israel Hilerio");
request.onsuccess = function (evt) { var record = this.result; }
---When retrieving the record of a compound key index they will query like
this:
var request = index.get(["PM","IE"]);
request.onsuccess = function (evt) { var record = this.result; };
. IDBIndex.getKey will be able to take in an array value. Each value in the
array will be mapped against the compound key defined in the IDBObjectStore and
the record will be queried using all of the compound key values specified in
the array. The result will be an array of values that can be accessed using
the property order of the compound key. Because the current type of the get
method parameter is an any and the type of the IDBRequest.result is an any,
this will automatically support both single and array values. For example,
---When retrieving the primaryKey of a single key record they do this:
var request = index.getKey("Israel Hilerio");
request.onsuccess = function (evt) { var primaryKey = this.result; }
---When retrieving the primaryKey of a compound key record they will query like
this:
var request = index.getKey(["PM","IE"]);
request.onsuccess = function (evt) { var firstKey = this.result[0]; var
secondKey = this.result[1] };
---This will also support an indexed property that doesn't contain any arrays
but the primary key of the record is an array. Notice that passing a string
into getKey will return an array as the result.
var request = index.getKey("Israel Hilerio");
request.onsuccess = function (evt) { var firstKey = this.result[0]; var
secondKey = this.result[1] };
. IDBCursor.key and IDBCursor.primaryKey won't have to change signature since
they are already any attributes. The current definition should allow them to
return an array if the key or primaryKey is a compound key. For example,
---When retrieving the value of a single key they do this:
var myKey = cursor.key;
---When retrieving the value of a compound key they will do this:
var myFirstKey = cursor.key[0];
var mySecondKey = cursor.key[1];
. The autoInc property will only apply to the first element on the compound
key. This will be consistent with our proposed KeyRange suggestion.
. We should change the signature of IDBObjectStore.keyPath to be DOMStringList
instead of DOMString. This will make it more intuitive that it supports arrays.
Let me know what you think.
Israel