@capacitor-community/sqlite 4.1.1 → 4.2.0
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 +5 -3
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +10 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +59 -6
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsDownloadFromHTTP.java +116 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java +89 -12
- package/ios/Plugin/CapacitorSQLite.swift +36 -6
- package/ios/Plugin/CapacitorSQLitePlugin.swift +49 -24
- package/ios/Plugin/Utils/UtilsDownloadFromHTTP.swift +122 -0
- package/ios/Plugin/Utils/UtilsFile.swift +40 -19
- package/ios/Plugin/Utils/UtilsMigrate.swift +1 -1
- package/ios/Plugin/Utils/UtilsUpgrade.swift +1 -1
- package/package.json +4 -4
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-
|
|
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
|
|
|
@@ -78,6 +78,7 @@ See [#301](https://github.com/capacitor-community/sqlite/issues/301) and [SO que
|
|
|
78
78
|
cd electron
|
|
79
79
|
npm install --save sqlite3
|
|
80
80
|
npm install --save jszip
|
|
81
|
+
npm install --save node-fetch
|
|
81
82
|
npm install --save-dev @types/sqlite3
|
|
82
83
|
```
|
|
83
84
|
|
|
@@ -137,7 +138,7 @@ npm install --save-dev @types/sqlite3
|
|
|
137
138
|
| closeNCConnection | ✅ | ✅ | ❌ | ❌ |
|
|
138
139
|
| isNCDatabase | ✅ | ✅ | ❌ | ❌ |
|
|
139
140
|
| transaction | ✅ | ✅ | ✅ | ✅ |
|
|
140
|
-
| getFromHTTPRequest |
|
|
141
|
+
| getFromHTTPRequest | ✅ | ✅ | ✅ | ✅ | since 4.2.0
|
|
141
142
|
|
|
142
143
|
|
|
143
144
|
## Documentation & APIs
|
|
@@ -210,7 +211,7 @@ npm install --save-dev @types/sqlite3
|
|
|
210
211
|
|
|
211
212
|
The iOS and Android codes are using `SQLCipher` allowing for database encryption.
|
|
212
213
|
The iOS codes is using `ZIPFoundation` for unzipping assets files
|
|
213
|
-
The Electron code is using `sqlite3
|
|
214
|
+
The Electron code is using `sqlite3` and `node-fetch` from 4.2.0.
|
|
214
215
|
The Web code is using the Stencil component `jeep-sqlite` based on `sql.js`, `localforage`. and `jszip`
|
|
215
216
|
|
|
216
217
|
## Contributors ✨
|
|
@@ -242,6 +243,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
242
243
|
<a href="https://github.com/antoniovlx" title="antoniovlx"><img src="https://github.com/antoniovlx.png?size=100" width="50" height="50" /></a>
|
|
243
244
|
<a href="https://github.com/HarelM" title="HarelM"><img src="https://github.com/HarelM.png?size=100" width="50" height="50" /></a>
|
|
244
245
|
<a href="https://github.com/rdlabo" title="rdlabo"><img src="https://github.com/rdlabo.png?size=100" width="50" height="50" /></a>
|
|
246
|
+
<a href="https://github.com/axkristiansen" title="rdlabo"><img src="https://github.com/axkristiansen.png?size=100" width="50" height="50" /></a>
|
|
245
247
|
</p>
|
|
246
248
|
|
|
247
249
|
<!-- markdownlint-enable -->
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java
CHANGED
|
@@ -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";
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java
CHANGED
|
@@ -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
|
-
|
|
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 = "
|
|
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.
|
|
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
|
+
}
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
151
|
+
String dbPath = databasePath + File.separator + toFileName;
|
|
152
|
+
boolean isExist = isPathExists(dbPath);
|
|
126
153
|
if (!isExist || overwrite) {
|
|
127
154
|
if (overwrite && isExist) {
|
|
128
|
-
|
|
155
|
+
deleteFile(databasePath, toFileName);
|
|
129
156
|
}
|
|
130
|
-
|
|
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
|
|
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
|
|
|
@@ -10,6 +10,7 @@ enum CapacitorSQLiteError: Error {
|
|
|
10
10
|
private var config: SqliteConfig
|
|
11
11
|
private var dbDict: [String: Database] = [:]
|
|
12
12
|
private var databaseLocation: String = "Documents"
|
|
13
|
+
private let retHandler: ReturnHandler = ReturnHandler()
|
|
13
14
|
private var initMessage: String = ""
|
|
14
15
|
private var isInit: Bool = false
|
|
15
16
|
private var isEncryption: Bool = true
|
|
@@ -457,6 +458,33 @@ enum CapacitorSQLiteError: Error {
|
|
|
457
458
|
}
|
|
458
459
|
}
|
|
459
460
|
|
|
461
|
+
// MARK: - GetFromHTTPRequest
|
|
462
|
+
|
|
463
|
+
@objc public func getFromHTTPRequest(_ call: CAPPluginCall, url: String) throws {
|
|
464
|
+
if isInit {
|
|
465
|
+
|
|
466
|
+
UtilsDownloadFromHTTP.download(databaseLocation: databaseLocation,
|
|
467
|
+
url: url) { ( result) in
|
|
468
|
+
switch result {
|
|
469
|
+
case .success(_):
|
|
470
|
+
self.retHandler.rResult(call: call)
|
|
471
|
+
return
|
|
472
|
+
case .failure(let error):
|
|
473
|
+
|
|
474
|
+
if error == .downloadFromHTTPFailed {
|
|
475
|
+
let msg = "Download from HTTP failed"
|
|
476
|
+
self.retHandler.rResult(call: call, message: msg)
|
|
477
|
+
return
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
}
|
|
483
|
+
} else {
|
|
484
|
+
throw CapacitorSQLiteError.failed(message: initMessage)
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
460
488
|
// MARK: - Close Connection
|
|
461
489
|
|
|
462
490
|
@objc public func closeConnection(_ dbName: String, readonly: Bool) throws {
|
|
@@ -1246,9 +1274,9 @@ enum CapacitorSQLiteError: Error {
|
|
|
1246
1274
|
|
|
1247
1275
|
// check if the assets/database folder exists
|
|
1248
1276
|
do {
|
|
1249
|
-
let
|
|
1277
|
+
let assetsDbURL: URL = try
|
|
1250
1278
|
UtilsFile.getAssetsDatabasesPath()
|
|
1251
|
-
let aPath: String =
|
|
1279
|
+
let aPath: String = assetsDbURL.path
|
|
1252
1280
|
let bRes: Bool = UtilsFile.isDirExist(dirPath: aPath)
|
|
1253
1281
|
if bRes {
|
|
1254
1282
|
// get the database files from assets
|
|
@@ -1274,9 +1302,11 @@ enum CapacitorSQLiteError: Error {
|
|
|
1274
1302
|
for zip in zipList {
|
|
1275
1303
|
// for each zip uncompress the file to the Application
|
|
1276
1304
|
// database folder
|
|
1277
|
-
_ = try UtilsFile
|
|
1278
|
-
|
|
1279
|
-
|
|
1305
|
+
_ = try UtilsFile.unzipToDatabase(
|
|
1306
|
+
fromURL: assetsDbURL,
|
|
1307
|
+
databaseLocation: databaseLocation,
|
|
1308
|
+
zip: zip,
|
|
1309
|
+
overwrite: overwrite)
|
|
1280
1310
|
}
|
|
1281
1311
|
return
|
|
1282
1312
|
} else {
|
|
@@ -1285,7 +1315,7 @@ enum CapacitorSQLiteError: Error {
|
|
|
1285
1315
|
}
|
|
1286
1316
|
} catch UtilsFileError.copyFromAssetToDatabaseFailed(let message) {
|
|
1287
1317
|
throw CapacitorSQLiteError.failed(message: message)
|
|
1288
|
-
} catch UtilsFileError.
|
|
1318
|
+
} catch UtilsFileError.unzipToDatabaseFailed(let message) {
|
|
1289
1319
|
throw CapacitorSQLiteError.failed(message: message)
|
|
1290
1320
|
} catch let error {
|
|
1291
1321
|
let msg: String = "\(error)"
|
|
@@ -1158,11 +1158,10 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
1158
1158
|
if let upgVersionDict: [Int: [String: Any]] = try
|
|
1159
1159
|
implementation?.addUpgradeStatement(dbName,
|
|
1160
1160
|
upgrade: upgrade) {
|
|
1161
|
-
if
|
|
1162
|
-
versionUpgrades[dbName] != nil
|
|
1163
|
-
){
|
|
1161
|
+
if
|
|
1162
|
+
versionUpgrades[dbName] != nil {
|
|
1164
1163
|
for (versionKey, upgObj) in upgVersionDict {
|
|
1165
|
-
versionUpgrades[dbName]
|
|
1164
|
+
versionUpgrades[dbName]?[versionKey] = upgObj
|
|
1166
1165
|
}
|
|
1167
1166
|
} else {
|
|
1168
1167
|
versionUpgrades = ["\(dbName)": upgVersionDict]
|
|
@@ -1323,13 +1322,42 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
1323
1322
|
}
|
|
1324
1323
|
|
|
1325
1324
|
}
|
|
1326
|
-
|
|
1325
|
+
|
|
1327
1326
|
// MARK: - GetFromHTTPRequest
|
|
1328
1327
|
|
|
1329
1328
|
@objc func getFromHTTPRequest(_ call: CAPPluginCall) {
|
|
1330
|
-
call.
|
|
1331
|
-
|
|
1329
|
+
guard let url = call.options["url"] as? String else {
|
|
1330
|
+
retHandler.rResult(
|
|
1331
|
+
call: call,
|
|
1332
|
+
message: "GetFromHTTPRequest: Must provide a database url")
|
|
1333
|
+
return
|
|
1334
|
+
}
|
|
1335
|
+
DispatchQueue.global(qos: .background).async {
|
|
1336
|
+
|
|
1337
|
+
do {
|
|
1338
|
+
try self.implementation?.getFromHTTPRequest(call, url: url)
|
|
1339
|
+
DispatchQueue.main.async {
|
|
1340
|
+
self.retHandler.rResult(call: call)
|
|
1341
|
+
return
|
|
1342
|
+
}
|
|
1343
|
+
} catch CapacitorSQLiteError.failed(let message) {
|
|
1332
1344
|
|
|
1345
|
+
DispatchQueue.main.async {
|
|
1346
|
+
let msg = "GetFromHTTPRequest: \(message)"
|
|
1347
|
+
self.retHandler.rResult(call: call, message: msg)
|
|
1348
|
+
return
|
|
1349
|
+
}
|
|
1350
|
+
} catch let error {
|
|
1351
|
+
DispatchQueue.main.async {
|
|
1352
|
+
let msg = "GetFromHTTPRequest: " +
|
|
1353
|
+
"\(error.localizedDescription)"
|
|
1354
|
+
self.retHandler.rResult(call: call, message: msg)
|
|
1355
|
+
return
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
}
|
|
1333
1361
|
|
|
1334
1362
|
// MARK: - Add Observers
|
|
1335
1363
|
|
|
@@ -1380,31 +1408,28 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
1380
1408
|
config.iosIsEncryption = 1
|
|
1381
1409
|
config.biometricAuth = 0
|
|
1382
1410
|
config.iosKeychainPrefix = ""
|
|
1383
|
-
|
|
1411
|
+
let configPlugin = getConfig()
|
|
1412
|
+
if let keychainPrefix = configPlugin.getString("iosKeychainPrefix") {
|
|
1384
1413
|
config.iosKeychainPrefix = keychainPrefix
|
|
1385
1414
|
}
|
|
1386
|
-
if let iosDatabaseLocation =
|
|
1387
|
-
as? String {
|
|
1415
|
+
if let iosDatabaseLocation = configPlugin.getString("iosDatabaseLocation") {
|
|
1388
1416
|
config.iosDatabaseLocation = iosDatabaseLocation
|
|
1389
1417
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
}
|
|
1418
|
+
let isEncryption = configPlugin.getBoolean("iosIsEncryption", false)
|
|
1419
|
+
if !isEncryption {
|
|
1420
|
+
config.iosIsEncryption = 0
|
|
1394
1421
|
}
|
|
1395
1422
|
if config.iosIsEncryption == 1 {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
}
|
|
1423
|
+
let iosBiometric = configPlugin.getObject("iosBiometric")
|
|
1424
|
+
if let bioAuth = iosBiometric?["biometricAuth"] as? Bool {
|
|
1425
|
+
if bioAuth {
|
|
1426
|
+
config.biometricAuth = 1
|
|
1427
|
+
if let bioTitle = iosBiometric?["biometricTitle"] as? String {
|
|
1428
|
+
config.biometricTitle = bioTitle.count > 0
|
|
1429
|
+
? bioTitle
|
|
1430
|
+
: "Biometric login for capacitor sqlite"
|
|
1405
1431
|
}
|
|
1406
1432
|
}
|
|
1407
|
-
|
|
1408
1433
|
}
|
|
1409
1434
|
}
|
|
1410
1435
|
return config
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UtilsDownloadFromHTTP.swift
|
|
3
|
+
// CapacitorCommunitySqlite
|
|
4
|
+
//
|
|
5
|
+
// Created by Quéau Jean Pierre on 05/10/2022.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import ZIPFoundation
|
|
10
|
+
|
|
11
|
+
enum UtilsDownloadError: Error {
|
|
12
|
+
case downloadFromHTTPFailed
|
|
13
|
+
}
|
|
14
|
+
class UtilsDownloadFromHTTP {
|
|
15
|
+
// swiftlint:disable cyclomatic_complexity
|
|
16
|
+
// swiftlint:disable function_body_length
|
|
17
|
+
class func download(databaseLocation: String, url: String,
|
|
18
|
+
completion: @escaping (Result<Bool, UtilsDownloadError>)
|
|
19
|
+
-> Void) {
|
|
20
|
+
if let mUrl: URL = URL(string: url) {
|
|
21
|
+
let fileName = mUrl.lastPathComponent
|
|
22
|
+
var dbName = fileName
|
|
23
|
+
var isZip = false
|
|
24
|
+
if !fileName.contains("SQLite.db") {
|
|
25
|
+
if String(fileName.suffix(3)) == ".db" {
|
|
26
|
+
dbName = fileName.replacingOccurrences(
|
|
27
|
+
of: ".db", with: "SQLite.db")
|
|
28
|
+
}
|
|
29
|
+
if String(fileName.suffix(4)) == ".zip" {
|
|
30
|
+
isZip = true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// compute a path to this Url in the cache
|
|
34
|
+
let cacheURL = UtilsFile.getTmpURL()
|
|
35
|
+
let tmp = cacheURL.lastPathComponent
|
|
36
|
+
let fileCacheURL = FileManager.default.temporaryDirectory
|
|
37
|
+
.appendingPathComponent(
|
|
38
|
+
dbName,
|
|
39
|
+
isDirectory: false
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
let task = URLSession.shared.downloadTask(with: mUrl) {
|
|
43
|
+
(tempURL, response, error) in
|
|
44
|
+
// Early exit on error
|
|
45
|
+
guard let tempURL = tempURL else {
|
|
46
|
+
let msg = "\(String(describing: error?.localizedDescription))"
|
|
47
|
+
print("\(msg)")
|
|
48
|
+
completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
if let httpResponse = response as? HTTPURLResponse {
|
|
52
|
+
switch httpResponse.statusCode {
|
|
53
|
+
case 200:
|
|
54
|
+
do {
|
|
55
|
+
// Remove any existing document at file
|
|
56
|
+
if FileManager.default.fileExists(
|
|
57
|
+
atPath: fileCacheURL.path) {
|
|
58
|
+
try FileManager.default.removeItem(
|
|
59
|
+
atPath: fileCacheURL.path)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Copy the tempURL to file
|
|
63
|
+
try FileManager.default.copyItem(
|
|
64
|
+
at: tempURL,
|
|
65
|
+
to: fileCacheURL
|
|
66
|
+
)
|
|
67
|
+
// Delete the tempUrl file
|
|
68
|
+
try FileManager.default.removeItem(at: tempURL)
|
|
69
|
+
let dbURL = try UtilsFile.getDatabaseLocationURL(
|
|
70
|
+
databaseLocation: databaseLocation)
|
|
71
|
+
if isZip {
|
|
72
|
+
// get the zip files
|
|
73
|
+
let zipList: [String] = try UtilsFile
|
|
74
|
+
.getFileList(path: cacheURL.path,
|
|
75
|
+
ext: ".zip")
|
|
76
|
+
// loop through the database files
|
|
77
|
+
for zip in zipList {
|
|
78
|
+
_ = try UtilsFile.unzipToDatabase(
|
|
79
|
+
fromURL: cacheURL,
|
|
80
|
+
databaseLocation: tmp,
|
|
81
|
+
zip: zip,
|
|
82
|
+
overwrite: true)
|
|
83
|
+
}
|
|
84
|
+
// Delete the zip file
|
|
85
|
+
try FileManager.default.removeItem(
|
|
86
|
+
at: fileCacheURL)
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
try UtilsFile.moveAllDBSQLite(
|
|
90
|
+
fromURL: cacheURL,
|
|
91
|
+
dirUrl: dbURL)
|
|
92
|
+
completion(.success(true))
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle potential file system errors
|
|
97
|
+
catch let error {
|
|
98
|
+
let msg = "\(error.localizedDescription)"
|
|
99
|
+
print("\(msg)")
|
|
100
|
+
completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
default:
|
|
104
|
+
let msg = "Download: GET resquest not successful. http status code \(httpResponse.statusCode)"
|
|
105
|
+
print("\(msg)")
|
|
106
|
+
completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
let msg = "Download: not a valid http response"
|
|
111
|
+
print("\(msg)")
|
|
112
|
+
completion(.failure(UtilsDownloadError.downloadFromHTTPFailed))
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Start the download
|
|
117
|
+
task.resume()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// swiftlint:enable cyclomatic_complexity
|
|
121
|
+
// swiftlint:enable function_body_length
|
|
122
|
+
}
|
|
@@ -25,12 +25,13 @@ enum UtilsFileError: Error {
|
|
|
25
25
|
case getLibraryURLFailed
|
|
26
26
|
case getFileListFailed
|
|
27
27
|
case copyFromAssetToDatabaseFailed(message: String)
|
|
28
|
-
case
|
|
28
|
+
case unzipToDatabaseFailed(message: String)
|
|
29
29
|
case copyFromNamesFailed
|
|
30
30
|
case getFolderURLFailed(message: String)
|
|
31
31
|
case createDirFailed(message: String)
|
|
32
32
|
case moveAllDBSQLiteFailed(message: String)
|
|
33
33
|
case createDatabaseLocationFailed(message: String)
|
|
34
|
+
case getDatabaseLocationURLFailed(message: String)
|
|
34
35
|
}
|
|
35
36
|
// swiftlint:disable file_length
|
|
36
37
|
// swiftlint:disable type_body_length
|
|
@@ -51,12 +52,17 @@ class UtilsFile {
|
|
|
51
52
|
// move all existing dbs from "Documents" to location folder
|
|
52
53
|
if location.prefix(9) != "Documents" &&
|
|
53
54
|
location.prefix(7) != "default" {
|
|
55
|
+
let databaseURL: URL = try UtilsFile
|
|
56
|
+
.getDatabasesUrl().absoluteURL
|
|
54
57
|
|
|
55
|
-
try UtilsFile.moveAllDBSQLite(
|
|
58
|
+
try UtilsFile.moveAllDBSQLite(fromURL: databaseURL,
|
|
59
|
+
dirUrl: dirUrl)
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
} catch UtilsFileError.getFolderURLFailed(let message) {
|
|
59
63
|
throw UtilsFileError.createDatabaseLocationFailed(message: message)
|
|
64
|
+
} catch UtilsFileError.getDatabasesURLFailed {
|
|
65
|
+
throw UtilsFileError.createDatabaseLocationFailed(message: "getDatabasesURLFailed")
|
|
60
66
|
} catch UtilsFileError.moveAllDBSQLiteFailed(let message) {
|
|
61
67
|
throw UtilsFileError.createDatabaseLocationFailed(message: message)
|
|
62
68
|
} catch let error {
|
|
@@ -77,16 +83,15 @@ class UtilsFile {
|
|
|
77
83
|
|
|
78
84
|
// MARK: - moveAllDBSQLite
|
|
79
85
|
|
|
80
|
-
class func moveAllDBSQLite(dirUrl: URL) throws {
|
|
86
|
+
class func moveAllDBSQLite(fromURL: URL, dirUrl: URL) throws {
|
|
81
87
|
// get the db list from Documents folder
|
|
82
88
|
do {
|
|
83
|
-
|
|
84
|
-
.getDatabasesUrl().absoluteURL
|
|
89
|
+
|
|
85
90
|
let fileList: [String] = try UtilsFile
|
|
86
|
-
.getFileList(path:
|
|
91
|
+
.getFileList(path: fromURL.path,
|
|
87
92
|
ext: "SQLite.db")
|
|
88
93
|
for file in fileList {
|
|
89
|
-
let fromFileURL: URL =
|
|
94
|
+
let fromFileURL: URL = fromURL
|
|
90
95
|
.appendingPathComponent(file).absoluteURL
|
|
91
96
|
let toFileURL = dirUrl
|
|
92
97
|
.appendingPathComponent(file).absoluteURL
|
|
@@ -149,6 +154,8 @@ class UtilsFile {
|
|
|
149
154
|
dbPathURL = try UtilsFile.getApplicationURL().absoluteURL
|
|
150
155
|
} else if first[0] == "Library" {
|
|
151
156
|
dbPathURL = try UtilsFile.getLibraryURL().absoluteURL
|
|
157
|
+
} else if first[0] == "tmp" {
|
|
158
|
+
dbPathURL = UtilsFile.getTmpURL().absoluteURL
|
|
152
159
|
} else if first[0].caseInsensitiveCompare("cache") == .orderedSame {
|
|
153
160
|
dbPathURL = try UtilsFile.getCacheURL().absoluteURL
|
|
154
161
|
} else if first[0] == "Documents" || first[0] == "default" {
|
|
@@ -216,6 +223,19 @@ class UtilsFile {
|
|
|
216
223
|
}
|
|
217
224
|
}
|
|
218
225
|
|
|
226
|
+
// MARK: - getDatabaseLocationURL
|
|
227
|
+
|
|
228
|
+
class func getDatabaseLocationURL(databaseLocation: String) throws -> URL {
|
|
229
|
+
do {
|
|
230
|
+
let url: URL = try UtilsFile
|
|
231
|
+
.getFolderURL(folderPath: databaseLocation)
|
|
232
|
+
|
|
233
|
+
return url
|
|
234
|
+
} catch UtilsFileError.getFolderURLFailed(let message) {
|
|
235
|
+
throw UtilsFileError.getDatabaseLocationURLFailed(message: message)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
219
239
|
// MARK: - getApplicationURL
|
|
220
240
|
|
|
221
241
|
class func getApplicationURL() throws -> URL {
|
|
@@ -255,6 +275,12 @@ class UtilsFile {
|
|
|
255
275
|
}
|
|
256
276
|
}
|
|
257
277
|
|
|
278
|
+
// MARK: - getTmpURL
|
|
279
|
+
|
|
280
|
+
class func getTmpURL() -> URL {
|
|
281
|
+
return FileManager.default.temporaryDirectory
|
|
282
|
+
}
|
|
283
|
+
|
|
258
284
|
// MARK: - getLibraryURL
|
|
259
285
|
|
|
260
286
|
class func getLibraryURL() throws -> URL {
|
|
@@ -395,15 +421,14 @@ class UtilsFile {
|
|
|
395
421
|
|
|
396
422
|
}
|
|
397
423
|
|
|
398
|
-
class func
|
|
399
|
-
|
|
424
|
+
class func unzipToDatabase(fromURL: URL, databaseLocation: String, zip: String,
|
|
425
|
+
overwrite: Bool) throws {
|
|
400
426
|
do {
|
|
401
|
-
let zipAsset: URL =
|
|
402
|
-
.appendingPathComponent(zip)
|
|
427
|
+
let zipAsset: URL = fromURL.appendingPathComponent(zip)
|
|
403
428
|
guard let archive = Archive(url: zipAsset, accessMode: .read) else {
|
|
404
429
|
let msg = "Error: Read Archive: \(zipAsset) failed"
|
|
405
430
|
print("\(msg)")
|
|
406
|
-
throw UtilsFileError.
|
|
431
|
+
throw UtilsFileError.unzipToDatabaseFailed(message: msg)
|
|
407
432
|
}
|
|
408
433
|
let uDb: URL = try getFolderURL(folderPath: databaseLocation)
|
|
409
434
|
for entry in archive {
|
|
@@ -421,20 +446,16 @@ class UtilsFile {
|
|
|
421
446
|
} catch {
|
|
422
447
|
let msg = "Error: Extracting \(entry.path) from archive failed \(error.localizedDescription)"
|
|
423
448
|
print("\(msg)")
|
|
424
|
-
throw UtilsFileError.
|
|
449
|
+
throw UtilsFileError.unzipToDatabaseFailed(message: msg)
|
|
425
450
|
}
|
|
426
451
|
}
|
|
427
|
-
} catch UtilsFileError.getAssetsDatabasesPathFailed {
|
|
428
|
-
let msg = "Error: getAssetsDatabasesPath Failed"
|
|
429
|
-
print("\(msg)")
|
|
430
|
-
throw UtilsFileError.unzipFromAssetToDatabaseFailed(message: msg)
|
|
431
452
|
} catch UtilsFileError.getFolderURLFailed(let message) {
|
|
432
453
|
print("Error: getFolderUrl Failed \(message)")
|
|
433
|
-
throw UtilsFileError.
|
|
454
|
+
throw UtilsFileError.unzipToDatabaseFailed(message: message)
|
|
434
455
|
} catch let error {
|
|
435
456
|
let msg = "Error: \(error)"
|
|
436
457
|
print("\(msg)")
|
|
437
|
-
throw UtilsFileError.
|
|
458
|
+
throw UtilsFileError.unzipToDatabaseFailed(message: msg)
|
|
438
459
|
}
|
|
439
460
|
}
|
|
440
461
|
|
|
@@ -238,7 +238,7 @@ class UtilsMigrate {
|
|
|
238
238
|
if !toFile.isEmpty {
|
|
239
239
|
let uFrom: URL = dbPathURL.appendingPathComponent(fromFile)
|
|
240
240
|
let uTo: URL = databaseURL.appendingPathComponent(toFile)
|
|
241
|
-
try UtilsFile.moveFile(pathName: uFrom.path, toPathName: uTo.path, overwrite: true)
|
|
241
|
+
_ = try UtilsFile.moveFile(pathName: uFrom.path, toPathName: uTo.path, overwrite: true)
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -27,7 +27,7 @@ class UtilsUpgrade {
|
|
|
27
27
|
for (versionKey, upgrade) in Array(upgDict).sorted(by: {$0.0 < $1.0}) {
|
|
28
28
|
if versionKey > currentVersion && versionKey <= targetVersion {
|
|
29
29
|
print("- UtilsUpgrade.onUpgrade toVersion: \(versionKey)")
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
guard let statements = upgrade["statements"] as? [String] else {
|
|
32
32
|
let msg: String = "Error: onUpgrade statements not given"
|
|
33
33
|
throw UtilsUpgradeError.onUpgradeFailed(message: msg)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor-community/sqlite",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Community plugin for native & electron SQLite databases",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"prepublishOnly": "npm run build && npm run build-electron && npm run docgen"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@capacitor/android": "^4.
|
|
59
|
-
"@capacitor/core": "^4.
|
|
58
|
+
"@capacitor/android": "^4.2.0",
|
|
59
|
+
"@capacitor/core": "^4.2.0",
|
|
60
60
|
"@capacitor/docgen": "^0.0.17",
|
|
61
|
-
"@capacitor/ios": "^4.
|
|
61
|
+
"@capacitor/ios": "^4.2.0",
|
|
62
62
|
"@ionic/eslint-config": "^0.3.0",
|
|
63
63
|
"@ionic/prettier-config": "^1.0.1",
|
|
64
64
|
"@ionic/swiftlint-config": "^1.1.2",
|