On 5/18/2010 7:20 AM, Jeremy Orlow wrote:
1. Once a database has been opened (a database connection has been
established) read access to meta-data, such as objectStore and index
names, is synchronous. Changes to such meta data, such as creating
objectStores and indexes, is still asynchronous.
I believe this is already how it's specced.  The IDBDatabase interface
already gives you synchronous access to all of this.
Mostly that is the same, with the exception of getting an object store or index which is now synchronous.

9. IDBKeyRanges are created using functions on IndexedDatabaseRequest.
We couldn't figure out how the old API allowed you to create a range
object without first having a range object.
In the spec, I see the following in examples:
var range = new IDBKeyRange.bound(2, 4);
and
var range = IDBKeyRange.leftBound(key);

I'm not particularly happy with hanging functions off of
IndexedDatabaseRequest for this.  Can it work something like what I listed
above?  If not, maybe we can find a better place to put them?  Or just
create multiple openCursor functions for each case?
I think one concern with the above syntax is that it's adding another object to the global scope. I recall Ben Turner and I discussing the possibility of hanging it off of indexedDB, so:
var range = new indexedDB.KeyRange.bound(2, 4);

My concern with making multiple openCursor functions is that there is more API complexity there. With that said, I don't have any strong opinions here either way.

10. You are allowed to have multiple transactions per database
connection. However if they use overlapping tables, only the first one
will receive events until it is finished (with the usual exceptions of
allowing multiple readers of the same table).
Can you please clarify what you mean here?  This seems like simply an
implementation detail to me, so maybe I'm missing something?
What this is trying to say is that you can have an object store being used in more than one transaction, but they cannot access it at the same time. However, I think it's best for Jonas to chime in here because this doesn't quite seem right to me like it did yesterday.

5)  You have two IDBTransactionRequest.onaborts.  I think one is supposed to
be an ontimeout.
Whoops, I thought we fixed that before he sent this out :)

6)  What is the default limit for the getAll functions?  Should we make it 0
(and define any<=0 amount to mean infinity)?
I believe we intended the default to be infinity (as in, if you don't specify, you get it all).

7)  I expect "add or modify" to be more used than the add or the modify
methods.  As such, I wonder if it makes sense to optimize the naming for
that.  For example, addOrModify=>set, add=>add/insert,
modify=>modify/update/replace maybe?
We had a lot of internal debate over this very thing. The problem we kept running into was that set could easily be read as doing just updating so it wouldn't be clear that you can also insert a new record there (without reading the spec or some tutorial). The benefit with addOrModify is that it is very explicit in what it does. We don't like how long it is, but we couldn't come up with a shorter name that doesn't have a fair amount of ambiguity.

8)   We can't leave deciding whether a cursor is pre-loaded up to UAs
since people will code for their favorite UA and then access
IDBCursorPreloadedRequest.count when some other UA does it as a
non-preloaded request.  Even in the same UA this will cause problems when
users have different datasets than developers are testing with.
I think that you might have been confused by our wording there. Sorry about that! IDBCursorPreloadedRequest is what you get if you pass sync=true into openCursor or openObjectCursor. Basically, sync cursors will give you a count, whereas async ones will not.

interface IBDCursorRequest : IDBCursor {
   readonly attribute any key;

   readonly attribute any value;

   *readonly attribute unsigned long long estimatedCount;*

  * // Returns null if the cursor was updated synchronously.  Otherwise*
*  // will return an IDBRequest object whose result will be set to this*
*  // cursor on success.  Until onsuccess is called, any access of key*
*  // or value will raise an exception.  The first request MUST cause*
*  // an asynchronous request but the behavior of subsequent calls is*
*  // up to the UA.*
*  IDBRequest continue(in optional any key /* null */);*

   // Success fires IDBTransactionEvent, result == key
   IDBRequest update(in any value);

   // Success fires IDBTransactionEvent, result == null
   IDBRequest remove();
};

I'm not super happy with this interface, but I think it's a lot better for a
few reasons:
1) It's not all or nothing.  Even if a result can't be 100% loaded into
memory, it doesn't mean that we'll have to deal with the overhead of every
fetch causing an asynchronous firing of an event.

2) There's an estimated count even if it's not pre-loaded (which has been
requested in other threads).
Were there use cases in those other threads? We couldn't come up with a case that would have been useful.

3) Because the first continue call will always be asynchronous, people using
this interface cannot get away with assuming results are always returned
synchronously, so the problems I mentioned in (8) are pretty much gone.
Not sure this matters (see my clarification).

Cheers,

Shawn

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to