- From: Dumitru Daniliuc <dumi@google.com>
- Date: Tue, 23 Feb 2010 16:23:14 -0800
- To: public-webapps <public-webapps@w3.org>
- Message-ID: <e753f47f1002231623k71af2c78nd0a48012f467affa@mail.gmail.com>
Hi, I know that not many people on this list care about the WebSQLDatabase spec anymore (especially when it comes to changing it), but Chromium extension developers do. So I was hoping somebody could explain the idea behind having openDatabase() take a creationCallback. As I understand it, the callback is supposed to be a place where the user initiates the DB (changes version, creates tables, etc.). However, if we follow the spec, then this callback becomes quite useless. *Example 1:* function creationCallback(db) { db.transaction(...); // change version, create tables, etc. } var db = openDatabase(..., creationCallback); db.transaction(tx1); db.transaction(tx2); According to the spec, if the database doesn't exist, we must queue a task to run creationCallback (4.1) and return from openDatabase(). Then we queue up tasks for the 2 transactions (4.3.2). So our queue ends up looking like this: 1. invoke creationCallback 2. invoke the transaction callback for tx1 3. invoke the transaction callback for tx2 Now we invoke creationCallback, and find a transaction there, so we queue up a task to invoke the transaction callback (4.3.2). Now our queue looks like this: 1. invoke transaction callback for tx1 2. invoke transaction callback for tx2 3. invoke transaction callback for the transaction defined inside creationCallback As you can see, if we follow the spec, we end up running the transaction(s) in creationCallback AFTER all other transactions in the code. So what's the point of having a creationCallback? *Example 2:* function creationCallback(db) { db.changeVersion(...); // change version to 1.0 } var db1 = openDatabase("db", "1.0", "", 1, creationCallback); var db2 = openDatabase("db", "1.0", "", 1); According to the spec, if "db" doesn't exist, then the first openDatabase() will set the version to "" (empty string) and queue up the creationCallback. Now before we have a chance to invoke the creationCallback, the second call to openDatabase() happens, and fails with a INVALID_STATE_ERR (as requested by the spec), because a database with that name exists, it's version is "", and we expect the version to be "1.0". So again, the creationCallback which was supposed to change the version comes in after the rest of the code has already failed. So it seems to me that if we follow the spec, then the creationCallback becomes nothing more than a flag that tells us whether or not the DB existed (and a pretty poor implementation of such a flag too, since it's set only after we're done executing the rest of the code). Is this really the intended purpose of this callback? If not, assuming the purpose of this callback was to initialize the database before running any transactions on it, I propose the following changes to the spec: 1. If the database doesn't exist and a creationCallback is specified, * invoke* the creation callback at the very end of openDatabase(). (This would take care of the problem described in example 1.) 2. If the database doesn't exist, always set its version to the given one. If a creation callback was specified, invoke it. If the creation callback fails or raises an exception, reset the database version to "". (This would take care of the problem in example 2. And in case creationCallback fails, we will reset the DB version to "" before any other transaction gets a chance to run.) Thanks, dumi
Received on Wednesday, 24 February 2010 00:23:44 UTC