@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unvired/cordova-plugin-unvired-electron-db",
3
3
  "displayName": "Unvired DB",
4
- "version": "0.0.37",
4
+ "version": "0.0.39",
5
5
  "description": "Unvired DB Native Support for Cordova",
6
6
  "scripts": {},
7
7
  "keywords": [
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.37"
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("");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-unvired-electron-db",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
4
4
  "description": "Unvired DB Native Support for Cordova",
5
5
  "main": "unvired-db-proxy.js",
6
6
  "author": "Unvired Inc",
@@ -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
- if (appDb) {
105
- appDb.close();
106
- }
107
- if (fwDb) {
108
- fwDb.close();
109
- }
110
- appDb = null;
111
- fwDb = null;
112
- return("DB connection closed")
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
- // Close DBs if they are open and point to this user's directory
158
- if (appDb) {
159
- try {
160
- appDb.close();
161
- } catch (e) {
162
- // Optionally log error
163
- }
164
- appDb = null;
165
- appDbFilePath = null;
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
- fwDb.close();
170
- } catch (e) {
171
- // Optionally log error
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
- fwDb.close((err) => {
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
  };
@@ -28,6 +28,8 @@
28
28
 
29
29
  - (void)saveWebDB:(CDVInvokedUrlCommand*)command;
30
30
 
31
+ - (void)exportWebDB:(CDVInvokedUrlCommand*)command;
32
+
31
33
  - (void)deleteUserData:(CDVInvokedUrlCommand*)command;
32
34
 
33
35
 
@@ -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
  }