From 673a8871dfc6f9f7f1d986b158111fdf3053e243 Mon Sep 17 00:00:00 2001 From: Bryce Curtis Date: Tue, 19 Apr 2011 16:54:16 -0500 Subject: [PATCH] Ticket 136: window.openDatabase() in Android 3.0 throws SECURITY_ERR (most code written by Simon MacDonald - I just tested and checked in) When you call window.openDatabase() on an Android 3.0 device you get and error something like this: E/Web Console( 1791): SECURITY_ERR: DOM Exception 18: An attempt was made to break through the security policy of the user agent. Simon worked with Pat for a bit and they think this is a WebKit or Android/WebKit interaction bug. In the meantime this fix determines if you are on Android 3.0 and uses Droid_DB if so. --- framework/assets/js/storage.js | 2 +- framework/src/com/phonegap/Storage.java | 45 +++++++++++++++++++------ 2 files changed, 36 insertions(+), 11 deletions(-) mode change 100644 => 100755 framework/src/com/phonegap/Storage.java diff --git a/framework/assets/js/storage.js b/framework/assets/js/storage.js index 5540a357..56d5e743 100755 --- a/framework/assets/js/storage.js +++ b/framework/assets/js/storage.js @@ -389,7 +389,7 @@ PhoneGap.addConstructor(function() { navigator.openDatabase = window.openDatabase = DroidDB_openDatabase; window.droiddb = new DroidDB(); } - if (typeof window.openDatabase === "undefined") { + if ((typeof window.openDatabase === "undefined") || (navigator.userAgent.indexOf("Android 3.0") != -1)) { setupDroidDB(); } else { window.openDatabase_orig = window.openDatabase; diff --git a/framework/src/com/phonegap/Storage.java b/framework/src/com/phonegap/Storage.java old mode 100644 new mode 100755 index 67fc6f3e..56bf7893 --- a/framework/src/com/phonegap/Storage.java +++ b/framework/src/com/phonegap/Storage.java @@ -21,6 +21,12 @@ import android.database.sqlite.*; */ public class Storage extends Plugin { + // Data Definition Language + private static final String ALTER = "alter"; + private static final String CREATE = "create"; + private static final String DROP = "drop"; + private static final String TRUNCATE = "truncate"; + SQLiteDatabase myDb = null; // Database object String path = null; // Database path String dbName = null; // Database name @@ -83,7 +89,7 @@ public class Storage extends Plugin { * @return T=returns value */ public boolean isSynch(String action) { - return false; + return true; } /** @@ -159,20 +165,39 @@ public class Storage extends Plugin { */ public void executeSql(String query, String[] params, String tx_id) { try { - Cursor myCursor = this.myDb.rawQuery(query, params); - this.processResults(myCursor, tx_id); - myCursor.close(); - } catch (SQLiteException ex) { + if (isDDL(query)) { + this.myDb.execSQL(query); + this.sendJavascript("droiddb.completeQuery('" + tx_id + "', '');"); + } + else { + Cursor myCursor = this.myDb.rawQuery(query, params); + this.processResults(myCursor, tx_id); + myCursor.close(); + } + } + catch (SQLiteException ex) { ex.printStackTrace(); - System.out - .println("Storage.executeSql(): Error=" + ex.getMessage()); - + System.out.println("Storage.executeSql(): Error=" + ex.getMessage()); + // Send error message back to JavaScript - this.sendJavascript("droiddb.fail('" + ex.getMessage() + "','" - + tx_id + "');"); + this.sendJavascript("droiddb.fail('" + ex.getMessage() + "','" + tx_id + "');"); } } + /** + * Checks to see the the query is a Data Definintion command + * + * @param query to be executed + * @return true if it is a DDL command, false otherwise + */ + private boolean isDDL(String query) { + String cmd = query.toLowerCase(); + if (cmd.startsWith(DROP) || cmd.startsWith(CREATE) || cmd.startsWith(ALTER) || cmd.startsWith(TRUNCATE)) { + return true; + } + return false; + } + /** * Process query results. *