initial checkin, kind of works but not ready yet

This commit is contained in:
Mike 2012-04-07 23:08:44 -04:00
parent 0a5dd20c3e
commit 22c392ff02
3 changed files with 566 additions and 0 deletions

4
Android/SQLitePlugin/README.md Executable file
View File

@ -0,0 +1,4 @@
Phonegap SQLitePlugin
=====================
Do not use yet, this is not ready!!

View File

@ -0,0 +1,245 @@
(function() {
var callbacks, cbref, counter, getOptions, root;
root = this;
callbacks = {};
counter = 0;
cbref = function(hash) {
var f;
f = "cb" + (counter += 1);
callbacks[f] = hash;
return f;
};
getOptions = function(opts, success, error) {
var cb, has_cbs;
cb = {};
has_cbs = false;
if (typeof success === "function") {
has_cbs = true;
cb.success = success;
}
if (typeof error === "function") {
has_cbs = true;
cb.error = error;
}
if (has_cbs) opts.callback = cbref(cb);
return opts;
};
root.SQLitePlugin = (function() {
console.log("root.SQLitePlugin");
SQLitePlugin.prototype.openDBs = {};
function SQLitePlugin(dbPath, openSuccess, openError) {
console.log("SQLitePlugin");
this.dbPath = dbPath;
this.openSuccess = openSuccess;
this.openError = openError;
if (!dbPath) {
throw new Error("Cannot create a SQLitePlugin instance without a dbPath");
}
this.openSuccess || (this.openSuccess = function() {
console.log("DB opened: " + dbPath);
});
this.openError || (this.openError = function(e) {
console.log(e.message);
});
this.open(this.openSuccess, this.openError);
}
SQLitePlugin.handleCallback = function(ref, type, obj) {
console.log("SQLitePlugin.prototype.handleCallback");
var _ref;
if ((_ref = callbacks[ref]) != null) {
if (typeof _ref[type] === "function") _ref[type](obj);
}
callbacks[ref] = null;
delete callbacks[ref];
};
SQLitePlugin.prototype.executeSql = function(sql, values, success, error) {
console.log("SQLitePlugin.prototype.executeSql");
var opts;
if (!sql) throw new Error("Cannot executeSql without a query");
opts = getOptions({
query: [sql].concat(values || []),
path: this.dbPath
}, success, error);
// PhoneGap.exec("SQLitePlugin.backgroundExecuteSql", opts);
PhoneGap.exec(null, null, "SQLitePlugin", "backgroundExecuteSql", opts);
};
SQLitePlugin.prototype.transaction = function(fn, error, success) {
console.log("SQLitePlugin.prototype.transaction");
var t;
t = new root.SQLitePluginTransaction(this.dbPath);
fn(t);
return t.complete(success, error);
};
SQLitePlugin.prototype.open = function(success, error) {
console.log("SQLitePlugin.prototype.open");
var opts;
if (!(this.dbPath in this.openDBs)) {
this.openDBs[this.dbPath] = true;
opts = getOptions({
path: this.dbPath
}, success, error);
//PhoneGap.exec("SQLitePlugin.open", opts);
/*
* db The name of the database
version The version
display_name The display name
size The size in bytes
*
*/
PhoneGap.exec(success, error, "SQLitePlugin", "open", [this.dbPath]);
}
};
SQLitePlugin.prototype.close = function(success, error) {
console.log("SQLitePlugin.prototype.close");
var opts;
if (this.dbPath in this.openDBs) {
delete this.openDBs[this.dbPath];
opts = getOptions({
path: this.dbPath
}, success, error);
//PhoneGap.exec("SQLitePlugin.close", opts);
PhoneGap.exec(null, null, "SQLitePlugin", "close", opts);
}
};
return SQLitePlugin;
})();
get_unique_id = function()
{
var id = new Date().getTime();
var id2 = new Date().getTime();
while(id === id2)
{
id2 = new Date().getTime();
}
return id2+'000';
}
transaction_queue = [];
transaction_callback_queue = new Object();
root.SQLitePluginTransaction = (function() {
console.log("root.SQLitePluginTransaction");
function SQLitePluginTransaction(dbPath) {
console.log("root.SQLitePluginTransaction.SQLitePluginTransaction");
this.dbPath = dbPath;
this.executes = [];
this.trans_id = get_unique_id();
console.log("root.SQLitePluginTransaction - this.trans_id:"+this.trans_id);
transaction_queue[this.trans_id] = [];
}
SQLitePluginTransaction.queryCompleteCallback = function(transId, queryId, result)
{
var query = null;
for (var x in transaction_queue[transId])
{
if(transaction_queue[transId][x]['query_id'] == queryId)
{
query = transaction_queue[transId][x];
break;
}
}
if(query)
console.log("SQLitePluginTransaction.completeCallback---query:"+query['query']);
else
console.log("SQLitePluginTransaction.completeCallback---JSON.stringify(transaction_queue):"+JSON.stringify(transaction_queue[transId]));
if(query['callback'])
query['callback'](result)
}
SQLitePluginTransaction.txCompleteCallback = function(transId)
{
if(typeof transId != 'undefined')
{
console.log("SQLitePluginTransaction.txCompleteCallback---transId:"+transId);
if(transId && transaction_callback_queue[transId])
transaction_callback_queue[transId]();
}
else
console.log("SQLitePluginTransaction.txCompleteCallback---transId = NULL");
}
SQLitePluginTransaction.prototype.add_to_transaction = function(trans_id, query, params, callback, err_callback)
{
var new_query = new Object();;
new_query['trans_id'] = trans_id;
new_query['query_id'] = get_unique_id();
new_query['query'] = query;
new_query['params'] = params;
new_query['callback'] = callback;
new_query['err_callback'] = err_callback;
if(!transaction_queue[trans_id])
transaction_queue[trans_id] = [];
transaction_queue[trans_id].push(new_query);
}
SQLitePluginTransaction.prototype.executeSql = function(sql, values, success, error) {
console.log("SQLitePluginTransaction.prototype.executeSql");
var errorcb, successcb, txself;
txself = this;
successcb = null;
if (success) {
successcb = function(execres) {
console.log("executeSql callback:"+JSON.stringify(execres));
var res, saveres;
saveres = execres;
res = {
rows: {
item: function(i) {
return saveres[i];
},
length: saveres.length
},
rowsAffected: saveres.rowsAffected,
insertId: saveres.insertId || null
};
return success(txself, res);
};
}
errorcb = null;
if (error) {
errorcb = function(res) {
return error(txself, res);
};
}
this.add_to_transaction(this.trans_id, sql, values, successcb, errorcb);
console.log("executeSql - add_to_transaction"+sql);
};
SQLitePluginTransaction.prototype.complete = function(success, error) {
console.log("SQLitePluginTransaction.prototype.complete");
var begin_opts, commit_opts, errorcb, executes, opts, successcb, txself;
if (this.__completed) throw new Error("Transaction already run");
this.__completed = true;
txself = this;
successcb = function() {};
if (success) {
successcb = function() {
return success(txself);
};
}
errorcb = function(res) {
};
if (error) {
errorcb = function(res) {
return error(txself, res);
};
}
console.log("complete - this.transaction_queue"+JSON.stringify(transaction_queue[this.trans_id]));
transaction_callback_queue[this.trans_id] = successcb;
PhoneGap.exec(null, null, "SQLitePlugin", "executeSqlBatch", transaction_queue[this.trans_id]);
};
return SQLitePluginTransaction;
})();
}).call(this);

