@unvired/cordova-plugin-unvired-electron-db 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin.xml +1 -1
- package/src/android/DBPlugin.java +38 -33
- package/src/browser/DbPluginProxy.js +32 -30
- package/src/electron/package.json +1 -1
- package/src/electron/unvired-db-proxy.js +8 -18
- package/src/ios/UnviredDB.m +29 -11
package/package.json
CHANGED
package/plugin.xml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version='1.0' encoding='utf-8'?>
|
|
2
2
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
3
3
|
id="@unvired/cordova-plugin-unvired-electron-db"
|
|
4
|
-
version="0.0.
|
|
4
|
+
version="0.0.44"
|
|
5
5
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
6
6
|
<name>Unvired DB</name>
|
|
7
7
|
<description>Unvired DB Native Support for Cordova</description>
|
|
@@ -117,6 +117,7 @@ public class DBPlugin extends CordovaPlugin {
|
|
|
117
117
|
String userId = params.getString("userId");
|
|
118
118
|
String dbType = params.getString("dbType");
|
|
119
119
|
String query = params.getString("query");
|
|
120
|
+
JSONArray queryArgs = params.optJSONArray("args");
|
|
120
121
|
|
|
121
122
|
if (userId == null || userId.isEmpty()) {
|
|
122
123
|
callbackContext.error("userId is required");
|
|
@@ -145,44 +146,48 @@ public class DBPlugin extends CordovaPlugin {
|
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
try {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
149
|
+
String[] selectionArgs = null;
|
|
150
|
+
if (queryArgs != null && queryArgs.length() > 0) {
|
|
151
|
+
selectionArgs = new String[queryArgs.length()];
|
|
152
|
+
for (int i = 0; i < queryArgs.length(); i++) {
|
|
153
|
+
Object val = queryArgs.get(i);
|
|
154
|
+
selectionArgs[i] = (val == null || val == JSONObject.NULL) ? null : String.valueOf(val);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
JSONArray results = new JSONArray();
|
|
159
|
+
android.database.Cursor cursor = db.rawQuery(query, selectionArgs);
|
|
160
|
+
if (cursor != null) {
|
|
161
|
+
try {
|
|
162
|
+
String[] columnNames = cursor.getColumnNames();
|
|
163
|
+
while (cursor.moveToNext()) {
|
|
164
|
+
JSONObject row = new JSONObject();
|
|
165
|
+
for (String columnName : columnNames) {
|
|
166
|
+
int columnIndex = cursor.getColumnIndex(columnName);
|
|
167
|
+
switch (cursor.getType(columnIndex)) {
|
|
168
|
+
case android.database.Cursor.FIELD_TYPE_INTEGER:
|
|
169
|
+
row.put(columnName, cursor.getLong(columnIndex));
|
|
170
|
+
break;
|
|
171
|
+
case android.database.Cursor.FIELD_TYPE_FLOAT:
|
|
172
|
+
row.put(columnName, cursor.getDouble(columnIndex));
|
|
173
|
+
break;
|
|
174
|
+
case android.database.Cursor.FIELD_TYPE_STRING:
|
|
175
|
+
row.put(columnName, cursor.getString(columnIndex));
|
|
176
|
+
break;
|
|
177
|
+
case android.database.Cursor.FIELD_TYPE_BLOB:
|
|
178
|
+
row.put(columnName, cursor.getBlob(columnIndex));
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
row.put(columnName, JSONObject.NULL);
|
|
174
182
|
}
|
|
175
|
-
results.put(row);
|
|
176
183
|
}
|
|
177
|
-
|
|
178
|
-
cursor.close();
|
|
184
|
+
results.put(row);
|
|
179
185
|
}
|
|
186
|
+
} finally {
|
|
187
|
+
cursor.close();
|
|
180
188
|
}
|
|
181
|
-
callbackContext.success(results);
|
|
182
|
-
} else {
|
|
183
|
-
db.execSQL(query);
|
|
184
|
-
callbackContext.success("Success");
|
|
185
189
|
}
|
|
190
|
+
callbackContext.success(results);
|
|
186
191
|
} catch (SQLiteException e) {
|
|
187
192
|
Log.e(TAG, "Error executing query", e);
|
|
188
193
|
callbackContext.error("Error executing query: " + e.getMessage());
|
|
@@ -27,35 +27,37 @@ module.exports.create = async function (sucessCallback, errorCallback, options)
|
|
|
27
27
|
module.exports.execute = async function (sucessCallback, errorCallback, options) {
|
|
28
28
|
const dbType = options[0].dbType
|
|
29
29
|
const query = options[0].query;
|
|
30
|
+
const args = options[0].args || [];
|
|
30
31
|
try {
|
|
31
32
|
const db = dbType == DBType.FrameworkDb ? webDb.fwDb : webDb.appDb;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let rows = [];
|
|
39
|
-
var stmt = db.prepare(query);
|
|
40
|
-
while (stmt.step()) {
|
|
41
|
-
var row = stmt.getAsObject();
|
|
42
|
-
rows.push(row);
|
|
34
|
+
var parsedQuery = {query: query, values: []}
|
|
35
|
+
if (args.length > 0) {
|
|
36
|
+
parsedQuery = {
|
|
37
|
+
query: query,
|
|
38
|
+
values: args
|
|
43
39
|
}
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
parsedQuery = webDb.parseQueryToPrepared(query);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let stmt;
|
|
46
|
+
if (parsedQuery.values.length > 0) {
|
|
47
|
+
stmt = db.prepare(parsedQuery.query);
|
|
48
|
+
stmt.bind(parsedQuery.values);
|
|
46
49
|
} else {
|
|
47
|
-
|
|
48
|
-
const parsedQuery = webDb.parseQueryToPrepared(query);
|
|
49
|
-
if (parsedQuery.isPrepared) {
|
|
50
|
-
var stmt = db.prepare(parsedQuery.query);
|
|
51
|
-
stmt.run(parsedQuery.values);
|
|
52
|
-
stmt.free();
|
|
53
|
-
} else {
|
|
54
|
-
// Fallback to exec for queries without parameters
|
|
55
|
-
db.exec(query);
|
|
56
|
-
}
|
|
57
|
-
sucessCallback("Success");
|
|
50
|
+
stmt = db.prepare(query);
|
|
58
51
|
}
|
|
52
|
+
|
|
53
|
+
// Execute statement and capture results if any
|
|
54
|
+
let rows = [];
|
|
55
|
+
while (stmt.step()) {
|
|
56
|
+
rows.push(stmt.getAsObject());
|
|
57
|
+
}
|
|
58
|
+
stmt.free();
|
|
59
|
+
|
|
60
|
+
sucessCallback(rows);
|
|
59
61
|
}
|
|
60
62
|
catch (err) {
|
|
61
63
|
console.error("Error executing query: " + query, err);
|
|
@@ -252,7 +254,7 @@ var webDb = /** @class */ (function () {
|
|
|
252
254
|
|
|
253
255
|
// If query already contains positional placeholders, don't attempt to re-parameterize it.
|
|
254
256
|
if (query.indexOf('?') !== -1) {
|
|
255
|
-
return {
|
|
257
|
+
return { query: query, values: [] };
|
|
256
258
|
}
|
|
257
259
|
if (queryUpper.startsWith('CREATE') ||
|
|
258
260
|
queryUpper.startsWith('DROP') ||
|
|
@@ -276,7 +278,7 @@ var webDb = /** @class */ (function () {
|
|
|
276
278
|
// DDL/transactional statements and similar should not be parameterized.
|
|
277
279
|
// Note: INSERT ... VALUES will be parameterized below so large
|
|
278
280
|
// string/numeric literals (eg. base64 blobs) can be bound safely.
|
|
279
|
-
return {
|
|
281
|
+
return { query: query, values: [] };
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
|
|
@@ -285,7 +287,7 @@ var webDb = /** @class */ (function () {
|
|
|
285
287
|
const hasNumericLiterals = /\b\d+\.?\d*\b/.test(query);
|
|
286
288
|
|
|
287
289
|
if (!hasStringLiterals && !hasNumericLiterals) {
|
|
288
|
-
return {
|
|
290
|
+
return { query: query, values: [] };
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
// We'll scan the original query left-to-right and replace literals with
|
|
@@ -333,7 +335,7 @@ var webDb = /** @class */ (function () {
|
|
|
333
335
|
|
|
334
336
|
if (!closed) {
|
|
335
337
|
// Unmatched quote; bail out to safe fallback to avoid errors
|
|
336
|
-
return {
|
|
338
|
+
return { query: query, values: [] };
|
|
337
339
|
}
|
|
338
340
|
|
|
339
341
|
// Extract content and handle escaped quotes
|
|
@@ -396,13 +398,13 @@ var webDb = /** @class */ (function () {
|
|
|
396
398
|
|
|
397
399
|
// If we didn't find any bindable literals, don't treat as prepared
|
|
398
400
|
if (values.length === 0) {
|
|
399
|
-
return {
|
|
401
|
+
return { query: query, values: [] };
|
|
400
402
|
}
|
|
401
403
|
|
|
402
|
-
return {
|
|
404
|
+
return { query: preparedQuery, values: values };
|
|
403
405
|
} catch (err) {
|
|
404
406
|
console.warn('Error parsing query to prepared statement:', err);
|
|
405
|
-
return {
|
|
407
|
+
return { query: query, values: [] };
|
|
406
408
|
}
|
|
407
409
|
};
|
|
408
410
|
|
|
@@ -52,6 +52,7 @@ const execute = (args) => {
|
|
|
52
52
|
const userId = args[0].userId
|
|
53
53
|
const dbType = args[0].dbType
|
|
54
54
|
const query = args[0].query;
|
|
55
|
+
const queryArgs = args[0].args || [];
|
|
55
56
|
|
|
56
57
|
if (userId == undefined || userId == null || userId == "") {
|
|
57
58
|
reject("userId is required")
|
|
@@ -79,24 +80,13 @@ const execute = (args) => {
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
db.run(query, (err) => {
|
|
93
|
-
if (err) {
|
|
94
|
-
reject(err)
|
|
95
|
-
} else {
|
|
96
|
-
resolve("Success")
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
83
|
+
db.all(query, queryArgs, (err, rows) => {
|
|
84
|
+
if (err) {
|
|
85
|
+
reject(err)
|
|
86
|
+
} else {
|
|
87
|
+
resolve(rows || []) // Ensure we return an array
|
|
88
|
+
}
|
|
89
|
+
});
|
|
100
90
|
});
|
|
101
91
|
}
|
|
102
92
|
|
package/src/ios/UnviredDB.m
CHANGED
|
@@ -129,12 +129,12 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
129
129
|
// enable foreign Keys ON
|
|
130
130
|
NSError *error = NULL;
|
|
131
131
|
|
|
132
|
-
[self executeQuery:@"PRAGMA journal_mode = WAL;" sqlDb:self->fwDb error:&error];
|
|
133
|
-
[self executeQuery:@"PRAGMA read_uncommitted = 1;" sqlDb:self->fwDb error:&error];
|
|
132
|
+
[self executeQuery:@"PRAGMA journal_mode = WAL;" args:nil sqlDb:self->fwDb error:&error];
|
|
133
|
+
[self executeQuery:@"PRAGMA read_uncommitted = 1;" args:nil sqlDb:self->fwDb error:&error];
|
|
134
134
|
|
|
135
|
-
[self executeQuery:@"PRAGMA journal_mode = WAL;" sqlDb:self->appDb error:&error];
|
|
136
|
-
[self executeQuery:@"PRAGMA foreign_keys = ON;" sqlDb:self->appDb error:&error];
|
|
137
|
-
[self executeQuery:@"PRAGMA read_uncommitted = 1;" sqlDb:self->appDb error:&error];
|
|
135
|
+
[self executeQuery:@"PRAGMA journal_mode = WAL;" args:nil sqlDb:self->appDb error:&error];
|
|
136
|
+
[self executeQuery:@"PRAGMA foreign_keys = ON;" args:nil sqlDb:self->appDb error:&error];
|
|
137
|
+
[self executeQuery:@"PRAGMA read_uncommitted = 1;" args:nil sqlDb:self->appDb error:&error];
|
|
138
138
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:true];
|
|
139
139
|
[pluginResult setKeepCallbackAsBool:true];
|
|
140
140
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
@@ -160,6 +160,7 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
160
160
|
NSString *userId = dataObjects[@"userId"];
|
|
161
161
|
NSString *dbType = dataObjects[@"dbType"];
|
|
162
162
|
NSString *query = dataObjects[@"query"];
|
|
163
|
+
NSArray *args = dataObjects[@"args"];
|
|
163
164
|
|
|
164
165
|
sqlite3 *sql = [dbType isEqualToString:DBTypeFrameworkDb] ? self->fwDb : self->appDb;
|
|
165
166
|
|
|
@@ -173,11 +174,7 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
// NSLog(@"EXECUTE QUERY: %@", query);
|
|
176
|
-
|
|
177
|
-
[self executeCreate:query sqlDb:sql error:&error];
|
|
178
|
-
else {
|
|
179
|
-
result = [self executeQuery:query sqlDb:sql error:&error];
|
|
180
|
-
}
|
|
177
|
+
result = [self executeQuery:query args:args sqlDb:sql error:&error];
|
|
181
178
|
if (error == NULL) {
|
|
182
179
|
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:result];
|
|
183
180
|
}
|
|
@@ -309,7 +306,7 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
309
306
|
return YES;
|
|
310
307
|
}
|
|
311
308
|
|
|
312
|
-
- (NSArray *)executeQuery:(NSString *)sqlStatement sqlDb:(sqlite3 *)sql error:(NSError **)error {
|
|
309
|
+
- (NSArray *)executeQuery:(NSString *)sqlStatement args:(NSArray *)args sqlDb:(sqlite3 *)sql error:(NSError **)error {
|
|
313
310
|
|
|
314
311
|
sqlite3_stmt *statement;
|
|
315
312
|
statement = [self prepareStatement:sqlStatement sqlDb:sql error:error];
|
|
@@ -317,6 +314,27 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
317
314
|
if (statement == NULL) {
|
|
318
315
|
return NULL;
|
|
319
316
|
}
|
|
317
|
+
|
|
318
|
+
if (args && [args isKindOfClass:[NSArray class]] && [args count] > 0) {
|
|
319
|
+
for (int i = 0; i < [args count]; i++) {
|
|
320
|
+
id val = args[i];
|
|
321
|
+
int idx = i + 1;
|
|
322
|
+
if ([val isKindOfClass:[NSString class]]) {
|
|
323
|
+
sqlite3_bind_text(statement, idx, [val UTF8String], -1, SQLITE_TRANSIENT);
|
|
324
|
+
} else if ([val isKindOfClass:[NSNumber class]]) {
|
|
325
|
+
const char *objCType = [val objCType];
|
|
326
|
+
if (strcmp(objCType, @encode(double)) == 0 || strcmp(objCType, @encode(float)) == 0) {
|
|
327
|
+
sqlite3_bind_double(statement, idx, [val doubleValue]);
|
|
328
|
+
} else {
|
|
329
|
+
sqlite3_bind_int64(statement, idx, [val longLongValue]);
|
|
330
|
+
}
|
|
331
|
+
} else if ([val isKindOfClass:[NSNull class]]) {
|
|
332
|
+
sqlite3_bind_null(statement, idx);
|
|
333
|
+
} else {
|
|
334
|
+
sqlite3_bind_text(statement, idx, [[NSString stringWithFormat:@"%@", val] UTF8String], -1, SQLITE_TRANSIENT);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
320
338
|
|
|
321
339
|
NSLog(@"Statement: %@", sqlStatement);
|
|
322
340
|
|