- From: Brady Eidson <beidson@apple.com>
- Date: Wed, 31 Oct 2007 17:40:35 -0700
>>> 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. Thanks, ~Brady
Received on Wednesday, 31 October 2007 17:40:35 UTC