Re: Detailed review of 4.12. Client-side database storage

Hello Ian!

Le Thu, 18 Oct 2007 04:10:34 +0300, Ian Hickson <ian@hixie.ch> a écrit:

> You also asked some questions about the globalStorage stuff and about
> file upload APIs. I'll answer those later when I address those areas.

No problem. I know I went off-topic, but I allowed myself to do that,  
because ideas are most important.

Thanks for the reply.

> On Fri, 12 Oct 2007, Mihai Sucan wrote:
>>
>> I'd recommend to add some examples for executeSql().
>
> Yeah, I'll add examples eventually. A whole introduction section, too. I
> just don't want to do it before we have a more stable body, otherwise  
> I'll
> be doing it over and over and errors will creep in.

Good. Looking forward to that.

>> 1. Why complicate things with database versions? Any use cases?
>
> It's for when you update your application and need to transition to a new
> database schema.

Can't this be done with a completely new database name?


>> As I see, one can have database versions completely different,
>> independent, of each other. Actually, database versions are not really
>> "versions". They *can* be used as versions, but they can also be used as
>> ... something completely different.
>
> No, each database is only one database with a version, you can't have
> multiple versions of the same database at the same time. What in the spec
> suggested this? I should change it.

The spec definition of what a database 'version' is, is not very clear.  
Let me see if I correctly understand now:

openDatabase('robodesign', 'v1')

... this creates the database 'robodesign' with version 'v1'.

... we can executeSql() as much as we want

openDatabase('robodesign', 'v2')

... this fails (INVALID_STATE_ERR), because the database doesn't have  
version 'v2'

openDatabase('robodesign', '')

... this works - no expected version.

... but still, we cannot executeSql() because the algorithm tells that the  
expected version must be te same as the current version.

db.changeVersion('v1', 'v2', callBack)

... allows the author to implement the transition from older versions to  
newer versions of the same database.

Now, the question is: how are authors supposed to make the transition  
between versions?

a) within the callback of changeVersion()?

The author is not supposed to start running any commands which transition  
the database to the newer version. Everything is supposed to be done  
within the callback.

b) outside the callback of changeVersion()? Before the author invokes the  
method.

The author is supposed to run all the commands which transition the  
database to the newer version. At the end, the author must change the  
version.


Personally, I believe the answer is point a) - everything must be done  
within the callback. I would suggest making this clear in the spec.


If my understanding of what the database version is correct, here's my try  
at a simpler "overview" definition:

"Any database can have only one version at a time - versions are not  
concurrent. The database version only serves the purpose of easier  
identification of the version for Web authors. They can write scripts  
which automatically upgrade the database of the client to a newer version.  
Without any version identifier, the authors would not be able to trivially  
check which database schema is provided by the client."


>> 2. Why openDatabase() instead of executeSql('SELECT databaseName') ?
>
> Because you're not executing SQL, you're selecting the database. I don't
> really see why you'd use executeSql for this.

Erm, that's a mistake. I wanted executeSql('USE database_name'). However,  
given the special purpose of openDatabase() ... the USE command cannot be  
used.


Further comments on the section:

1. The changeVersion() definition does not tell what happens if the author  
invokes the method with the first two arguments being the same. It also  
does not tell what happens when the newVersion is the same as the current  
version.


2. The changeVersion() method should also provide the Database object to  
the callback function, as the first argument. The second argument should  
be the boolean value determined by the algorithm defined for the  
changeVersion() method.


3. In step 5 of the executeSql() algorithm it is said:

"The user agent must then add the specified SQL statement to transaction,  
and must execute it as soon as all the statements that were added to that  
transaction before it have themselves successfully executed. [SQL]

If the Database object has an expected version that is neither the empty  
string nor the actual version of the database, the statement must fail."

The UA must execute the SQL statement. However, if the expected version is  
not the same as the current version, *then* the statement must fail. How  
does this work? Shouldn't the UA skip the execution of the SQL statement  
if the two versions don't match, and simply fail?


4. Based on the definition of the openDatabase() method I understand that  
the expected version can *only* be the empty string *or* the actual value  
of the *current* version of the database. Is that correct? If yes (or not)  
this should also be made more clear.

The expected version cannot be any other values than the two  
aforementioned ones, because if the author tries to open the database with  
a different value, then open fails (INVALID_STATE_ERR).


5. In the list of error codes, maybe an error code should be defined for  
one of the most common errors: duplicate ID. The error is triggered when  
the author tries to execute an SQL statement which inserts a new row with  
an existing ID - duplicate ID.


That's about all, for now.



-- 
Mihai Sucan
http://www.robodesign.ro

Received on Thursday, 18 October 2007 13:03:06 UTC