[whatwg] SQL API complex for simple cases

Brady Eidson beidson at apple.com
Wed Oct 31 17:40:35 PDT 2007

>>> On Wed, 31 Oct 2007, Brady Eidson wrote:
>>>> My understanding with this design is that you would get this
>>>> SQLTransaction object back and it would just sit around, not doing
>>>> anything.  When you first call executeSql on it, you kick off the
>>>> transaction steps as they already exist.  Until you call
>>>> executeSql(), it's just a dummy object that doesn't interfere with
>>>> the database at all.
>>> What if there's a problem with opening the transaction itself? You
>>> don't want to run all the code for preparing the statement only to
>>> find you didn't have a chance for the statement to run in the first
>>> place.
>> While the spec *does* currently enforce preparing the statement at  
>> the
>> time of calling executeSql() just to mark the statement bogus,  
>> "marking
>> the statement bogus" is only a flag that takes effect later during  
>> the
>> transaction effects.
>> Therefore, why is it so necessary to prepare the statement before the
>> transaction is opened?  Why don't we parse and validate the  
>> statement in
>> the transaction steps themselves?
>> If we adopted both of these models (Tims idea and allowing the  
>> statement
>> to be parsed in the transaction steps) and there was a problem with
>> opening the transaction itself, you'd get the
>> SQLTransactionErrorCallback and the statement would never even be
>> touched at all.
> I'm talking about:
>   var transaction = db.transaction(errorCallback);
>   // the transaction has failed at this point
>   // but we have no way to stop the next few lines from running:
>   ...do lots of work to get the data to put into the transaction...
>   transaction.executeSql('...', [expensiveData], ...);
> vs:
>   db.transaction(function (transaction) {
>     // this never gets called, since the transaction failed
>     ...do lots of work to get the data to put into the transaction...
>     transaction.executeSql('...', [expensiveData], ...);
>   }, errorCallback);

Interesting.  I think you've swayed me with this argument.

I have an alternative to propose - how about reinstating  
Database.executeSql(), and do something like this.

db.executeSql("select * from table;", [], <SQLStatementCallback>,  
<SQLStatementErrorCallback>, <SQLTransactionErrorCallback>);

This would "fire and forget" a single, individual statement in its own  
transaction.  It would follow transaction steps exactly as they  
currently exist, except it would skip the SQLTransactionCallback  
because the first sql statement to execute is already queued.

This way you could do:

db.executeSql("SELECT * FROM Notes", [], function(tx, results) { //  
Start a new transaction with one sql statement on the queue
	tx.executeSql("INSERT INTO Notes...", [], ...);  // Add a new  
statement to this transaction
	db.executeSql("SOME OTHER SQL STATEMENT", ...); // Start a new  
transaction with its first sql statement queued up
	}, statementErrorCallback, txErrorCallback);

But could also do something as simple as:

db.executeSql("CREATE TABLE Notes (...)", [], NULL, NULL, NULL);

Someone I talked to about this in person was concerned about the  
naming collision of executeSql() - it might be confusing if JS  
developers start making custom classes and you start seeing  
this.executeSql() - is it a database or a sqltransaction?  Perhaps  
naming one of them something other than executeSql().

But I do think this is a reasonable way to A - make it easier to kick  
off an individual statement and B - allows the developer, in the best  
case scenario of no failures, kick off a sql statement that runs to  
completion with *no* callbacks.

I think both of these points are important.


More information about the whatwg mailing list