Updated Branches: refs/heads/plugins 0e1772a85 -> a1cbf99ac
Rename android-storage as android-legacy-websql Project: http://git-wip-us.apache.org/repos/asf/cordova-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-labs/commit/a1cbf99a Tree: http://git-wip-us.apache.org/repos/asf/cordova-labs/tree/a1cbf99a Diff: http://git-wip-us.apache.org/repos/asf/cordova-labs/diff/a1cbf99a Branch: refs/heads/plugins Commit: a1cbf99ac209b12f1068508c450f877f5994167a Parents: 0e1772a Author: Andrew Grieve <[email protected]> Authored: Tue Oct 22 22:08:17 2013 -0400 Committer: Andrew Grieve <[email protected]> Committed: Tue Oct 22 22:08:17 2013 -0400 ---------------------------------------------------------------------- android-legacy-websql/LegacyWebSql.java | 233 ++++++++++++++++++++ android-legacy-websql/README.md | 11 + android-legacy-websql/legacywebsql.js | 311 +++++++++++++++++++++++++++ android-legacy-websql/openDatabase.js | 47 ++++ android-legacy-websql/plugin.xml | 25 +++ android-storage/README.md | 3 - android-storage/Storage.java | 244 --------------------- android-storage/openDatabase.js | 47 ---- android-storage/plugin.xml | 25 --- android-storage/storage.js | 311 --------------------------- 10 files changed, 627 insertions(+), 630 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-legacy-websql/LegacyWebSql.java ---------------------------------------------------------------------- diff --git a/android-legacy-websql/LegacyWebSql.java b/android-legacy-websql/LegacyWebSql.java new file mode 100644 index 0000000..25cfad1 --- /dev/null +++ b/android-legacy-websql/LegacyWebSql.java @@ -0,0 +1,233 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ +package org.apache.cordova.legacywebsql; + +import java.io.File; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.*; + +public class LegacyWebSql extends CordovaPlugin { + + // 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 + + /** + * Executes the request and returns PluginResult. + * + * @param action + * The action to execute. + * @param args + * JSONArry of arguments for the plugin. + * @param callbackContext + * The callback context used when calling back into JavaScript. + * @return True if the action was valid, false otherwise. + */ + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + if (action.equals("openDatabase")) { + this.openDatabase(args.getString(0), args.getString(1), + args.getString(2), args.getLong(3)); + } else if (action.equals("executeSql")) { + String[] s = null; + if (args.isNull(1)) { + s = new String[0]; + } else { + JSONArray a = args.getJSONArray(1); + int len = a.length(); + s = new String[len]; + for (int i = 0; i < len; i++) { + s[i] = a.getString(i); + } + } + this.executeSql(args.getString(0), s, args.getString(2)); + } + else { + return false; + } + callbackContext.success(); + return true; + } + + /** + * Clean up and close database. + */ + @Override + public void onDestroy() { + if (this.myDb != null) { + this.myDb.close(); + this.myDb = null; + } + } + + /** + * Clean up on navigation/refresh. + */ + public void onReset() { + this.onDestroy(); + } + + // -------------------------------------------------------------------------- + // LOCAL METHODS + // -------------------------------------------------------------------------- + + /** + * Open database. + * + * @param db + * The name of the database + * @param version + * The version + * @param display_name + * The display name + * @param size + * The size in bytes + */ + public void openDatabase(String db, String version, String display_name, + long size) { + + // If database is open, then close it + if (this.myDb != null) { + this.myDb.close(); + } + + // If no database path, generate from application package + if (this.path == null) { + this.path = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); + } + + this.dbName = this.path + File.separator + db + ".db"; + + /* + * What is all this nonsense? Well the separator was incorrect so the db was showing up in the wrong + * directory. This bit of code fixes that issue and moves the db to the correct directory. + */ + File oldDbFile = new File(this.path + File.pathSeparator + db + ".db"); + if (oldDbFile.exists()) { + File dbPath = new File(this.path); + File dbFile = new File(dbName); + dbPath.mkdirs(); + oldDbFile.renameTo(dbFile); + } + + this.myDb = SQLiteDatabase.openOrCreateDatabase(this.dbName, null); + } + + /** + * Execute SQL statement. + * + * @param query + * The SQL query + * @param params + * Parameters for the query + * @param tx_id + * Transaction id + */ + public void executeSql(String query, String[] params, String tx_id) { + try { + if (isDDL(query)) { + this.myDb.execSQL(query); + this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').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()); + + // Send error message back to JavaScript + this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').failQuery('" + ex.getMessage() + "','" + tx_id + "');"); + } + } + + /** + * Checks to see the the query is a Data Definition 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. + * + * @param cur + * Cursor into query results + * @param tx_id + * Transaction id + */ + public void processResults(Cursor cur, String tx_id) { + + String result = "[]"; + // If query result has rows + + if (cur.moveToFirst()) { + JSONArray fullresult = new JSONArray(); + String key = ""; + String value = ""; + int colCount = cur.getColumnCount(); + + // Build up JSON result object for each row + do { + JSONObject row = new JSONObject(); + try { + for (int i = 0; i < colCount; ++i) { + key = cur.getColumnName(i); + value = cur.getString(i); + row.put(key, value); + } + fullresult.put(row); + + } catch (JSONException e) { + e.printStackTrace(); + } + + } while (cur.moveToNext()); + + result = fullresult.toString(); + } + + // Let JavaScript know that there are no more rows + this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').completeQuery('" + tx_id + "', " + result + ");"); + } + +} http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-legacy-websql/README.md ---------------------------------------------------------------------- diff --git a/android-legacy-websql/README.md b/android-legacy-websql/README.md new file mode 100644 index 0000000..515d95a --- /dev/null +++ b/android-legacy-websql/README.md @@ -0,0 +1,11 @@ +Legacy WebSQL Plugin for Android +--------------------------------- +This plugin provided WebSQL support on Android prior to version 3.0 and is obsoleted by [org.apache.cordova.websql](http://plugins.cordova.io/#/org.apache.cordova.websql). + +To transfer data from from the old database to the new one, you need to: +1. Install both plugins +2. Open your old database via `cordova.plugins.legacySQL.openDatabase()` +3. Open your new database via `window.openDatabase()` +4. Copy data from one to the other by going through JS. + +Since this is pretty annoying code to write, you might not want to use the new websql plugin for existing apps. Instead, continue to use the old one. http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-legacy-websql/legacywebsql.js ---------------------------------------------------------------------- diff --git a/android-legacy-websql/legacywebsql.js b/android-legacy-websql/legacywebsql.js new file mode 100644 index 0000000..72742c1 --- /dev/null +++ b/android-legacy-websql/legacywebsql.js @@ -0,0 +1,311 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +var utils = require('cordova/utils'), + exec = require('cordova/exec'), + channel = require('cordova/channel'); + +var queryQueue = {}; + +/** + * SQL result set object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Rows = function() { + this.resultSet = []; // results array + this.length = 0; // number of rows +}; + +/** + * Get item from SQL result set + * + * @param row The row number to return + * @return The row object + */ +DroidDB_Rows.prototype.item = function(row) { + return this.resultSet[row]; +}; + +/** + * SQL result set that is returned to user. + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Result = function() { + this.rows = new DroidDB_Rows(); +}; + +/** + * Callback from native code when query is complete. + * PRIVATE METHOD + * + * @param id Query id + */ +function completeQuery(id, data) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + + // Save query results + var r = new DroidDB_Result(); + r.rows.resultSet = data; + r.rows.length = data.length; + try { + if (typeof query.successCallback === 'function') { + query.successCallback(query.tx, r); + } + } catch (ex) { + console.log("executeSql error calling user success callback: "+ex); + } + + tx.queryComplete(id); + } + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * Callback from native code when query fails + * PRIVATE METHOD + * + * @param reason Error message + * @param id Query id + */ +function failQuery(reason, id) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + tx.queryList = {}; + + try { + if (typeof query.errorCallback === 'function') { + query.errorCallback(query.tx, reason); + } + } catch (ex) { + console.log("executeSql error calling user error callback: "+ex); + } + + tx.queryFailed(id, reason); + } + + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * SQL query object + * PRIVATE METHOD + * + * @constructor + * @param tx The transaction object that this query belongs to + */ +var DroidDB_Query = function(tx) { + + // Set the id of the query + this.id = utils.createUUID(); + + // Add this query to the queue + queryQueue[this.id] = this; + + // Init result + this.resultSet = []; + + // Set transaction that this query belongs to + this.tx = tx; + + // Add this query to transaction list + this.tx.queryList[this.id] = this; + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + +}; + +/** + * Transaction object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Tx = function() { + + // Set the id of the transaction + this.id = utils.createUUID(); + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + + // Query list + this.queryList = {}; +}; + +/** + * Mark query in transaction as complete. + * If all queries are complete, call the user's transaction success callback. + * + * @param id Query id + */ +DroidDB_Tx.prototype.queryComplete = function(id) { + delete this.queryList[id]; + + // If no more outstanding queries, then fire transaction success + if (this.successCallback) { + var count = 0; + var i; + for (i in this.queryList) { + if (this.queryList.hasOwnProperty(i)) { + count++; + } + } + if (count === 0) { + try { + this.successCallback(); + } catch(e) { + console.log("Transaction error calling user success callback: " + e); + } + } + } +}; + +/** + * Mark query in transaction as failed. + * + * @param id Query id + * @param reason Error message + */ +DroidDB_Tx.prototype.queryFailed = function(id, reason) { + + // The sql queries in this transaction have already been run, since + // we really don't have a real transaction implemented in native code. + // However, the user callbacks for the remaining sql queries in transaction + // will not be called. + this.queryList = {}; + + if (this.errorCallback) { + try { + this.errorCallback(reason); + } catch(e) { + console.log("Transaction error calling user error callback: " + e); + } + } +}; + +/** + * Execute SQL statement + * + * @param sql SQL statement to execute + * @param params Statement parameters + * @param successCallback Success callback + * @param errorCallback Error callback + */ +DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { + + // Init params array + if (typeof params === 'undefined') { + params = []; + } + + // Create query and add to queue + var query = new DroidDB_Query(this); + queryQueue[query.id] = query; + + // Save callbacks + query.successCallback = successCallback; + query.errorCallback = errorCallback; + + // Call native code + exec(null, null, "LegacyWebSql", "executeSql", [sql, params, query.id]); +}; + +var DatabaseShell = function() { +}; + +/** + * Start a transaction. + * Does not support rollback in event of failure. + * + * @param process {Function} The transaction function + * @param successCallback {Function} + * @param errorCallback {Function} + */ +DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) { + var tx = new DroidDB_Tx(); + tx.successCallback = successCallback; + tx.errorCallback = errorCallback; + try { + process(tx); + } catch (e) { + console.log("Transaction error: "+e); + if (tx.errorCallback) { + try { + tx.errorCallback(e); + } catch (ex) { + console.log("Transaction error calling user error callback: "+e); + } + } + } +}; + +/** + * Open database + * + * @param name Database name + * @param version Database version + * @param display_name Database display name + * @param size Database size in bytes + * @return Database object + */ +var DroidDB_openDatabase = function(name, version, display_name, size) { + exec(null, null, "LegacyWebSql", "openDatabase", [name, version, display_name, size]); + var db = new DatabaseShell(); + return db; +}; + + +module.exports = { + openDatabase:DroidDB_openDatabase, + failQuery:failQuery, + completeQuery:completeQuery +}; http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-legacy-websql/openDatabase.js ---------------------------------------------------------------------- diff --git a/android-legacy-websql/openDatabase.js b/android-legacy-websql/openDatabase.js new file mode 100644 index 0000000..1eb16ae --- /dev/null +++ b/android-legacy-websql/openDatabase.js @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + + +var modulemapper = require('cordova/modulemapper'), + legacywebsql = require('./legacywebsql'); + +var originalOpenDatabase = modulemapper.getOriginalSymbol(window, 'openDatabase'); + +module.exports = function(name, version, desc, size) { + // First patch WebSQL if necessary + if (!originalOpenDatabase) { + // Not defined, create an openDatabase function for all to use! + return legacywebsql.openDatabase.apply(this, arguments); + } + + // 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. + try { + return originalOpenDatabase(name, version, desc, size); + } catch (ex) { + if (ex.code !== 18) { + throw ex; + } + } + return legacywebsql.openDatabase(name, version, desc, size); +}; + + http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-legacy-websql/plugin.xml ---------------------------------------------------------------------- diff --git a/android-legacy-websql/plugin.xml b/android-legacy-websql/plugin.xml new file mode 100644 index 0000000..b6af32e --- /dev/null +++ b/android-legacy-websql/plugin.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" + id="org.apache.cordova.legacyandroidwebsql" + version="0.1.0"> + + <name>Legacy Android WebSQL</name> + + <platform name="android"> + <js-module src="legacywebsql.js" name="legacywebsql" /> + + <js-module src="openDatabase.js" name="openDatabase"> + <clobbers target="openDatabase" /> + <clobbers target="cordova.plugins.legacySQL.openDatabase" /> + </js-module> + + <config-file target="res/xml/config.xml" parent="/*"> + <feature name="LegacyWebSql"> + <param name="android-package" value="org.apache.cordova.legacywebsql.LegacyWebSql"/> + </feature> + </config-file> + + <source-file src="LegacyWebSql.java" target-dir="src/org/apache/cordova/legacywebsql" /> + </platform> +</plugin> http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-storage/README.md ---------------------------------------------------------------------- diff --git a/android-storage/README.md b/android-storage/README.md deleted file mode 100644 index 4851e98..0000000 --- a/android-storage/README.md +++ /dev/null @@ -1,3 +0,0 @@ -cordova-plugin-android-storage -------------------------------- -This plugin enables WebSQL support on Android. http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-storage/Storage.java ---------------------------------------------------------------------- diff --git a/android-storage/Storage.java b/android-storage/Storage.java deleted file mode 100644 index 193febc..0000000 --- a/android-storage/Storage.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. -*/ -package org.apache.cordova.labs.storage; - -import java.io.File; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.*; - -/** - * This class implements the HTML5 database support to work around a bug for - * Android 3.0 devices. It is not used for other versions of Android, since - * HTML5 database is built in to the browser. - */ -public class Storage extends CordovaPlugin { - - // 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 - - /** - * Constructor. - */ - public Storage() { - } - - /** - * Executes the request and returns PluginResult. - * - * @param action - * The action to execute. - * @param args - * JSONArry of arguments for the plugin. - * @param callbackContext - * The callback context used when calling back into JavaScript. - * @return True if the action was valid, false otherwise. - */ - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - if (action.equals("openDatabase")) { - this.openDatabase(args.getString(0), args.getString(1), - args.getString(2), args.getLong(3)); - } else if (action.equals("executeSql")) { - String[] s = null; - if (args.isNull(1)) { - s = new String[0]; - } else { - JSONArray a = args.getJSONArray(1); - int len = a.length(); - s = new String[len]; - for (int i = 0; i < len; i++) { - s[i] = a.getString(i); - } - } - this.executeSql(args.getString(0), s, args.getString(2)); - } - else { - return false; - } - callbackContext.success(); - return true; - } - - /** - * Clean up and close database. - */ - @Override - public void onDestroy() { - if (this.myDb != null) { - this.myDb.close(); - this.myDb = null; - } - } - - /** - * Clean up on navigation/refresh. - */ - public void onReset() { - this.onDestroy(); - } - - // -------------------------------------------------------------------------- - // LOCAL METHODS - // -------------------------------------------------------------------------- - - /** - * Open database. - * - * @param db - * The name of the database - * @param version - * The version - * @param display_name - * The display name - * @param size - * The size in bytes - */ - public void openDatabase(String db, String version, String display_name, - long size) { - - // If database is open, then close it - if (this.myDb != null) { - this.myDb.close(); - } - - // If no database path, generate from application package - if (this.path == null) { - this.path = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); - } - - this.dbName = this.path + File.separator + db + ".db"; - - /* - * What is all this nonsense? Well the separator was incorrect so the db was showing up in the wrong - * directory. This bit of code fixes that issue and moves the db to the correct directory. - */ - File oldDbFile = new File(this.path + File.pathSeparator + db + ".db"); - if (oldDbFile.exists()) { - File dbPath = new File(this.path); - File dbFile = new File(dbName); - dbPath.mkdirs(); - oldDbFile.renameTo(dbFile); - } - - this.myDb = SQLiteDatabase.openOrCreateDatabase(this.dbName, null); - } - - /** - * Execute SQL statement. - * - * @param query - * The SQL query - * @param params - * Parameters for the query - * @param tx_id - * Transaction id - */ - public void executeSql(String query, String[] params, String tx_id) { - try { - if (isDDL(query)) { - this.myDb.execSQL(query); - this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').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()); - - // Send error message back to JavaScript - this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').failQuery('" + ex.getMessage() + "','" + tx_id + "');"); - } - } - - /** - * Checks to see the the query is a Data Definition 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. - * - * @param cur - * Cursor into query results - * @param tx_id - * Transaction id - */ - public void processResults(Cursor cur, String tx_id) { - - String result = "[]"; - // If query result has rows - - if (cur.moveToFirst()) { - JSONArray fullresult = new JSONArray(); - String key = ""; - String value = ""; - int colCount = cur.getColumnCount(); - - // Build up JSON result object for each row - do { - JSONObject row = new JSONObject(); - try { - for (int i = 0; i < colCount; ++i) { - key = cur.getColumnName(i); - value = cur.getString(i); - row.put(key, value); - } - fullresult.put(row); - - } catch (JSONException e) { - e.printStackTrace(); - } - - } while (cur.moveToNext()); - - result = fullresult.toString(); - } - - // Let JavaScript know that there are no more rows - this.webView.sendJavascript("cordova.require('cordova/plugin/android/storage').completeQuery('" + tx_id + "', " + result + ");"); - } - -} http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-storage/openDatabase.js ---------------------------------------------------------------------- diff --git a/android-storage/openDatabase.js b/android-storage/openDatabase.js deleted file mode 100644 index a67aea6..0000000 --- a/android-storage/openDatabase.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - - -var modulemapper = require('cordova/modulemapper'), - storage = require('./storage'); - -var originalOpenDatabase = modulemapper.getOriginalSymbol(window, 'openDatabase'); - -module.exports = function(name, version, desc, size) { - // First patch WebSQL if necessary - if (!originalOpenDatabase) { - // Not defined, create an openDatabase function for all to use! - return storage.openDatabase.apply(this, arguments); - } - - // 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. - try { - return originalOpenDatabase(name, version, desc, size); - } catch (ex) { - if (ex.code !== 18) { - throw ex; - } - } - return storage.openDatabase(name, version, desc, size); -}; - - http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-storage/plugin.xml ---------------------------------------------------------------------- diff --git a/android-storage/plugin.xml b/android-storage/plugin.xml deleted file mode 100644 index 00fed84..0000000 --- a/android-storage/plugin.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" - id="org.apache.cordova.labs.androidstorage" - version="0.1.0"> - - <name>Android Storage</name> - - <!-- android --> - <platform name="android"> - <js-module src="storage.js" name="storage" /> - - <js-module src="openDatabase.js" name="openDatabase"> - <clobbers target="openDatabase" /> - </js-module> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Storage"> - <param name="android-package" value="org.apache.cordova.labs.storage.Storage"/> - </feature> - </config-file> - - <source-file src="Storage.java" target-dir="src/org/apache/cordova/labs/storage" /> - </platform> -</plugin> http://git-wip-us.apache.org/repos/asf/cordova-labs/blob/a1cbf99a/android-storage/storage.js ---------------------------------------------------------------------- diff --git a/android-storage/storage.js b/android-storage/storage.js deleted file mode 100644 index e615ebc..0000000 --- a/android-storage/storage.js +++ /dev/null @@ -1,311 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -var utils = require('cordova/utils'), - exec = require('cordova/exec'), - channel = require('cordova/channel'); - -var queryQueue = {}; - -/** - * SQL result set object - * PRIVATE METHOD - * @constructor - */ -var DroidDB_Rows = function() { - this.resultSet = []; // results array - this.length = 0; // number of rows -}; - -/** - * Get item from SQL result set - * - * @param row The row number to return - * @return The row object - */ -DroidDB_Rows.prototype.item = function(row) { - return this.resultSet[row]; -}; - -/** - * SQL result set that is returned to user. - * PRIVATE METHOD - * @constructor - */ -var DroidDB_Result = function() { - this.rows = new DroidDB_Rows(); -}; - -/** - * Callback from native code when query is complete. - * PRIVATE METHOD - * - * @param id Query id - */ -function completeQuery(id, data) { - var query = queryQueue[id]; - if (query) { - try { - delete queryQueue[id]; - - // Get transaction - var tx = query.tx; - - // If transaction hasn't failed - // Note: We ignore all query results if previous query - // in the same transaction failed. - if (tx && tx.queryList[id]) { - - // Save query results - var r = new DroidDB_Result(); - r.rows.resultSet = data; - r.rows.length = data.length; - try { - if (typeof query.successCallback === 'function') { - query.successCallback(query.tx, r); - } - } catch (ex) { - console.log("executeSql error calling user success callback: "+ex); - } - - tx.queryComplete(id); - } - } catch (e) { - console.log("executeSql error: "+e); - } - } -} - -/** - * Callback from native code when query fails - * PRIVATE METHOD - * - * @param reason Error message - * @param id Query id - */ -function failQuery(reason, id) { - var query = queryQueue[id]; - if (query) { - try { - delete queryQueue[id]; - - // Get transaction - var tx = query.tx; - - // If transaction hasn't failed - // Note: We ignore all query results if previous query - // in the same transaction failed. - if (tx && tx.queryList[id]) { - tx.queryList = {}; - - try { - if (typeof query.errorCallback === 'function') { - query.errorCallback(query.tx, reason); - } - } catch (ex) { - console.log("executeSql error calling user error callback: "+ex); - } - - tx.queryFailed(id, reason); - } - - } catch (e) { - console.log("executeSql error: "+e); - } - } -} - -/** - * SQL query object - * PRIVATE METHOD - * - * @constructor - * @param tx The transaction object that this query belongs to - */ -var DroidDB_Query = function(tx) { - - // Set the id of the query - this.id = utils.createUUID(); - - // Add this query to the queue - queryQueue[this.id] = this; - - // Init result - this.resultSet = []; - - // Set transaction that this query belongs to - this.tx = tx; - - // Add this query to transaction list - this.tx.queryList[this.id] = this; - - // Callbacks - this.successCallback = null; - this.errorCallback = null; - -}; - -/** - * Transaction object - * PRIVATE METHOD - * @constructor - */ -var DroidDB_Tx = function() { - - // Set the id of the transaction - this.id = utils.createUUID(); - - // Callbacks - this.successCallback = null; - this.errorCallback = null; - - // Query list - this.queryList = {}; -}; - -/** - * Mark query in transaction as complete. - * If all queries are complete, call the user's transaction success callback. - * - * @param id Query id - */ -DroidDB_Tx.prototype.queryComplete = function(id) { - delete this.queryList[id]; - - // If no more outstanding queries, then fire transaction success - if (this.successCallback) { - var count = 0; - var i; - for (i in this.queryList) { - if (this.queryList.hasOwnProperty(i)) { - count++; - } - } - if (count === 0) { - try { - this.successCallback(); - } catch(e) { - console.log("Transaction error calling user success callback: " + e); - } - } - } -}; - -/** - * Mark query in transaction as failed. - * - * @param id Query id - * @param reason Error message - */ -DroidDB_Tx.prototype.queryFailed = function(id, reason) { - - // The sql queries in this transaction have already been run, since - // we really don't have a real transaction implemented in native code. - // However, the user callbacks for the remaining sql queries in transaction - // will not be called. - this.queryList = {}; - - if (this.errorCallback) { - try { - this.errorCallback(reason); - } catch(e) { - console.log("Transaction error calling user error callback: " + e); - } - } -}; - -/** - * Execute SQL statement - * - * @param sql SQL statement to execute - * @param params Statement parameters - * @param successCallback Success callback - * @param errorCallback Error callback - */ -DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { - - // Init params array - if (typeof params === 'undefined') { - params = []; - } - - // Create query and add to queue - var query = new DroidDB_Query(this); - queryQueue[query.id] = query; - - // Save callbacks - query.successCallback = successCallback; - query.errorCallback = errorCallback; - - // Call native code - exec(null, null, "Storage", "executeSql", [sql, params, query.id]); -}; - -var DatabaseShell = function() { -}; - -/** - * Start a transaction. - * Does not support rollback in event of failure. - * - * @param process {Function} The transaction function - * @param successCallback {Function} - * @param errorCallback {Function} - */ -DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) { - var tx = new DroidDB_Tx(); - tx.successCallback = successCallback; - tx.errorCallback = errorCallback; - try { - process(tx); - } catch (e) { - console.log("Transaction error: "+e); - if (tx.errorCallback) { - try { - tx.errorCallback(e); - } catch (ex) { - console.log("Transaction error calling user error callback: "+e); - } - } - } -}; - -/** - * Open database - * - * @param name Database name - * @param version Database version - * @param display_name Database display name - * @param size Database size in bytes - * @return Database object - */ -var DroidDB_openDatabase = function(name, version, display_name, size) { - exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]); - var db = new DatabaseShell(); - return db; -}; - - -module.exports = { - openDatabase:DroidDB_openDatabase, - failQuery:failQuery, - completeQuery:completeQuery -};
