Initial commit
This commit is contained in:
commit
5bf0b6752b
31
package.json
Executable file
31
package.json
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "pawsqlite-cordova-adapter",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Cordova adapter for PawSQLite",
|
||||||
|
"cordova": {
|
||||||
|
"id": "org.n0m.pawsqlite",
|
||||||
|
"platforms": [
|
||||||
|
"android"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "webpack"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.n0m.org/n0m/PawSQLite-Cordova-Adapter.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"cordova",
|
||||||
|
"sqlite",
|
||||||
|
"ecosystem:cordova",
|
||||||
|
"cordova-android"
|
||||||
|
],
|
||||||
|
"author": "Ben Ashton",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"webpack": "5.x",
|
||||||
|
"webpack-cli": "4.x"
|
||||||
|
}
|
||||||
|
}
|
30
plugin.xml
Normal file
30
plugin.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||||
|
id="org.n0m.pawsqlite" version="0.2.3">
|
||||||
|
<name>PawSQLite</name>
|
||||||
|
<description>Cordova SQLite Plugin</description>
|
||||||
|
<license></license>
|
||||||
|
<keywords>cordova,sqlite</keywords>
|
||||||
|
<js-module src="www/pawsqlite-cordova-adapter.js" name="PawSQLite">
|
||||||
|
<clobbers target="PawSQLite" />
|
||||||
|
</js-module>
|
||||||
|
<platform name="android">
|
||||||
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
|
<feature name="PawSQLite">
|
||||||
|
<param name="android-package" value="org.n0m.pawsqlite.PawSQLite" />
|
||||||
|
</feature>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<config-file target="AndroidManifest.xml" parent="/*">
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/android/CallbackWrapper.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/DB.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/DBAction.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/DBManager.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/DBRequest.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/DBRunner.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/PawSQLite.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
<source-file src="src/android/QueryWrapper.java" target-dir="src/ca/patterpaws/sqlite" />
|
||||||
|
</platform>
|
||||||
|
</plugin>
|
72
src/android/CallbackWrapper.java
Normal file
72
src/android/CallbackWrapper.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
|
||||||
|
|
||||||
|
public class CallbackWrapper {
|
||||||
|
private CallbackContext callbackContext;
|
||||||
|
|
||||||
|
CallbackWrapper(CallbackContext callbackContext) {
|
||||||
|
this.callbackContext = callbackContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(String name) {
|
||||||
|
error(name, null, null);
|
||||||
|
}
|
||||||
|
public void error(String name, String message) {
|
||||||
|
error(name, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(String name, Exception e) {
|
||||||
|
String message = null;
|
||||||
|
if (e != null) {
|
||||||
|
message = e.getMessage();
|
||||||
|
}
|
||||||
|
error(name, message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(String name, String message, Exception e) {
|
||||||
|
try {
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
|
response.put("name", name);
|
||||||
|
|
||||||
|
if (message != null) {
|
||||||
|
response.put("message", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != null) {
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(stringWriter));
|
||||||
|
response.put("trace", stringWriter.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
callbackContext.error(response);
|
||||||
|
} catch (JSONException jsonException) {
|
||||||
|
callbackContext.error("Encountered error and unable to generate " +
|
||||||
|
"response");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void success() {
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
|
success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void success(JSONObject response) {
|
||||||
|
if (!response.has("success")) {
|
||||||
|
try {
|
||||||
|
response.put("success", true);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// Will never happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callbackContext.success(response);
|
||||||
|
}
|
||||||
|
}
|
132
src/android/DB.java
Normal file
132
src/android/DB.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.SQLException;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
|
|
||||||
|
class DB {
|
||||||
|
private static final String TAG = "PawSQLite";
|
||||||
|
|
||||||
|
public final String dbName;
|
||||||
|
private File dbFile;
|
||||||
|
|
||||||
|
public SQLiteDatabase db;
|
||||||
|
|
||||||
|
|
||||||
|
public DB (File dbFile, String dbName) {
|
||||||
|
this.dbFile = dbFile;
|
||||||
|
this.dbName = dbName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleRequest(DBRequest request) {
|
||||||
|
try {
|
||||||
|
switch(request.action) {
|
||||||
|
case VERSION:
|
||||||
|
version(request.callback);
|
||||||
|
break;
|
||||||
|
case OPEN:
|
||||||
|
open(request.callback);
|
||||||
|
break;
|
||||||
|
case SQL:
|
||||||
|
sql(request.args, request.callback);
|
||||||
|
break;
|
||||||
|
case CLOSE:
|
||||||
|
close(request.callback);
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
delete(request.callback);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
request.callback.error("Unrecognised Action");
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
request.callback.error("JSONException", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open(CallbackWrapper callback) throws JSONException {
|
||||||
|
if (db == null || !db.isOpen()) {
|
||||||
|
db = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
|
response.put("path", db.getPath());
|
||||||
|
response.put("version", db.getVersion());
|
||||||
|
callback.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void delete(CallbackWrapper callback) {
|
||||||
|
if (db == null) {
|
||||||
|
if(SQLiteDatabase.deleteDatabase(dbFile)) {
|
||||||
|
callback.success();
|
||||||
|
} else {
|
||||||
|
callback.error("Unable to Delete Database",
|
||||||
|
"SQLiteDatabase.deleteDatabase returned false");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.error("Unable to Delete Database",
|
||||||
|
"Database is currently open");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sql(JSONArray args, CallbackWrapper callback) throws JSONException {
|
||||||
|
if (db == null) {
|
||||||
|
callback.error(
|
||||||
|
"DB Not open",
|
||||||
|
"Database: " + dbName + " is not open"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = args.optString(0);
|
||||||
|
// Remove query from args
|
||||||
|
args.remove(0);
|
||||||
|
|
||||||
|
QueryWrapper queryWrapper = new QueryWrapper(db, query, args);
|
||||||
|
|
||||||
|
JSONObject result;
|
||||||
|
try {
|
||||||
|
result = queryWrapper.execute();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
callback.error("SQLException", e);
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
callback.error("Exception", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.success(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close(CallbackWrapper callback) {
|
||||||
|
if (db != null) {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
callback.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void version(CallbackWrapper callback) throws JSONException {
|
||||||
|
String query = "select sqlite_version() AS sqlite_version";
|
||||||
|
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(":memory:", null);
|
||||||
|
Cursor cursor = db.rawQuery(query, null);
|
||||||
|
String sqliteVersion = "";
|
||||||
|
if (cursor.moveToNext()) {
|
||||||
|
sqliteVersion = cursor.getString(0);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
db.close();
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
result.put("version", sqliteVersion);
|
||||||
|
callback.success(result);
|
||||||
|
}
|
||||||
|
}
|
9
src/android/DBAction.java
Normal file
9
src/android/DBAction.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
public enum DBAction {
|
||||||
|
VERSION,
|
||||||
|
OPEN,
|
||||||
|
CLOSE,
|
||||||
|
DELETE,
|
||||||
|
SQL
|
||||||
|
}
|
44
src/android/DBManager.java
Normal file
44
src/android/DBManager.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaInterface;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class DBManager {
|
||||||
|
private static final String TAG = "PawSQLite";
|
||||||
|
|
||||||
|
private CordovaInterface cordova;
|
||||||
|
private ConcurrentHashMap<String, DBRunner> dbRunnerMap =
|
||||||
|
new ConcurrentHashMap<String, DBRunner>();
|
||||||
|
|
||||||
|
|
||||||
|
DBManager(CordovaInterface cordova) {
|
||||||
|
this.cordova = cordova;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueRequest(String dbName, DBRequest request) {
|
||||||
|
DBRunner dbRunner = dbRunnerMap.get(dbName);
|
||||||
|
|
||||||
|
if (dbRunner == null) {
|
||||||
|
File dbFile = cordova.getActivity().getDatabasePath(dbName);
|
||||||
|
dbRunner = new DBRunner(dbFile, dbName);
|
||||||
|
this.cordova.getThreadPool().execute(dbRunner);
|
||||||
|
dbRunnerMap.put(dbName, dbRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbRunner.queueRequest(request);
|
||||||
|
|
||||||
|
// Remove dbRunner if it is being closed
|
||||||
|
if (request.action == DBAction.CLOSE ||
|
||||||
|
request.action == DBAction.DELETE) {
|
||||||
|
|
||||||
|
this.remove(dbName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(String dbName) {
|
||||||
|
dbRunnerMap.remove(dbName);
|
||||||
|
}
|
||||||
|
}
|
18
src/android/DBRequest.java
Normal file
18
src/android/DBRequest.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
|
||||||
|
|
||||||
|
public class DBRequest {
|
||||||
|
private static final String TAG = "PawSQLite";
|
||||||
|
|
||||||
|
public DBAction action;
|
||||||
|
public JSONArray args;
|
||||||
|
public CallbackWrapper callback;
|
||||||
|
|
||||||
|
DBRequest(DBAction action, JSONArray args, CallbackWrapper callback) {
|
||||||
|
this.action = action;
|
||||||
|
this.args = args;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
}
|
50
src/android/DBRunner.java
Normal file
50
src/android/DBRunner.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
public class DBRunner implements Runnable {
|
||||||
|
private static final String TAG = "PawSQLite";
|
||||||
|
|
||||||
|
private LinkedBlockingQueue<DBRequest> queue;
|
||||||
|
|
||||||
|
public String dbName;
|
||||||
|
private File dbFile;
|
||||||
|
|
||||||
|
DBRunner(File dbFile, final String dbName) {
|
||||||
|
queue = new LinkedBlockingQueue<DBRequest>();
|
||||||
|
this.dbFile = dbFile;
|
||||||
|
this.dbName = dbName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueRequest(DBRequest request) {
|
||||||
|
try {
|
||||||
|
queue.put(request);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, "Unexpected Error", e);
|
||||||
|
request.callback.error(
|
||||||
|
"Unexpected Error",
|
||||||
|
"Thread Interrupted",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
DBRequest request;
|
||||||
|
DB db = new DB(dbFile, dbName);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
request = queue.take();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, "Unexpected Error", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
db.handleRequest(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
src/android/PawSQLite.java
Normal file
67
src/android/PawSQLite.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
public class PawSQLite extends CordovaPlugin {
|
||||||
|
private static final String TAG = "PawSQLite";
|
||||||
|
|
||||||
|
DBManager dbManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void pluginInitialize() {
|
||||||
|
Log.d(TAG, "Initialized Plugin");
|
||||||
|
this.dbManager = new DBManager(this.cordova);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String actionStr, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||||
|
CallbackWrapper callback = new CallbackWrapper(callbackContext);
|
||||||
|
|
||||||
|
// Get Action
|
||||||
|
DBAction action;
|
||||||
|
try {
|
||||||
|
action = DBAction.valueOf(actionStr.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get DB Name
|
||||||
|
String dbName = args.optString(0).trim();
|
||||||
|
|
||||||
|
if (dbName.isEmpty()) {
|
||||||
|
callback.error(
|
||||||
|
"Unknown Database",
|
||||||
|
"Database name not included in request"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove dbName so that remaining args can be handled appropriately
|
||||||
|
args.remove(0);
|
||||||
|
|
||||||
|
// Queue request
|
||||||
|
DBRequest request = new DBRequest(action, args, callback);
|
||||||
|
dbManager.queueRequest(dbName, request);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject jsonError(String name, String message) throws JSONException {
|
||||||
|
JSONObject response = new JSONObject();
|
||||||
|
|
||||||
|
JSONObject error = new JSONObject();
|
||||||
|
error.put("name", name);
|
||||||
|
error.put("message", message);
|
||||||
|
response.put("error", error);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
188
src/android/QueryWrapper.java
Normal file
188
src/android/QueryWrapper.java
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package org.n0m.pawsqlite;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteStatement;
|
||||||
|
import android.database.SQLException;
|
||||||
|
import android.database.Cursor;
|
||||||
|
|
||||||
|
|
||||||
|
class QueryWrapper {
|
||||||
|
static enum QueryType {
|
||||||
|
SELECT,
|
||||||
|
INSERT,
|
||||||
|
UPDATE,
|
||||||
|
DELETE,
|
||||||
|
BEGIN,
|
||||||
|
COMMIT,
|
||||||
|
ROLLBACK,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLiteDatabase db;
|
||||||
|
String query;
|
||||||
|
QueryType queryType;
|
||||||
|
JSONArray args;
|
||||||
|
|
||||||
|
public QueryWrapper(SQLiteDatabase db, String query, JSONArray args) {
|
||||||
|
this.db = db;
|
||||||
|
this.args = args;
|
||||||
|
|
||||||
|
query = query.trim();
|
||||||
|
|
||||||
|
// Strip trailing semi-colon
|
||||||
|
if (query.endsWith(";")) {
|
||||||
|
query = query.substring(0, query.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String operation = query
|
||||||
|
.replaceAll("[^a-zA-Z].*", "")
|
||||||
|
.toUpperCase();
|
||||||
|
|
||||||
|
try {
|
||||||
|
queryType = QueryType.valueOf(operation);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
queryType = QueryType.OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject execute() throws JSONException, SQLException {
|
||||||
|
JSONObject result = new JSONObject();
|
||||||
|
|
||||||
|
result.put("query", query);
|
||||||
|
result.put("args", args);
|
||||||
|
|
||||||
|
switch (queryType) {
|
||||||
|
case SELECT:
|
||||||
|
executeRaw(result);
|
||||||
|
break;
|
||||||
|
case INSERT:
|
||||||
|
executeInsert(result);
|
||||||
|
break;
|
||||||
|
case UPDATE:
|
||||||
|
case DELETE:
|
||||||
|
executeUpdateDelete(result);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
executeOther(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject executeInsert(JSONObject result) throws JSONException, SQLException {
|
||||||
|
SQLiteStatement statement = compileStatement();
|
||||||
|
|
||||||
|
long rowId = statement.executeInsert();
|
||||||
|
|
||||||
|
result.put("insertId", rowId);
|
||||||
|
|
||||||
|
// Allow chaining
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private JSONObject executeUpdateDelete(JSONObject result) throws JSONException, SQLException {
|
||||||
|
SQLiteStatement statement = compileStatement();
|
||||||
|
|
||||||
|
int rowsAffected = statement.executeUpdateDelete();
|
||||||
|
|
||||||
|
result.put("rowsAffected", rowsAffected);
|
||||||
|
|
||||||
|
// Allow chaining
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject executeOther(JSONObject result) throws JSONException, SQLException {
|
||||||
|
SQLiteStatement statement = compileStatement();
|
||||||
|
statement.execute();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private SQLiteStatement compileStatement() throws JSONException, SQLException {
|
||||||
|
SQLiteStatement statement = db.compileStatement(query);
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length(); i++) {
|
||||||
|
if (args.get(i) instanceof Float || args.get(i) instanceof Double) {
|
||||||
|
statement.bindDouble(i + 1, args.getDouble(i));
|
||||||
|
} else if (args.get(i) instanceof Number) {
|
||||||
|
statement.bindLong(i + 1, args.getLong(i));
|
||||||
|
} else if (args.isNull(i)) {
|
||||||
|
statement.bindNull(i + 1);
|
||||||
|
} else {
|
||||||
|
statement.bindString(i + 1, args.getString(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private JSONObject executeRaw(JSONObject result) throws JSONException {
|
||||||
|
String[] stringArgs = new String[args.length()];
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length(); i++) {
|
||||||
|
if (args.isNull(i)) {
|
||||||
|
stringArgs[i] = "";
|
||||||
|
} else {
|
||||||
|
stringArgs[i] = args.getString(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor cur = db.rawQuery(query, stringArgs);
|
||||||
|
|
||||||
|
if (cur != null) {
|
||||||
|
JSONArray rows = cursorToJSONArray(cur);
|
||||||
|
result.put("rows", rows);
|
||||||
|
cur.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow chaining
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONArray cursorToJSONArray(Cursor cur) throws JSONException {
|
||||||
|
JSONArray rows = new JSONArray();
|
||||||
|
|
||||||
|
if (cur != null && cur.moveToFirst()) {
|
||||||
|
int colCount = cur.getColumnCount();
|
||||||
|
|
||||||
|
do {
|
||||||
|
JSONObject row = new JSONObject();
|
||||||
|
|
||||||
|
for (int i = 0; i < colCount; i++) {
|
||||||
|
String key = cur.getColumnName(i);
|
||||||
|
|
||||||
|
switch(cur.getType(i)) {
|
||||||
|
case Cursor.FIELD_TYPE_NULL:
|
||||||
|
row.put(key, JSONObject.NULL);
|
||||||
|
break;
|
||||||
|
case Cursor.FIELD_TYPE_INTEGER:
|
||||||
|
row.put(key, cur.getLong(i));
|
||||||
|
break;
|
||||||
|
case Cursor.FIELD_TYPE_FLOAT:
|
||||||
|
row.put(key, cur.getDouble(i));
|
||||||
|
break;
|
||||||
|
case Cursor.FIELD_TYPE_STRING:
|
||||||
|
case Cursor.FIELD_TYPE_BLOB:
|
||||||
|
default:
|
||||||
|
row.put(key, cur.getString(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rows.put(row);
|
||||||
|
}
|
||||||
|
while (cur.moveToNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
}
|
14
src/log.mjs
Normal file
14
src/log.mjs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
let DEBUG = false;
|
||||||
|
|
||||||
|
export function log(...args) {
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function enableDebug(active) {
|
||||||
|
DEBUG = !!active;
|
||||||
|
log("PawSQLite-Cordova-Adapter: debugging " + (
|
||||||
|
DEBUG ? "enabled" : "disabled")
|
||||||
|
);
|
||||||
|
}
|
31
src/psql_adapter.mjs
Normal file
31
src/psql_adapter.mjs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { PSQLAdapterError } from "./psql_adapter_error.mjs";
|
||||||
|
import { log, enableDebug } from "./log.mjs";
|
||||||
|
|
||||||
|
|
||||||
|
export const PSQLAdapter = {
|
||||||
|
name: "PawSQLiteCordovaAdapter",
|
||||||
|
|
||||||
|
open: (dbName) => new Promise((resolve, reject) => {
|
||||||
|
cordova.exec(resolve, (e) => {
|
||||||
|
reject(new PSQLAdapterError(e));
|
||||||
|
}, "PawSQLite", "open", [dbName]);
|
||||||
|
}),
|
||||||
|
close: (dbName) => new Promise((resolve, reject) => {
|
||||||
|
cordova.exec(resolve, (e) => {
|
||||||
|
reject(new PSQLAdapterError(e));
|
||||||
|
}, "PawSQLite", "close", [dbName]);
|
||||||
|
}),
|
||||||
|
sql: (dbName, sql, ...args) => new Promise((resolve, reject) => {
|
||||||
|
log(sql);
|
||||||
|
cordova.exec(resolve, (e) => {
|
||||||
|
reject(new PSQLAdapterError(e));
|
||||||
|
}, "PawSQLite", "sql", [dbName, sql, ...args]);
|
||||||
|
}),
|
||||||
|
delete: (dbName) => new Promise((resolve, reject) => {
|
||||||
|
cordova.exec(resolve, (e) => {
|
||||||
|
reject(new PSQLAdapterError(e));
|
||||||
|
}, "PawSQLite", "delete", [dbName]);
|
||||||
|
}),
|
||||||
|
|
||||||
|
debug: enableDebug
|
||||||
|
};
|
28
src/psql_adapter_error.mjs
Normal file
28
src/psql_adapter_error.mjs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export class PSQLAdapterError extends Error {
|
||||||
|
constructor(response) {
|
||||||
|
if (response.hasOwnProperty("message")) {
|
||||||
|
super(response.message);
|
||||||
|
} else {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
if (response.hasOwnProperty("name")) {
|
||||||
|
this.name = response.name;
|
||||||
|
} else {
|
||||||
|
this.name = "PSQLAdapterError";
|
||||||
|
}
|
||||||
|
if (response.hasOwnProperty("trace")) {
|
||||||
|
this.trace = response.trace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
let str = this.name;
|
||||||
|
if (this.hasOwnProperty("message")) {
|
||||||
|
str += ": " + this.message;
|
||||||
|
}
|
||||||
|
if (this.hasOwnProperty("trace")) {
|
||||||
|
str += "\n" + this.trace;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
17
webpack.config.js
Normal file
17
webpack.config.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
var webpack = require('webpack');
|
||||||
|
var libraryName = 'pawsqlite-cordova-adapter';
|
||||||
|
var outputFile = libraryName + '.js';
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
mode: 'development',
|
||||||
|
entry: __dirname + '/src/psql_adapter.mjs',
|
||||||
|
devtool: 'source-map',
|
||||||
|
output: {
|
||||||
|
path: __dirname + '/www',
|
||||||
|
filename: outputFile,
|
||||||
|
libraryExport: 'default',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
Loading…
Reference in New Issue
Block a user