[TIMOB-2147] Android: PRAGMA and non-SELECT statements return null from Ti.Database.DB.execute() instead of ResultSet
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Medium |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2011-04-17T01:58:14.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 1.5.0 |
Components | Android |
Labels | android, database, db, defect, patch, pragma, resultset, sqlite |
Reporter | Brion Vibber |
Assignee | Don Thorp |
Created | 2011-04-15T03:11:51.000+0000 |
Updated | 2011-04-17T01:58:14.000+0000 |
Description
I'm attempting to upgrade a database table from a prior revision of my app by checking if fields are present on a table. To do this, I'm using SQLite's PRAGMA statement:
PRAGMA table_info(account)
On iOS w/ current git-master code this works fine, as well as directly hitting databases with 'sqlite3'. However on Android, DB.execute() returns null instead of a ResultSet object, so I cannot access any of the returned data.
This appears to be because the Android TiDatabaseProxy.java assumes that only SELECT statements can ever return data:
if(sql.trim().toLowerCase().startsWith("select")) {
c = db.rawQuery(sql, newArgs);
if (c != null) {
rs = new TiResultSetProxy(getTiContext(), c);
if (rs.isValidRow()) {
rs.next(); // Position on first row if we have data.
}
} else {
rs = new TiResultSetProxy(getTiContext(), null); // because iPhone does it this way.
}
} else {
if (args != null) {
db.execSQL(sql, args);
} else {
db.execSQL(sql);
}
}
The iPhone implementation on the other hand doesn't make any such assumption, and ships every query through the same code paths. If the result info from the DB has no columns, then it returns null instead of a ResultSet.
Quick fix which seems to work for me so far, but I'm not 100% sure on it:
http://github.com/brion/titanium_mobile/commits/2147">http://github.com/brion/titanium_mobile/commits/2147
http://github.com/brion/titanium_mobile/commit/8d3251fca69e10df6a96a2a9ae513159494d17c3"> http://github.com/brion/titanium_mobile/commit/8d3251fca69e10df6a96...
I've encountered the same issue. I'm afraid I don't know how to try out your proposed fix, so I'll have to wait till it's released.
(from [17b01d60fe9c3c8a8b4055c376ba3625e8dc3d29]) [#2147 state:fixed-in-qa] test: drillbit/tests/tidb/tidb.js#test_database_lh_2147. This one took quite awhile because you can't just switch out execSql for rawSql. After suffering with it for a few hours I remember that raw doesn't do transactions, therefore if you made sure the database was deleted before starting, the database would get created, but the Test table would not. If you happened to have another database around with the same table you'd get a false positive because the drop table would fail too. So the compromise is detect select and pragma queries and use rawSql otherwise use exec. https://github.com/appcelerator/titanium_mobile/commit/17b01d60fe9c3c8a8b4055c376ba3625e8dc3d29"> https://github.com/appcelerator/titanium_mobile/commit/17b01d60fe9c...
Resolved Titanium SDK version: 1.5.0 (12/03/10 10:38 33c2058), Android 1.6/2.1 Emulators, Drillbit.