| /* |
| * |
| * 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 |
| }; |