@capacitor-community/sqlite 3.4.1-1 → 3.4.1-4
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 +24 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +14 -6
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +24 -11
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +5 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +24 -15
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java +23 -0
- package/electron/dist/plugin.js +265 -198
- package/electron/dist/plugin.js.map +1 -1
- package/electron/rollup.config.js +18 -2
- package/ios/Plugin/BiometricIDAuthentication.swift +3 -0
- package/ios/Plugin/CapacitorSQLite.swift +4 -0
- package/ios/Plugin/CapacitorSQLitePlugin.swift +2 -0
- package/ios/Plugin/Database.swift +32 -9
- package/ios/Plugin/ImportExportJson/ExportToJson.swift +8 -0
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +20 -14
- package/ios/Plugin/Utils/UtilsJson.swift +28 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -28,10 +28,33 @@
|
|
|
28
28
|
|
|
29
29
|
## CAPACITOR 3 (Master)
|
|
30
30
|
|
|
31
|
+
🚨 Since release 3.4.1-4 ->> 🚨
|
|
32
|
+
MacOS only, databases location for Electron can be set in `the config.config.ts` as followed:
|
|
33
|
+
plugins: {
|
|
34
|
+
CapacitorSQLite: {
|
|
35
|
+
electronMacLocation: "/YOUR_DATABASES_PATH"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
For existing databases, YOU MUST COPY old databases to the new location
|
|
39
|
+
You MUST remove the Electron folder and add it again with
|
|
40
|
+
```
|
|
41
|
+
npx cap add @capacitor-community/electron
|
|
42
|
+
npm run build
|
|
43
|
+
cd electron
|
|
44
|
+
npm i --save sqlite3
|
|
45
|
+
npm i --save @types:sqlite3
|
|
46
|
+
npm run rebuild
|
|
47
|
+
cd ..
|
|
48
|
+
npx cap sync @capacitor-community/electron
|
|
49
|
+
npm run build
|
|
50
|
+
npx cap copy @capacitor-community/electron
|
|
51
|
+
npx cap open @capacitor-community/electron
|
|
52
|
+
🚨 Since release 3.4.1-4 <<- 🚨
|
|
53
|
+
|
|
31
54
|
🚨 Since release 3.4.1-1 ->> 🚨
|
|
32
55
|
|
|
33
56
|
- add iosIsEncryption, androidIsEncryption in capacitor.config.ts
|
|
34
|
-
When your application use only `non-encrypted
|
|
57
|
+
When your application use only `non-encrypted databases` set those parameter to false then iOS KeyChain & Android MasterKey are not defined.
|
|
35
58
|
|
|
36
59
|
🚨 Since release 3.4.1-1 <<- 🚨
|
|
37
60
|
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java
CHANGED
|
@@ -29,6 +29,7 @@ import java.io.IOException;
|
|
|
29
29
|
import java.nio.charset.Charset;
|
|
30
30
|
import java.nio.charset.StandardCharsets;
|
|
31
31
|
import java.security.GeneralSecurityException;
|
|
32
|
+
import java.security.KeyStore;
|
|
32
33
|
import java.util.ArrayList;
|
|
33
34
|
import java.util.Arrays;
|
|
34
35
|
import java.util.Collections;
|
|
@@ -63,7 +64,7 @@ public class CapacitorSQLite {
|
|
|
63
64
|
private Boolean biometricAuth = false;
|
|
64
65
|
private String biometricTitle;
|
|
65
66
|
private String biometricSubTitle;
|
|
66
|
-
private int VALIDITY_DURATION =
|
|
67
|
+
private int VALIDITY_DURATION = 5;
|
|
67
68
|
private RetHandler rHandler = new RetHandler();
|
|
68
69
|
private PluginCall call;
|
|
69
70
|
|
|
@@ -86,11 +87,18 @@ public class CapacitorSQLite {
|
|
|
86
87
|
@Override
|
|
87
88
|
public void onSuccess(BiometricPrompt.AuthenticationResult result) {
|
|
88
89
|
try {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
|
|
91
|
+
ks.load(null);
|
|
92
|
+
Enumeration<String> aliases = ks.aliases();
|
|
93
|
+
if (aliases.hasMoreElements()) {
|
|
94
|
+
masterKeyAlias =
|
|
95
|
+
new MasterKey.Builder(context)
|
|
96
|
+
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
|
97
|
+
.setUserAuthenticationRequired(true, VALIDITY_DURATION)
|
|
98
|
+
.build();
|
|
99
|
+
} else {
|
|
100
|
+
masterKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
|
|
101
|
+
}
|
|
94
102
|
setSharedPreferences();
|
|
95
103
|
notifyBiometricEvent(true, null);
|
|
96
104
|
return;
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java
CHANGED
|
@@ -569,17 +569,22 @@ public class Database {
|
|
|
569
569
|
// check if the table has already been created
|
|
570
570
|
boolean isExists = _uJson.isTableExists(this, "sync_table");
|
|
571
571
|
if (!isExists) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
572
|
+
boolean isLastModified = _uJson.isLastModified(this);
|
|
573
|
+
if (isLastModified) {
|
|
574
|
+
Date date = new Date();
|
|
575
|
+
long syncTime = date.getTime() / 1000L;
|
|
576
|
+
String[] statements = {
|
|
577
|
+
"CREATE TABLE IF NOT EXISTS sync_table (" + "id INTEGER PRIMARY KEY NOT NULL," + "sync_date INTEGER);",
|
|
578
|
+
"INSERT INTO sync_table (sync_date) VALUES ('" + syncTime + "');"
|
|
579
|
+
};
|
|
580
|
+
try {
|
|
581
|
+
retObj = execute(statements);
|
|
582
|
+
return retObj;
|
|
583
|
+
} catch (Exception e) {
|
|
584
|
+
throw new Exception(e.getMessage());
|
|
585
|
+
}
|
|
586
|
+
} else {
|
|
587
|
+
throw new Exception("No last_modified column in tables");
|
|
583
588
|
}
|
|
584
589
|
} else {
|
|
585
590
|
retObj.put("changes", Integer.valueOf(0));
|
|
@@ -596,6 +601,10 @@ public class Database {
|
|
|
596
601
|
public void setSyncDate(String syncDate) throws Exception {
|
|
597
602
|
JSObject retObj = new JSObject();
|
|
598
603
|
try {
|
|
604
|
+
boolean isSyncTable = _uJson.isTableExists(this, "sync_table");
|
|
605
|
+
if (!isSyncTable) {
|
|
606
|
+
throw new Exception("No sync_table available");
|
|
607
|
+
}
|
|
599
608
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
|
600
609
|
Date date = formatter.parse(syncDate.replaceAll("Z$", "+0000"));
|
|
601
610
|
long syncTime = date.getTime() / 1000L;
|
|
@@ -614,6 +623,10 @@ public class Database {
|
|
|
614
623
|
public Long getSyncDate() throws Exception {
|
|
615
624
|
long syncDate = 0;
|
|
616
625
|
try {
|
|
626
|
+
boolean isSyncTable = _uJson.isTableExists(this, "sync_table");
|
|
627
|
+
if (!isSyncTable) {
|
|
628
|
+
throw new Exception("No sync_table available");
|
|
629
|
+
}
|
|
617
630
|
syncDate = toJson.getSyncDate(this);
|
|
618
631
|
return syncDate;
|
|
619
632
|
} catch (Exception e) {
|
|
@@ -68,6 +68,11 @@ public class ExportToJson {
|
|
|
68
68
|
if (resTables.length() == 0) {
|
|
69
69
|
throw new Exception("CreateExportObject: table's names failed");
|
|
70
70
|
} else {
|
|
71
|
+
boolean isSyncTable = uJson.isTableExists(db, "sync_table");
|
|
72
|
+
if (!isSyncTable && sqlObj.getMode().equals("partial")) {
|
|
73
|
+
throw new Exception("No sync_table available");
|
|
74
|
+
}
|
|
75
|
+
|
|
71
76
|
switch (sqlObj.getMode()) {
|
|
72
77
|
case "partial":
|
|
73
78
|
tables = getTablesPartial(db, resTables);
|
|
@@ -167,11 +167,15 @@ public class ImportFromJson {
|
|
|
167
167
|
private ArrayList<String> createTableSchema(ArrayList<JsonColumn> mSchema, String tableName) {
|
|
168
168
|
ArrayList<String> statements = new ArrayList<>();
|
|
169
169
|
String stmt = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(tableName).append(" (").toString();
|
|
170
|
+
Boolean isLastModified = false;
|
|
170
171
|
for (int j = 0; j < mSchema.size(); j++) {
|
|
171
172
|
if (j == mSchema.size() - 1) {
|
|
172
173
|
if (mSchema.get(j).getColumn() != null) {
|
|
173
174
|
stmt =
|
|
174
175
|
new StringBuilder(stmt).append(mSchema.get(j).getColumn()).append(" ").append(mSchema.get(j).getValue()).toString();
|
|
176
|
+
if (mSchema.get(j).getColumn().equals("last_modified")) {
|
|
177
|
+
isLastModified = true;
|
|
178
|
+
}
|
|
175
179
|
} else if (mSchema.get(j).getForeignkey() != null) {
|
|
176
180
|
stmt =
|
|
177
181
|
new StringBuilder(stmt)
|
|
@@ -198,6 +202,9 @@ public class ImportFromJson {
|
|
|
198
202
|
.append(mSchema.get(j).getValue())
|
|
199
203
|
.append(",")
|
|
200
204
|
.toString();
|
|
205
|
+
if (mSchema.get(j).getColumn().equals("last_modified")) {
|
|
206
|
+
isLastModified = true;
|
|
207
|
+
}
|
|
201
208
|
} else if (mSchema.get(j).getForeignkey() != null) {
|
|
202
209
|
stmt =
|
|
203
210
|
new StringBuilder(stmt)
|
|
@@ -221,21 +228,23 @@ public class ImportFromJson {
|
|
|
221
228
|
}
|
|
222
229
|
stmt = new StringBuilder(stmt).append(");").toString();
|
|
223
230
|
statements.add(stmt);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
231
|
+
if (isLastModified) {
|
|
232
|
+
// create trigger last_modified associated with the table
|
|
233
|
+
String stmtTrigger = new StringBuilder("CREATE TRIGGER IF NOT EXISTS ")
|
|
234
|
+
.append(tableName)
|
|
235
|
+
.append("_trigger_last_modified")
|
|
236
|
+
.append(" AFTER UPDATE ON ")
|
|
237
|
+
.append(tableName)
|
|
238
|
+
.append(" FOR EACH ROW ")
|
|
239
|
+
.append("WHEN NEW.last_modified <= " + "OLD.last_modified BEGIN ")
|
|
240
|
+
.append("UPDATE ")
|
|
241
|
+
.append(tableName)
|
|
242
|
+
.append(" SET last_modified = (strftime('%s','now')) ")
|
|
243
|
+
.append("WHERE id=OLD.id; ")
|
|
244
|
+
.append("END;")
|
|
245
|
+
.toString();
|
|
246
|
+
statements.add(stmtTrigger);
|
|
247
|
+
}
|
|
239
248
|
return statements;
|
|
240
249
|
}
|
|
241
250
|
|
|
@@ -3,6 +3,7 @@ package com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson;
|
|
|
3
3
|
import com.getcapacitor.JSArray;
|
|
4
4
|
import com.getcapacitor.JSObject;
|
|
5
5
|
import com.getcapacitor.community.database.sqlite.SQLite.Database;
|
|
6
|
+
import com.getcapacitor.community.database.sqlite.SQLite.UtilsDrop;
|
|
6
7
|
import java.sql.Blob;
|
|
7
8
|
import java.util.ArrayList;
|
|
8
9
|
import java.util.Iterator;
|
|
@@ -16,6 +17,28 @@ public class UtilsJson {
|
|
|
16
17
|
private JsonIndex uJIdx = new JsonIndex();
|
|
17
18
|
private JsonTrigger uJTrg = new JsonTrigger();
|
|
18
19
|
private JsonView uJView = new JsonView();
|
|
20
|
+
private UtilsDrop _uDrop = new UtilsDrop();
|
|
21
|
+
|
|
22
|
+
public boolean isLastModified(Database db) throws Exception {
|
|
23
|
+
if (!db.isOpen()) {
|
|
24
|
+
throw new Exception("isLastModified: Database not opened");
|
|
25
|
+
}
|
|
26
|
+
boolean ret = false;
|
|
27
|
+
try {
|
|
28
|
+
List<String> tables = _uDrop.getTablesNames(db);
|
|
29
|
+
for (String tableName : tables) {
|
|
30
|
+
JSObject namesTypes = getTableColumnNamesTypes(db, tableName);
|
|
31
|
+
ArrayList<String> colNames = (ArrayList<String>) namesTypes.get("names");
|
|
32
|
+
if (colNames.contains("last_modified")) {
|
|
33
|
+
ret = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return ret;
|
|
38
|
+
} catch (Exception e) {
|
|
39
|
+
throw new Exception("isLastModified: " + e.getMessage());
|
|
40
|
+
}
|
|
41
|
+
}
|
|
19
42
|
|
|
20
43
|
/**
|
|
21
44
|
* Check if a table exists
|