@unvired/cordova-plugin-unvired-electron-db 0.0.37 → 0.0.39
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 +7 -0
- package/src/browser/DbPluginProxy.js +17 -0
- package/src/electron/package.json +1 -1
- package/src/electron/unvired-db-proxy.js +70 -42
- package/src/ios/UnviredDB.h +2 -0
- package/src/ios/UnviredDB.m +12 -0
- package/www/unvired-db.js +4 -0
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.39"
|
|
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>
|
|
@@ -45,6 +45,9 @@ public class DBPlugin extends CordovaPlugin {
|
|
|
45
45
|
case "saveWebDB":
|
|
46
46
|
saveWebDB(args, callbackContext);
|
|
47
47
|
return true;
|
|
48
|
+
case "exportWebDB":
|
|
49
|
+
exportWebDB(args, callbackContext);
|
|
50
|
+
return true;
|
|
48
51
|
case "deleteUserData":
|
|
49
52
|
deleteUserData(args, callbackContext);
|
|
50
53
|
default:
|
|
@@ -253,6 +256,10 @@ public class DBPlugin extends CordovaPlugin {
|
|
|
253
256
|
private void saveWebDB(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
254
257
|
callbackContext.success("Web DB save is only for browser.");
|
|
255
258
|
}
|
|
259
|
+
|
|
260
|
+
private void exportWebDB(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
261
|
+
callbackContext.success();
|
|
262
|
+
}
|
|
256
263
|
|
|
257
264
|
private void deleteUserData(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
258
265
|
JSONObject params = args.getJSONObject(0);
|
|
@@ -85,6 +85,23 @@ module.exports.saveWebDB = async function(successCallback, errorCallback, option
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
module.exports.exportWebDB = async function(successCallback, errorCallback, options) {
|
|
89
|
+
//Download sqlite db
|
|
90
|
+
var arraybuff = webDb.appDb.export();
|
|
91
|
+
var blob = new Blob([arraybuff]);
|
|
92
|
+
var a = document.createElement("a");
|
|
93
|
+
document.body.appendChild(a);
|
|
94
|
+
a.href = window.URL.createObjectURL(blob);
|
|
95
|
+
a.download = "sql.db";
|
|
96
|
+
a.onclick = function () {
|
|
97
|
+
setTimeout(function () {
|
|
98
|
+
window.URL.revokeObjectURL(a.href);
|
|
99
|
+
}, 1500);
|
|
100
|
+
};
|
|
101
|
+
a.click();
|
|
102
|
+
successCallback();
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
// Execute raw query without returned result
|
|
89
106
|
module.exports.getDBFilePath = async function (sucessCallback, errorCallback, options) {
|
|
90
107
|
sucessCallback("");
|
|
@@ -28,7 +28,7 @@ const create = (args) => {
|
|
|
28
28
|
// Set PRAGMA for framework database
|
|
29
29
|
fwDb.run("PRAGMA journal_mode = WAL;");
|
|
30
30
|
fwDb.run("PRAGMA read_uncommitted = 1;");
|
|
31
|
-
return("Connected to database at " + fwDbFilePath)
|
|
31
|
+
return ("Connected to database at " + fwDbFilePath)
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
|
|
@@ -42,13 +42,13 @@ const create = (args) => {
|
|
|
42
42
|
appDb.run("PRAGMA journal_mode = WAL;");
|
|
43
43
|
appDb.run("PRAGMA read_uncommitted = 1;");
|
|
44
44
|
appDb.run("PRAGMA foreign_keys = ON;");
|
|
45
|
-
return("Connected to database at " + appDbFilePath)
|
|
45
|
+
return ("Connected to database at " + appDbFilePath)
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const execute = (args) => {
|
|
51
|
-
return new Promise((resolve,reject) => {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
52
|
const userId = args[0].userId
|
|
53
53
|
const dbType = args[0].dbType
|
|
54
54
|
const query = args[0].query;
|
|
@@ -57,20 +57,20 @@ const execute = (args) => {
|
|
|
57
57
|
reject("userId is required")
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
if (dbType != DBType.AppDb && dbType != DBType.FrameworkDb) {
|
|
62
62
|
reject("Invalid dbType")
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
if (query == undefined || query==null || query=="") {
|
|
66
|
+
if (query == undefined || query == null || query == "") {
|
|
67
67
|
reject("query is required")
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const db = dbType == DBType.AppDb ? appDb : fwDb;
|
|
72
72
|
|
|
73
|
-
if(db == null || db == undefined) {
|
|
73
|
+
if (db == null || db == undefined) {
|
|
74
74
|
try {
|
|
75
75
|
create(args);
|
|
76
76
|
} catch (error) {
|
|
@@ -79,7 +79,7 @@ const execute = (args) => {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
if(query.toUpperCase().includes("SELECT")) {
|
|
82
|
+
if (query.toUpperCase().includes("SELECT")) {
|
|
83
83
|
db.all(query, [], (err, rows) => {
|
|
84
84
|
if (err) {
|
|
85
85
|
reject(err)
|
|
@@ -100,16 +100,40 @@ const execute = (args) => {
|
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const close = ()=>{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
const close = () => {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const closeAppDb = new Promise((res) => {
|
|
106
|
+
if (appDb) {
|
|
107
|
+
appDb.close((err) => {
|
|
108
|
+
if (err) console.error("Error closing appDb:", err);
|
|
109
|
+
appDb = null;
|
|
110
|
+
appDbFilePath = null;
|
|
111
|
+
res();
|
|
112
|
+
});
|
|
113
|
+
} else {
|
|
114
|
+
res();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const closeFwDb = new Promise((res) => {
|
|
119
|
+
if (fwDb) {
|
|
120
|
+
fwDb.close((err) => {
|
|
121
|
+
if (err) console.error("Error closing fwDb:", err);
|
|
122
|
+
fwDb = null;
|
|
123
|
+
fwDbFilePath = null;
|
|
124
|
+
res();
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
res();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
Promise.all([closeAppDb, closeFwDb]).then(() => {
|
|
132
|
+
resolve("DB connection closed");
|
|
133
|
+
}).catch(err => {
|
|
134
|
+
reject(err);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
113
137
|
}
|
|
114
138
|
|
|
115
139
|
const getDBFilePath = (args) => {
|
|
@@ -140,12 +164,17 @@ const saveWebDB = (args) => {
|
|
|
140
164
|
return "Web DB save is only for browser."
|
|
141
165
|
}
|
|
142
166
|
|
|
167
|
+
const exportWebDB = (args) => {
|
|
168
|
+
// Return void or success message as requested
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
143
172
|
/**
|
|
144
173
|
* Deletes the user directory and all its contents for the given userId.
|
|
145
174
|
* @param {Array} args - Array with an object containing userId.
|
|
146
|
-
* @returns {string} - Success or error message.
|
|
175
|
+
* @returns {Promise<string>} - Success or error message.
|
|
147
176
|
*/
|
|
148
|
-
const deleteUserData = (args) => {
|
|
177
|
+
const deleteUserData = async (args) => {
|
|
149
178
|
const userId = args[0]?.userId;
|
|
150
179
|
if (!userId) {
|
|
151
180
|
throw new Error("userId is required");
|
|
@@ -154,30 +183,28 @@ const deleteUserData = (args) => {
|
|
|
154
183
|
if (!fs.existsSync(userPath)) {
|
|
155
184
|
return `User directory does not exist: ${userPath}`;
|
|
156
185
|
}
|
|
157
|
-
|
|
158
|
-
if
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (fwDb) {
|
|
186
|
+
|
|
187
|
+
// Close DBs if they are open. We must wait for them to close to release file locks on Windows.
|
|
188
|
+
await close();
|
|
189
|
+
|
|
190
|
+
// On Windows, file locks might take a few milliseconds to be released by the OS even after closing the connection.
|
|
191
|
+
// We use a retry mechanism to handle this.
|
|
192
|
+
const maxRetries = 10;
|
|
193
|
+
const retryDelay = 100; // ms
|
|
194
|
+
|
|
195
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
168
196
|
try {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
197
|
+
if (fs.existsSync(userPath)) {
|
|
198
|
+
fs.rmSync(userPath, { recursive: true, force: true });
|
|
199
|
+
}
|
|
200
|
+
return `User directory deleted: ${userPath}`;
|
|
201
|
+
} catch (err) {
|
|
202
|
+
if (i === maxRetries - 1) {
|
|
203
|
+
throw new Error(`Failed to delete user directory after ${maxRetries} attempts: ${err.message}`);
|
|
204
|
+
}
|
|
205
|
+
// Wait before retrying
|
|
206
|
+
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
172
207
|
}
|
|
173
|
-
fwDb = null;
|
|
174
|
-
fwDbFilePath = null;
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
fs.rmSync(userPath, { recursive: true, force: true });
|
|
178
|
-
return `User directory deleted: ${userPath}`;
|
|
179
|
-
} catch (err) {
|
|
180
|
-
throw new Error(`Failed to delete user directory: ${err.message}`);
|
|
181
208
|
}
|
|
182
209
|
}
|
|
183
210
|
|
|
@@ -193,7 +220,7 @@ app.on('before-quit', () => {
|
|
|
193
220
|
});
|
|
194
221
|
}
|
|
195
222
|
if (fwDb) {
|
|
196
|
-
|
|
223
|
+
fwDb.close((err) => {
|
|
197
224
|
if (err) {
|
|
198
225
|
throw err.message;
|
|
199
226
|
} else {
|
|
@@ -211,5 +238,6 @@ module.exports = {
|
|
|
211
238
|
getDBFilePath,
|
|
212
239
|
getUserDirectoryPath,
|
|
213
240
|
saveWebDB,
|
|
241
|
+
exportWebDB,
|
|
214
242
|
deleteUserData
|
|
215
243
|
};
|
package/src/ios/UnviredDB.h
CHANGED
package/src/ios/UnviredDB.m
CHANGED
|
@@ -437,6 +437,18 @@ static const NSString *DBTypeFrameworkDb = @"FrameworkDb";
|
|
|
437
437
|
}];
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
+
- (void)exportWebDB:(CDVInvokedUrlCommand*)command {
|
|
441
|
+
[self.commandDelegate runInBackground: ^{
|
|
442
|
+
@try {
|
|
443
|
+
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
|
|
444
|
+
} @catch (NSException *exception) {
|
|
445
|
+
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[exception description]];
|
|
446
|
+
[pluginResult setKeepCallbackAsBool:true];
|
|
447
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
448
|
+
}
|
|
449
|
+
}];
|
|
450
|
+
}
|
|
451
|
+
|
|
440
452
|
- (void)deleteUserData:(CDVInvokedUrlCommand*)command {
|
|
441
453
|
[self.commandDelegate runInBackground: ^{
|
|
442
454
|
@try {
|
package/www/unvired-db.js
CHANGED
|
@@ -24,6 +24,10 @@ exports.saveWebDB = function (arg0, successCallback, errorCallback) {
|
|
|
24
24
|
exec(successCallback, errorCallback, "UnviredDB", 'saveWebDB', [arg0]);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
exports.exportWebDB = function (arg0, successCallback, errorCallback) {
|
|
28
|
+
exec(successCallback, errorCallback, "UnviredDB", 'exportWebDB', [arg0]);
|
|
29
|
+
};
|
|
30
|
+
|
|
27
31
|
exports.deleteUserData = function (arg0, successCallback, errorCallback) {
|
|
28
32
|
exec(successCallback, errorCallback, "UnviredDB", 'deleteUserData', [arg0]);
|
|
29
33
|
}
|