View File

@ -0,0 +1,317 @@
/*
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
*
* Copyright (c) 2005-2010, Nitobi Software Inc.
* Copyright (c) 2010, IBM Corporation
*/
package com.phonegap.plugins.sqlitePlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import android.database.Cursor;
import android.database.sqlite.*;
import android.util.Log;
/**
* This class implements the HTML5 database support for Android 1.X devices. It
* is not used for Android 2.X, since HTML5 database is built in to the browser.
*/
public class SQLitePlugin 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
/**
* Constructor.
*/
public SQLitePlugin() {
}
/**
* Executes the request and returns PluginResult.
*
* @param action
* The action to execute.
* @param args
* JSONArry of arguments for the plugin.
* @param callbackId
* The callback id used when calling back into JavaScript.
* @return A PluginResult object with a status and message.
*/
public PluginResult execute(String action, JSONArray args, String callbackId) {
PluginResult.Status status = PluginResult.Status.OK;
String result = "";
try {
// TODO: Do we want to allow a user to do this, since they could get
// to other app databases?
if (action.equals("setStorage")) {
this.setStorage(args.getString(0));
} else if (action.equals("open")) {
this.openDatabase(args.getString(0), "1",
"database", 5000000);
//this.openDatabase(args.getString(0), args.getString(1),
// args.getString(2), args.getLong(3));
}
else if (action.equals("executeSqlBatch"))
{
String[] queries = null;
String[] queryIDs = null;
String[][] params = null;
String trans_id = null;
JSONObject a = null;
JSONArray jsonArr = null;
int paramLen = 0;
if (args.isNull(0)) {
queries = new String[0];
} else {
int len = args.length();
queries = new String[len];
queryIDs = new String[len];
params = new String[len][1];
for (int i = 0; i < len; i++)
{
a = args.getJSONObject(i);
queries[i] = a.getString("query");
queryIDs[i] = a.getString("query_id");
trans_id = a.getString("trans_id");
jsonArr = a.getJSONArray("params");
paramLen = jsonArr.length();
params[i] = new String[paramLen];
for (int j = 0; j < paramLen; j++) {
params[i][j] = jsonArr.getString(j);
}
}
}
if(trans_id != null)
this.executeSqlBatch(queries, params, queryIDs, trans_id);
else
Log.v("error", "null trans_id");
}
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));
}
return new PluginResult(status, result);
} catch (JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
/**
* Identifies if action to be executed returns a value and should be run
* synchronously.
*
* @param action
* The action to execute
* @return T=returns value
*/
public boolean isSynch(String action) {
return true;
}
/**
* Clean up and close database.
*/
@Override
public void onDestroy() {
if (this.myDb != null) {
this.myDb.close();
this.myDb = null;
}
}
// --------------------------------------------------------------------------
// LOCAL METHODS
// --------------------------------------------------------------------------
/**
* Set the application package for the database. Each application saves its
* database files in a directory with the application package as part of the
* file name.
*
* For example, application "com.phonegap.demo.Demo" would save its database
* files in "/data/data/com.phonegap.demo/databases/" directory.
*
* @param appPackage
* The application package.
*/
public void setStorage(String appPackage) {
this.path = "/data/data/" + appPackage + "/databases/";
}
/**
* 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) {
Package pack = this.ctx.getClass().getPackage();
String appPackage = pack.getName();
this.setStorage(appPackage);
}
this.dbName = this.path + db + ".db";
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.sendJavascript("dddb.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("SQLitePlugin.executeSql(): Error=" + ex.getMessage());
// Send error message back to JavaScript
this.sendJavascript("dddb.fail('" + ex.getMessage() + "','" + tx_id + "');");
}
}
public void executeSqlBatch(String[] queryarr, String[][] paramsarr, String[] queryIDs, String tx_id) {
try {
this.myDb.beginTransaction();
String query = "";
String query_id = "";
String[] params;
int len = queryarr.length;
for (int i = 0; i < len; i++) {
query = queryarr[i];
params = paramsarr[i];
query_id = queryIDs[i];
Cursor myCursor = this.myDb.rawQuery(query, params);
this.processResults(myCursor, query_id, tx_id);
myCursor.close();
}
this.myDb.setTransactionSuccessful();
}
catch (SQLiteException ex) {
ex.printStackTrace();
System.out.println("SQLitePlugin.executeSql(): Error=" + ex.getMessage());
// Send error message back to JavaScript
//this.sendJavascript("dddb.fail('" + ex.getMessage() + "','" + tx_id + "');");
}
finally {
this.myDb.endTransaction();
Log.v("executeSqlBatch", tx_id);
this.sendJavascript("SQLitePluginTransaction.txCompleteCallback('" + 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.
*
* @param cur
* Cursor into query results
* @param tx_id
* Transaction id
*/
public void processResults(Cursor cur, String query_id, 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.sendJavascript(" SQLitePluginTransaction.queryCompleteCallback('" + tx_id + "','" + query_id + "', " + result + ");");
}
}