window.openDatabase on Android doesn't handle the version parameter very well.
------------------------------------------------------------------------------
Key: CB-482
URL: https://issues.apache.org/jira/browse/CB-482
Project: Apache Callback
Issue Type: Bug
Components: Android
Affects Versions: 1.4.0, 1.3.0, 1.2.0
Reporter: Wayne Fisher
Assignee: Joe Bowser
In the database code for Android, near the very bottom of the phonegap.js file,
we find the following code:
{code}
if (typeof window.openDatabase === "undefined") {
setupDroidDB();
} else {
window.openDatabase_orig = window.openDatabase;
window.openDatabase = function(name, version, desc, size){
// Some versions of Android will throw a SECURITY_ERR so we need
// to catch the exception and seutp our own DB handling.
var db = null;
try {
db = window.openDatabase_orig(name, version, desc, size);
}
catch (ex) {
db = null;
}
if (db == null) {
setupDroidDB();
return DroidDB_openDatabase(name, version, desc, size);
}
else {
return db;
}
};
}
{code}
The comment makes reference to a SECURITY_ERR exception that appears to occur
on some versions of Android. The following try/catch block will catch the
SECURITY_ERR exception and proceed to setup the DroidDB.
However, the try/catch block does not take into account that other exceptions
can occur. In particular, from w3.org the following specifies an exception that
should be raised if the specified version does not match the actual database
version:
{quote}
If the database version provided is not the empty string, and the database
already exists but has a different version, or no version, then the method must
raise an INVALID_STATE_ERR exception.
{quote}
It would appear to me that the above code should be modified to be more
selective about the handling of exceptions. If an INVALID_STATE_ERR exception
is raised, it should not setup the DroidDB but instead allow it to propagate to
the caller.
I came across this issue when attempting to update a database to a new version
due to a requirement for additional columns. My code attempted to open the new
database version and if it failed (due to exception) it would fallback and
attempt to open and upgrade the previous version. What happened was that it was
never able to find the previous version since the INVALID_STATE_ERR exception
was being thrown which was caught by the PhoneGap code which would then proceed
to setup the DroidDB. There was no way to get to the original database.
The above code appears the same in PhoneGap v1.2, 1.3, and 1.4. I didn't check
1.5. In 1.5 the code moved to be much earlier in the file and changed slightly
but is effectively the same:
{code}
// First patch WebSQL if necessary
if (typeof window.openDatabase == 'undefined') {
// Not defined, create an openDatabase function for all to use!
window.openDatabase = storage.openDatabase;
} else {
// Defined, but some Android devices will throw a SECURITY_ERR -
// so we wrap the whole thing in a try-catch and shim in our own
// if the device has Android bug 16175.
var originalOpenDatabase = window.openDatabase;
window.openDatabase = function(name, version, desc, size) {
var db = null;
try {
db = originalOpenDatabase(name, version, desc, size);
}
catch (ex) {
db = null;
}
if (db === null) {
return storage.openDatabase(name, version, desc, size);
}
else {
return db;
}
};
}
{code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira