@capacitor-community/sqlite 4.1.1 → 4.2.1

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/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  <a href="https://www.npmjs.com/package/@capacitor-community/sqlite"><img src="https://img.shields.io/npm/dw/@capacitor-community/sqlite?style=flat-square" /></a>
17
17
  <a href="https://www.npmjs.com/package/@capacitor-community/sqlite"><img src="https://img.shields.io/npm/v/@capacitor-community/sqlite?style=flat-square" /></a>
18
18
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
19
- <a href="#contributors-"><img src="https://img.shields.io/badge/all%20contributors-17-orange?style=flat-square" /></a>
19
+ <a href="#contributors-"><img src="https://img.shields.io/badge/all%20contributors-22-orange?style=flat-square" /></a>
20
20
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
21
21
  </p>
22
22
 
@@ -27,8 +27,21 @@
27
27
  | Quéau Jean Pierre | [jepiqueau](https://github.com/jepiqueau) | |
28
28
 
29
29
  To install:
30
+
31
+ ```
32
+ npm install --save @capacitor-community/sqlite
33
+ npx cap sync
34
+ ```
35
+
36
+ ```
37
+ yarn install --save @capacitor-community/sqlite
38
+ npx cap sync
39
+ ```
40
+
30
41
  ```
31
- npm install @capacitor-community/sqlite
42
+ pnpm install --save @capacitor-community/sqlite
43
+ pnpm install --save @jeep-sqlite
44
+ pnpm install --save sql.js
32
45
  npx cap sync
33
46
  ```
34
47
 
@@ -78,6 +91,7 @@ See [#301](https://github.com/capacitor-community/sqlite/issues/301) and [SO que
78
91
  cd electron
79
92
  npm install --save sqlite3
80
93
  npm install --save jszip
94
+ npm install --save node-fetch
81
95
  npm install --save-dev @types/sqlite3
82
96
  ```
83
97
 
@@ -137,7 +151,7 @@ npm install --save-dev @types/sqlite3
137
151
  | closeNCConnection | ✅ | ✅ | ❌ | ❌ |
138
152
  | isNCDatabase | ✅ | ✅ | ❌ | ❌ |
139
153
  | transaction | ✅ | ✅ | ✅ | ✅ |
140
- | getFromHTTPRequest | | | ✅ | ✅ | since 4.1.1
154
+ | getFromHTTPRequest | | | ✅ | ✅ | since 4.2.0
141
155
 
142
156
 
143
157
  ## Documentation & APIs
@@ -210,7 +224,7 @@ npm install --save-dev @types/sqlite3
210
224
 
211
225
  The iOS and Android codes are using `SQLCipher` allowing for database encryption.
212
226
  The iOS codes is using `ZIPFoundation` for unzipping assets files
213
- The Electron code is using `sqlite3`.
227
+ The Electron code is using `sqlite3` and `node-fetch` from 4.2.0.
214
228
  The Web code is using the Stencil component `jeep-sqlite` based on `sql.js`, `localforage`. and `jszip`
215
229
 
216
230
  ## Contributors ✨
@@ -242,6 +256,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
242
256
  <a href="https://github.com/antoniovlx" title="antoniovlx"><img src="https://github.com/antoniovlx.png?size=100" width="50" height="50" /></a>
243
257
  <a href="https://github.com/HarelM" title="HarelM"><img src="https://github.com/HarelM.png?size=100" width="50" height="50" /></a>
244
258
  <a href="https://github.com/rdlabo" title="rdlabo"><img src="https://github.com/rdlabo.png?size=100" width="50" height="50" /></a>
259
+ <a href="https://github.com/axkristiansen" title="rdlabo"><img src="https://github.com/axkristiansen.png?size=100" width="50" height="50" /></a>
245
260
  </p>
246
261
 
247
262
  <!-- markdownlint-enable -->
@@ -17,6 +17,7 @@ import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.JsonSQ
17
17
  import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.UtilsJson;
18
18
  import com.getcapacitor.community.database.sqlite.SQLite.SqliteConfig;
19
19
  import com.getcapacitor.community.database.sqlite.SQLite.UtilsBiometric;
20
+ import com.getcapacitor.community.database.sqlite.SQLite.UtilsDownloadFromHTTP;
20
21
  import com.getcapacitor.community.database.sqlite.SQLite.UtilsFile;
21
22
  import com.getcapacitor.community.database.sqlite.SQLite.UtilsMigrate;
22
23
  import com.getcapacitor.community.database.sqlite.SQLite.UtilsNCDatabase;
@@ -46,6 +47,7 @@ public class CapacitorSQLite {
46
47
  private final UtilsJson uJson = new UtilsJson();
47
48
  private final UtilsMigrate uMigrate = new UtilsMigrate();
48
49
  private final UtilsNCDatabase uNCDatabase = new UtilsNCDatabase();
50
+ private final UtilsDownloadFromHTTP uHTTP = new UtilsDownloadFromHTTP();
49
51
  private UtilsSecret uSecret;
50
52
  private SharedPreferences sharedPreferences = null;
51
53
  private MasterKey masterKeyAlias;
@@ -537,6 +539,14 @@ public class CapacitorSQLite {
537
539
  }
538
540
  }
539
541
 
542
+ public void getFromHTTPRequest(String url) throws Exception {
543
+ try {
544
+ uHTTP.download(context, url);
545
+ } catch (Exception e) {
546
+ throw new Exception(e.getMessage());
547
+ }
548
+ }
549
+
540
550
  public Boolean checkConnectionsConsistency(JSArray dbNames, JSArray openModes) throws Exception {
541
551
  Set<String> keys = new HashSet<String>(Collections.list(dbDict.keys()));
542
552
  String msg = "All Native Connections released";
@@ -12,12 +12,10 @@ import com.getcapacitor.annotation.CapacitorPlugin;
12
12
  import com.getcapacitor.community.database.sqlite.SQLite.Database;
13
13
  import com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson.JsonSQLite;
14
14
  import com.getcapacitor.community.database.sqlite.SQLite.SqliteConfig;
15
-
16
15
  import java.util.Collections;
17
16
  import java.util.Dictionary;
18
17
  import java.util.Hashtable;
19
18
  import java.util.List;
20
-
21
19
  import org.json.JSONArray;
22
20
  import org.json.JSONException;
23
21
  import org.json.JSONObject;
@@ -1225,9 +1223,9 @@ public class CapacitorSQLitePlugin extends Plugin {
1225
1223
  try {
1226
1224
  Dictionary<Integer, JSONObject> upgDict = implementation.addUpgradeStatement(upgrade);
1227
1225
 
1228
- if (versionUpgrades.get(dbName) != null){
1226
+ if (versionUpgrades.get(dbName) != null) {
1229
1227
  List<Integer> keys = Collections.list(upgDict.keys());
1230
- for (Integer versionKey : keys) {
1228
+ for (Integer versionKey : keys) {
1231
1229
  JSONObject upgObj = upgDict.get(versionKey);
1232
1230
 
1233
1231
  versionUpgrades.get(dbName).put(versionKey, upgObj);
@@ -1362,7 +1360,7 @@ public class CapacitorSQLitePlugin extends Plugin {
1362
1360
  JSObject retObj = new JSObject();
1363
1361
  JsonSQLite retJson = new JsonSQLite();
1364
1362
  if (!call.getData().has("database")) {
1365
- String msg = "ExportToJson: Must provide a database name";
1363
+ String msg = "DeleteExportedRows: Must provide a database name";
1366
1364
  rHandler.retResult(call, null, msg);
1367
1365
  return;
1368
1366
  }
@@ -1418,7 +1416,62 @@ public class CapacitorSQLitePlugin extends Plugin {
1418
1416
  */
1419
1417
  @PluginMethod
1420
1418
  public void getFromHTTPRequest(PluginCall call) {
1421
- call.unimplemented("Not implemented on Android.");
1419
+ if (!call.getData().has("url")) {
1420
+ String msg = "GetFromHTTPRequest: Must provide a database url";
1421
+ rHandler.retResult(call, null, msg);
1422
+ return;
1423
+ }
1424
+ String url = call.getString("url");
1425
+ if (implementation != null) {
1426
+ Runnable setHTTPRunnable = new Runnable() {
1427
+ @Override
1428
+ public void run() {
1429
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
1430
+ try {
1431
+ implementation.getFromHTTPRequest(url);
1432
+ getActivity()
1433
+ .runOnUiThread(
1434
+ new Runnable() {
1435
+ @Override
1436
+ public void run() {
1437
+ rHandler.retResult(call, null, null);
1438
+ return;
1439
+ }
1440
+ }
1441
+ );
1442
+ } catch (Exception e) {
1443
+ getActivity()
1444
+ .runOnUiThread(
1445
+ new Runnable() {
1446
+ @Override
1447
+ public void run() {
1448
+ String msg = "GetFromHTTPRequest: " + e.getMessage();
1449
+ rHandler.retResult(call, null, msg);
1450
+ return;
1451
+ }
1452
+ }
1453
+ );
1454
+ }
1455
+ }
1456
+ };
1457
+ Thread myHttpThread = new Thread(setHTTPRunnable);
1458
+ myHttpThread.start();
1459
+ while (myHttpThread.isAlive());
1460
+ System.out.println("Thread Exiting!");
1461
+ /* try {
1462
+ implementation.getFromHTTPRequest(url);
1463
+ rHandler.retResult(call, null, null);
1464
+ return;
1465
+ } catch (Exception e) {
1466
+ String msg = "GetFromHTTPRequest: " + e.getMessage();
1467
+ rHandler.retResult(call, null, msg);
1468
+ return;
1469
+ }
1470
+ */
1471
+ } else {
1472
+ rHandler.retResult(call, null, loadMessage);
1473
+ return;
1474
+ }
1422
1475
  }
1423
1476
 
1424
1477
  private void AddObserversToNotificationCenter() {
@@ -0,0 +1,116 @@
1
+ package com.getcapacitor.community.database.sqlite.SQLite;
2
+
3
+ import android.content.Context;
4
+ import android.content.res.AssetManager;
5
+ import java.io.File;
6
+ import java.io.FileOutputStream;
7
+ import java.io.IOException;
8
+ import java.io.InputStream;
9
+ import java.net.HttpURLConnection;
10
+ import java.net.URL;
11
+
12
+ public class UtilsDownloadFromHTTP {
13
+
14
+ private static final String TAG = UtilsDownloadFromHTTP.class.getName();
15
+ private static final int BUFFER_SIZE = 4096;
16
+ private final UtilsFile _uFile = new UtilsFile();
17
+
18
+ public void download(Context context, String fileUrl) throws Exception {
19
+ AssetManager assetManager = context.getAssets();
20
+ String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
21
+ String dbName = fileName;
22
+ Boolean isZip = false;
23
+ if (!fileName.contains("SQLite.db")) {
24
+ if (_uFile.getFileExtension((fileName)).equals("db")) {
25
+ dbName = fileName.substring(0, fileName.length() - 3) + "SQLite.db";
26
+ }
27
+ if (_uFile.isLast(fileName, ".zip")) {
28
+ isZip = true;
29
+ }
30
+ }
31
+ File cacheDir = context.getCacheDir();
32
+ String cachePath = cacheDir.getAbsolutePath();
33
+ String tmpFilePath = cachePath + File.separator + dbName;
34
+ String databasePath = _uFile.getDatabaseDirectoryPath(context);
35
+ File databaseDir = new File(databasePath);
36
+ try {
37
+ // delete file if exists in cache
38
+ Boolean isExists = _uFile.isPathExists(tmpFilePath);
39
+ if (isExists) {
40
+ _uFile.deleteFile(cachePath, dbName);
41
+ }
42
+ downloadFileToCache(fileUrl, cachePath);
43
+ if (isZip) {
44
+ _uFile.unzipCopyDatabase(cachePath, null, tmpFilePath, true);
45
+ // delete zip file from cache
46
+ _uFile.deleteFile(cachePath, dbName);
47
+ }
48
+ // move files to database folder
49
+ _uFile.moveAllDBs(cacheDir, databaseDir);
50
+ } catch (Exception e) {
51
+ throw new Exception(e.getMessage());
52
+ }
53
+ }
54
+
55
+ public static void downloadFileToCache(String fileURL, String cacheDir) throws Exception {
56
+ HttpURLConnection httpConn = null;
57
+ try {
58
+ URL url = new URL(fileURL);
59
+ httpConn = (HttpURLConnection) url.openConnection();
60
+ int responseCode = httpConn.getResponseCode();
61
+ if (responseCode == HttpURLConnection.HTTP_OK) {
62
+ String fileName = "";
63
+ String disposition = httpConn.getHeaderField("Content-Disposition");
64
+ // String contentType = httpConn.getContentType();
65
+ int contentLength = httpConn.getContentLength();
66
+
67
+ if (disposition != null) {
68
+ // extracts file name from header field
69
+ int index = disposition.indexOf("filename=");
70
+ if (index > 0) {
71
+ fileName = disposition.substring(index + 10, disposition.length() - 1);
72
+ }
73
+ } else {
74
+ // extracts file name from URL
75
+ fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1);
76
+ }
77
+ String dbName = fileName;
78
+ if (!fileName.contains("SQLite.db")) {
79
+ if (fileName.substring(fileName.length() - 3).equals(".db")) {
80
+ dbName = fileName.substring(0, fileName.length() - 3) + "SQLite.db";
81
+ }
82
+ }
83
+
84
+ // System.out.println("Content-Type = " + contentType);
85
+ // System.out.println("Content-Disposition = " + disposition);
86
+ // System.out.println("Content-Length = " + contentLength);
87
+ // System.out.println("fileName = " + fileName);
88
+ // opens input stream from the HTTP connection
89
+ InputStream inputStream = httpConn.getInputStream();
90
+ // create temporary file path
91
+ String tmpFilePath = cacheDir + File.separator + dbName;
92
+ // opens an output stream to save into file
93
+ FileOutputStream outputStream = new FileOutputStream(tmpFilePath);
94
+ int bytesRead = -1;
95
+ byte[] buffer = new byte[BUFFER_SIZE];
96
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
97
+ outputStream.write(buffer, 0, bytesRead);
98
+ }
99
+
100
+ outputStream.close();
101
+ inputStream.close();
102
+
103
+ System.out.println("File " + fileName + " downloaded (" + contentLength + ")");
104
+ } else {
105
+ String msg = "No file to download. Server replied HTTP code: " + responseCode;
106
+ throw new IOException(msg);
107
+ }
108
+ } catch (IOException e) {
109
+ throw new Exception(e);
110
+ } finally {
111
+ if (httpConn != null) {
112
+ httpConn.disconnect();
113
+ }
114
+ }
115
+ }
116
+ }
@@ -2,7 +2,9 @@ package com.getcapacitor.community.database.sqlite.SQLite;
2
2
 
3
3
  import android.content.Context;
4
4
  import android.content.res.AssetManager;
5
+ import android.os.Build;
5
6
  import android.util.Log;
7
+ import androidx.annotation.RequiresApi;
6
8
  import java.io.File;
7
9
  import java.io.FileInputStream;
8
10
  import java.io.FileOutputStream;
@@ -10,8 +12,16 @@ import java.io.IOException;
10
12
  import java.io.InputStream;
11
13
  import java.io.OutputStream;
12
14
  import java.nio.channels.FileChannel;
15
+ import java.nio.file.DirectoryStream;
16
+ import java.nio.file.Files;
17
+ import java.nio.file.Path;
18
+ import java.nio.file.Paths;
13
19
  import java.util.ArrayList;
20
+ import java.util.HashSet;
14
21
  import java.util.List;
22
+ import java.util.Set;
23
+ import java.util.stream.Collectors;
24
+ import java.util.stream.Stream;
15
25
  import java.util.zip.ZipEntry;
16
26
  import java.util.zip.ZipInputStream;
17
27
 
@@ -33,6 +43,10 @@ public class UtilsFile {
33
43
  }
34
44
  }
35
45
 
46
+ public String getDatabaseDirectoryPath(Context context) {
47
+ return context != null && context.getDatabasePath("x") != null ? context.getDatabasePath("x").getParent() : "";
48
+ }
49
+
36
50
  public String[] getListOfFiles(Context context) {
37
51
  String[] files = context.databaseList();
38
52
  List<String> dbs = new ArrayList<>();
@@ -64,6 +78,10 @@ public class UtilsFile {
64
78
  return file.delete();
65
79
  }
66
80
 
81
+ public Boolean deleteFile(File file) {
82
+ return file.delete();
83
+ }
84
+
67
85
  public void copyFromAssetsToDatabase(Context context, Boolean overwrite) throws Exception {
68
86
  AssetManager assetManager = context.getAssets();
69
87
  String assetsDatabasePath = "public/assets/databases";
@@ -99,7 +117,8 @@ public class UtilsFile {
99
117
  if (isLast(fileName, ".zip")) {
100
118
  // unzip file and extract databases
101
119
  String zipPathName = assetsDatabasePath + "/" + fileName;
102
- unzipCopyDatabase(context, assetManager, zipPathName, assetsDatabasePath, overwrite);
120
+ String databasePath = getDatabaseDirectoryPath(context);
121
+ unzipCopyDatabase(databasePath, assetManager, zipPathName, overwrite);
103
122
  }
104
123
  }
105
124
  return;
@@ -109,26 +128,33 @@ public class UtilsFile {
109
128
  }
110
129
  }
111
130
 
112
- public void unzipCopyDatabase(Context context, AssetManager asm, String zipPath, String assetsDatabasePath, Boolean overwrite)
113
- throws IOException {
114
- InputStream is;
131
+ public void unzipCopyDatabase(String databasePath, AssetManager asm, String zipPath, Boolean overwrite) throws IOException {
132
+ InputStream is = null;
133
+ FileInputStream isF = null;
134
+ ZipInputStream zis;
115
135
  byte[] buffer = new byte[1024];
116
- try {
117
- is = asm.open(zipPath);
118
- ZipInputStream zis = new ZipInputStream(is);
119
136
 
137
+ try {
138
+ if (asm != null) {
139
+ is = asm.open(zipPath);
140
+ zis = new ZipInputStream(is);
141
+ } else {
142
+ File zipFile = new File(zipPath);
143
+ isF = new FileInputStream(zipFile);
144
+ zis = new ZipInputStream(isF);
145
+ }
120
146
  ZipEntry ze = zis.getNextEntry();
121
147
  while (ze != null) {
122
148
  String fileName = ze.getName();
123
149
  if (isLast(fileName, ".db")) {
124
150
  String toFileName = addSQLiteSuffix(fileName);
125
- boolean isExist = isFileExists(context, toFileName);
151
+ String dbPath = databasePath + File.separator + toFileName;
152
+ boolean isExist = isPathExists(dbPath);
126
153
  if (!isExist || overwrite) {
127
154
  if (overwrite && isExist) {
128
- deleteDatabase(context, toFileName);
155
+ deleteFile(databasePath, toFileName);
129
156
  }
130
- String toPathName = context.getDatabasePath(toFileName).getAbsolutePath();
131
- File newFile = new File(toPathName);
157
+ File newFile = new File(dbPath);
132
158
  System.out.println("Unzipping to " + newFile.getAbsolutePath());
133
159
  FileOutputStream fos = new FileOutputStream(newFile);
134
160
  int len;
@@ -145,7 +171,11 @@ public class UtilsFile {
145
171
  //close last ZipEntry
146
172
  zis.closeEntry();
147
173
  zis.close();
148
- is.close();
174
+ if (asm != null && is != null) {
175
+ is.close();
176
+ } else if (isF != null) {
177
+ isF.close();
178
+ }
149
179
  } catch (IOException e) {
150
180
  throw new IOException("in unzipCopyDatabase " + e.getLocalizedMessage());
151
181
  }
@@ -294,6 +324,53 @@ public class UtilsFile {
294
324
  }
295
325
  }
296
326
 
327
+ public void moveAllDBs(File fromDir, File toDir) throws Exception {
328
+ // get the file List from fromDir
329
+ List<String> fileList;
330
+ String fromDirPath = fromDir.getAbsolutePath();
331
+ String toDirPath = toDir.getAbsolutePath();
332
+
333
+ try {
334
+ fileList = listDatabases(fromDir);
335
+ for (String fileName : fileList) {
336
+ // Check if the file exists in toDir
337
+ File toFile = new File(toDirPath, fileName);
338
+ Boolean isPath = isPathExists(toFile.getAbsolutePath());
339
+ if (isPath) {
340
+ deleteFile(toFile);
341
+ }
342
+ File fromFile = new File(fromDirPath, fileName);
343
+
344
+ Boolean success = fromFile.renameTo(toFile);
345
+ if (!success) {
346
+ throw new Exception("moveAllDBs: move file " + fileName + " failed");
347
+ }
348
+ }
349
+ } catch (Exception e) {
350
+ throw new Exception(e.getMessage());
351
+ }
352
+ }
353
+
354
+ public List<String> listDatabases(File fileDir) throws Exception {
355
+ List<String> fileList = new ArrayList<>();
356
+ if (!fileDir.exists()) {
357
+ throw new Exception("File " + fileDir.getAbsolutePath() + " does not exist");
358
+ }
359
+ if (!fileDir.isDirectory()) {
360
+ throw new Exception("File " + fileDir.getAbsolutePath() + " is not a directory");
361
+ }
362
+ File[] fList = fileDir.listFiles();
363
+ for (File file : fList) {
364
+ if (file.isFile()) {
365
+ String fileName = file.getName();
366
+ if (getFileExtension((fileName)).equals("db")) {
367
+ fileList.add(fileName);
368
+ }
369
+ }
370
+ }
371
+ return fileList;
372
+ }
373
+
297
374
  private static void copyFileFromFile(File sourceFile, File destFile) throws IOException {
298
375
  if (!destFile.getParentFile().exists()) destFile.getParentFile().mkdirs();
299
376
 
@@ -3,12 +3,13 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var require$$0 = require('sqlite3');
6
- var require$$0$1 = require('path');
7
- var require$$1 = require('fs');
8
- var require$$2 = require('node-fetch');
9
- var require$$3 = require('os');
10
- var require$$4 = require('jszip');
11
- var require$$5 = require('electron');
6
+ var require$$0$1 = require('node:fs/promises');
7
+ var require$$1 = require('path');
8
+ var require$$2 = require('fs');
9
+ var require$$3 = require('node-fetch');
10
+ var require$$4 = require('os');
11
+ var require$$5 = require('jszip');
12
+ var require$$6 = require('electron');
12
13
 
13
14
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
14
15
 
@@ -19,6 +20,7 @@ var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
19
20
  var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
20
21
  var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
21
22
  var require$$5__default = /*#__PURE__*/_interopDefaultLegacy(require$$5);
23
+ var require$$6__default = /*#__PURE__*/_interopDefaultLegacy(require$$6);
22
24
 
23
25
  var src = {};
24
26
 
@@ -2673,6 +2675,7 @@ var utilsFile = {};
2673
2675
 
2674
2676
  Object.defineProperty(utilsFile, "__esModule", { value: true });
2675
2677
  utilsFile.UtilsFile = void 0;
2678
+ const promises_1 = require$$0__default$1["default"];
2676
2679
  class UtilsFile {
2677
2680
  constructor() {
2678
2681
  this.pathDB = 'Databases';
@@ -2685,12 +2688,12 @@ class UtilsFile {
2685
2688
  this.AppName = '';
2686
2689
  this.HomeDir = '';
2687
2690
  this.sep = '/';
2688
- this.Path = require$$0__default$1["default"];
2689
- this.NodeFs = require$$1__default["default"];
2690
- this.NodeFetch = require$$2__default["default"];
2691
- this.Os = require$$3__default["default"];
2692
- this.JSZip = require$$4__default["default"];
2693
- this.Electron = require$$5__default["default"];
2691
+ this.Path = require$$1__default["default"];
2692
+ this.NodeFs = require$$2__default["default"];
2693
+ this.NodeFetch = require$$3__default["default"];
2694
+ this.Os = require$$4__default["default"];
2695
+ this.JSZip = require$$5__default["default"];
2696
+ this.Electron = require$$6__default["default"];
2694
2697
  this.HomeDir = this.Os.homedir();
2695
2698
  const dir = __dirname;
2696
2699
  const idx = dir.indexOf('\\');
@@ -2996,6 +2999,7 @@ class UtilsFile {
2996
2999
  const isPath = this.isPathExists(filePath);
2997
3000
  if (isPath) {
2998
3001
  try {
3002
+ await this.waitForFilePathLock(filePath);
2999
3003
  this.NodeFs.unlinkSync(filePath);
3000
3004
  return Promise.resolve();
3001
3005
  }
@@ -3011,6 +3015,52 @@ class UtilsFile {
3011
3015
  return Promise.reject('DeleteFilePath: delete filePath' + 'failed');
3012
3016
  }
3013
3017
  }
3018
+ async waitForFilePathLock(filePath, timeoutMS = 4000) {
3019
+ let timeIsOver = false;
3020
+ setTimeout(() => {
3021
+ timeIsOver = true;
3022
+ }, timeoutMS);
3023
+ return new Promise((resolve, reject) => {
3024
+ const check = async () => {
3025
+ if (timeIsOver) {
3026
+ reject(new Error(`WaitForFilePathLock: The resource is still locked / busy after ${timeoutMS} milliseconds.`));
3027
+ return;
3028
+ }
3029
+ // check if path exists
3030
+ const isPath = this.isPathExists(filePath);
3031
+ // The file path does not exist. A non existant path cannot be locked.
3032
+ if (!isPath) {
3033
+ resolve();
3034
+ return;
3035
+ }
3036
+ try {
3037
+ const stream = await promises_1.open(filePath, 'r+');
3038
+ // We need to close the stream afterwards, because otherwise, we're locking the file
3039
+ await stream.close();
3040
+ resolve();
3041
+ }
3042
+ catch (err) {
3043
+ if (err.code === 'EBUSY') {
3044
+ // The resource is busy. Retry in 100ms
3045
+ setTimeout(() => {
3046
+ check();
3047
+ }, 100);
3048
+ return;
3049
+ }
3050
+ else if (err.code === 'ENOENT') {
3051
+ // The file does not exist (anymore). So it cannot be locked.
3052
+ resolve();
3053
+ return;
3054
+ }
3055
+ else {
3056
+ // Something else went wrong.
3057
+ reject(new Error(`WaitForFilePathLock: Error while checking the file: ${err}`));
3058
+ }
3059
+ }
3060
+ };
3061
+ check();
3062
+ });
3063
+ }
3014
3064
  /**
3015
3065
  * RenameFileName
3016
3066
  * @param fileName
@@ -3350,11 +3400,15 @@ class Database {
3350
3400
  */
3351
3401
  async close() {
3352
3402
  this.ensureDatabaseIsOpen();
3353
- this.database.close((err) => {
3354
- if (err) {
3355
- throw new Error('Close failed: ${this.dbName} ${err}');
3356
- }
3357
- this._isDbOpen = false;
3403
+ return new Promise((resolve, reject) => {
3404
+ this.database.close((err) => {
3405
+ if (err) {
3406
+ reject(new Error(`Close failed: ${this.dbName} ${err}`));
3407
+ return;
3408
+ }
3409
+ this._isDbOpen = false;
3410
+ resolve();
3411
+ });
3358
3412
  });
3359
3413
  }
3360
3414
  /**