Ben Ashton
3 years ago
commit
5bf0b6752b
15 changed files with 734 additions and 0 deletions
@ -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" |
||||||
|
} |
||||||
|
} |
@ -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> |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package org.n0m.pawsqlite; |
||||||
|
|
||||||
|
public enum DBAction { |
||||||
|
VERSION, |
||||||
|
OPEN, |
||||||
|
CLOSE, |
||||||
|
DELETE, |
||||||
|
SQL |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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") |
||||||
|
); |
||||||
|
} |
@ -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 |
||||||
|
}; |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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