@capacitor-community/sqlite 5.0.5-2 → 5.0.6
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/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +118 -156
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +81 -249
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/NotificationCenter.java +1 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/RetHandler.java +0 -12
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +184 -40
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +141 -135
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +2 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsEncryption.java +111 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsBiometric.java +0 -4
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java +30 -18
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsMigrate.java +12 -4
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsNCDatabase.java +4 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLCipher.java +8 -6
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java +14 -28
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSecret.java +3 -4
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsUpgrade.java +0 -1
- package/dist/esm/definitions.d.ts +91 -4
- package/dist/esm/definitions.js +79 -19
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +8 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +87 -19
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +87 -19
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +333 -148
- package/electron/dist/plugin.js.map +1 -1
- package/electron/rollup.config.js +2 -0
- package/ios/Plugin/CapacitorSQLite.swift +125 -92
- package/ios/Plugin/CapacitorSQLitePlugin.swift +6 -3
- package/ios/Plugin/Database.swift +45 -19
- package/ios/Plugin/ImportExportJson/ExportToJson.swift +10 -5
- package/ios/Plugin/ImportExportJson/ImportData.swift +434 -0
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +47 -59
- package/ios/Plugin/ImportExportJson/JsonSQLite.swift +7 -0
- package/ios/Plugin/Utils/UtilsDownloadFromHTTP.swift +61 -61
- package/ios/Plugin/Utils/UtilsDrop.swift +2 -1
- package/ios/Plugin/Utils/UtilsJson.swift +123 -1
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +254 -23
- package/ios/Plugin/Utils/UtilsUpgrade.swift +0 -1
- package/package.json +2 -2
- package/src/definitions.ts +171 -18
- package/src/web.ts +10 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
package com.getcapacitor.community.database.sqlite.SQLite.ImportExportJson;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.content.SharedPreferences;
|
|
5
|
+
import android.util.Base64;
|
|
6
|
+
import com.getcapacitor.JSObject;
|
|
7
|
+
import com.getcapacitor.community.database.sqlite.SQLite.UtilsSecret;
|
|
8
|
+
import java.security.NoSuchAlgorithmException;
|
|
9
|
+
import java.security.SecureRandom;
|
|
10
|
+
import java.security.spec.InvalidKeySpecException;
|
|
11
|
+
import javax.crypto.Cipher;
|
|
12
|
+
import javax.crypto.SecretKey;
|
|
13
|
+
import javax.crypto.SecretKeyFactory;
|
|
14
|
+
import javax.crypto.spec.GCMParameterSpec;
|
|
15
|
+
import javax.crypto.spec.PBEKeySpec;
|
|
16
|
+
import javax.crypto.spec.SecretKeySpec;
|
|
17
|
+
import org.json.JSONObject;
|
|
18
|
+
|
|
19
|
+
public class UtilsEncryption {
|
|
20
|
+
|
|
21
|
+
private static final int ITERATION_COUNT = 65536;
|
|
22
|
+
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
|
23
|
+
private static final String CIPHER_TRANSFORMATION = "AES/GCM/NoPadding";
|
|
24
|
+
|
|
25
|
+
private static final String SALT = "jeep_capacitor_sqlite";
|
|
26
|
+
|
|
27
|
+
public static String encryptJSONObject(Context context, JSONObject jsonObject) throws Exception {
|
|
28
|
+
String jsonString = jsonObject.toString();
|
|
29
|
+
|
|
30
|
+
if (!UtilsSecret.isPassphrase()) {
|
|
31
|
+
throw new Exception("encryptJSONObject: No Passphrase stored");
|
|
32
|
+
}
|
|
33
|
+
String passphrase = UtilsSecret.getPassphrase();
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
// byte[] saltBytes = generateSalt();
|
|
37
|
+
byte[] saltBytes = SALT.getBytes("UTF-8");
|
|
38
|
+
// Derive a secure key from the passphrase using PBKDF2
|
|
39
|
+
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
|
40
|
+
PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), saltBytes, ITERATION_COUNT, 256);
|
|
41
|
+
SecretKey secretKey = new SecretKeySpec(factory.generateSecret(keySpec).getEncoded(), "AES");
|
|
42
|
+
|
|
43
|
+
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
|
|
44
|
+
// Extract the IV from the saltBytes (first 12 bytes for GCM)
|
|
45
|
+
GCMParameterSpec spec = new GCMParameterSpec(128, saltBytes, 0, 12);
|
|
46
|
+
cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);
|
|
47
|
+
|
|
48
|
+
byte[] encryptedBytes = cipher.doFinal(jsonString.getBytes());
|
|
49
|
+
|
|
50
|
+
// Concatenate salt and encrypted data for storage
|
|
51
|
+
byte[] combined = new byte[saltBytes.length + encryptedBytes.length];
|
|
52
|
+
System.arraycopy(saltBytes, 0, combined, 0, saltBytes.length);
|
|
53
|
+
System.arraycopy(encryptedBytes, 0, combined, saltBytes.length, encryptedBytes.length);
|
|
54
|
+
|
|
55
|
+
return Base64.encodeToString(combined, Base64.DEFAULT);
|
|
56
|
+
} catch (Exception e) {
|
|
57
|
+
e.printStackTrace();
|
|
58
|
+
throw new Exception("encryptJSONObject: " + e.getMessage());
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Decrypts the JSONObject from the Base64 string
|
|
63
|
+
public static JSObject decryptJSONObject(Context context, String encryptedBase64) throws Exception {
|
|
64
|
+
if (!UtilsSecret.isPassphrase()) {
|
|
65
|
+
throw new Exception("decryptJSONObject: No Passphrase stored");
|
|
66
|
+
}
|
|
67
|
+
String passphrase = UtilsSecret.getPassphrase();
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
byte[] combined = Base64.decode(encryptedBase64, Base64.DEFAULT);
|
|
71
|
+
|
|
72
|
+
// byte[] saltBytes = generateSalt();
|
|
73
|
+
byte[] saltBytes = SALT.getBytes("UTF-8");
|
|
74
|
+
|
|
75
|
+
byte[] encryptedBytes = new byte[combined.length - saltBytes.length];
|
|
76
|
+
System.arraycopy(combined, 0, saltBytes, 0, saltBytes.length);
|
|
77
|
+
System.arraycopy(combined, saltBytes.length, encryptedBytes, 0, encryptedBytes.length);
|
|
78
|
+
|
|
79
|
+
// Derive a secure key from the passphrase using PBKDF2
|
|
80
|
+
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
|
81
|
+
PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), saltBytes, ITERATION_COUNT, 256);
|
|
82
|
+
SecretKey secretKey = new SecretKeySpec(factory.generateSecret(keySpec).getEncoded(), "AES");
|
|
83
|
+
|
|
84
|
+
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
|
|
85
|
+
|
|
86
|
+
// Extract the IV from the saltBytes (first 12 bytes for GCM)
|
|
87
|
+
GCMParameterSpec spec = new GCMParameterSpec(128, saltBytes, 0, 12);
|
|
88
|
+
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
|
|
89
|
+
|
|
90
|
+
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
|
91
|
+
return new JSObject(new String(decryptedBytes, "UTF-8"));
|
|
92
|
+
} catch (Exception e) {
|
|
93
|
+
e.printStackTrace();
|
|
94
|
+
throw new Exception("decryptJSONObject: " + e.getMessage());
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Other methods...
|
|
99
|
+
|
|
100
|
+
private static byte[] generateSalt() {
|
|
101
|
+
try {
|
|
102
|
+
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
|
|
103
|
+
byte[] salt = new byte[16]; // 16 bytes is recommended for AES
|
|
104
|
+
secureRandom.nextBytes(salt);
|
|
105
|
+
return salt;
|
|
106
|
+
} catch (NoSuchAlgorithmException e) {
|
|
107
|
+
e.printStackTrace();
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsBiometric.java
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.getcapacitor.community.database.sqlite.SQLite;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
|
-
import android.content.SharedPreferences;
|
|
5
4
|
import android.util.Log;
|
|
6
5
|
import android.widget.Toast;
|
|
7
6
|
import androidx.annotation.NonNull;
|
|
@@ -9,9 +8,6 @@ import androidx.biometric.BiometricManager;
|
|
|
9
8
|
import androidx.biometric.BiometricPrompt;
|
|
10
9
|
import androidx.core.content.ContextCompat;
|
|
11
10
|
import androidx.fragment.app.FragmentActivity;
|
|
12
|
-
import androidx.security.crypto.MasterKey;
|
|
13
|
-
import java.io.IOException;
|
|
14
|
-
import java.security.GeneralSecurityException;
|
|
15
11
|
import java.util.concurrent.Executor;
|
|
16
12
|
|
|
17
13
|
public class UtilsBiometric {
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsFile.java
CHANGED
|
@@ -2,9 +2,7 @@ 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;
|
|
6
5
|
import android.util.Log;
|
|
7
|
-
import androidx.annotation.RequiresApi;
|
|
8
6
|
import java.io.File;
|
|
9
7
|
import java.io.FileInputStream;
|
|
10
8
|
import java.io.FileOutputStream;
|
|
@@ -12,16 +10,8 @@ import java.io.IOException;
|
|
|
12
10
|
import java.io.InputStream;
|
|
13
11
|
import java.io.OutputStream;
|
|
14
12
|
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;
|
|
19
13
|
import java.util.ArrayList;
|
|
20
|
-
import java.util.HashSet;
|
|
21
14
|
import java.util.List;
|
|
22
|
-
import java.util.Set;
|
|
23
|
-
import java.util.stream.Collectors;
|
|
24
|
-
import java.util.stream.Stream;
|
|
25
15
|
import java.util.zip.ZipEntry;
|
|
26
16
|
import java.util.zip.ZipInputStream;
|
|
27
17
|
|
|
@@ -90,7 +80,10 @@ public class UtilsFile {
|
|
|
90
80
|
String pathDB = new File(context.getFilesDir().getParentFile(), "databases").getAbsolutePath();
|
|
91
81
|
File dirDB = new File(pathDB);
|
|
92
82
|
if (!dirDB.isDirectory()) {
|
|
93
|
-
dirDB.mkdir();
|
|
83
|
+
boolean nDir = dirDB.mkdir();
|
|
84
|
+
if (!nDir) {
|
|
85
|
+
throw new Exception("Cannot create dir" + pathDB);
|
|
86
|
+
}
|
|
94
87
|
}
|
|
95
88
|
|
|
96
89
|
// look into the public/assets/databases to get databases to copy
|
|
@@ -228,7 +221,10 @@ public class UtilsFile {
|
|
|
228
221
|
|
|
229
222
|
try {
|
|
230
223
|
if (!toFile.exists()) {
|
|
231
|
-
toFile.createNewFile();
|
|
224
|
+
boolean cFile = toFile.createNewFile();
|
|
225
|
+
if (!cFile) {
|
|
226
|
+
throw new Exception("Cannot create file" + dbName);
|
|
227
|
+
}
|
|
232
228
|
}
|
|
233
229
|
copyFileFromFile(file, toFile);
|
|
234
230
|
return true;
|
|
@@ -240,13 +236,19 @@ public class UtilsFile {
|
|
|
240
236
|
|
|
241
237
|
public Boolean copyFromNames(Context context, String fromPath, String fromName, String toPath, String toName) {
|
|
242
238
|
File fromFile = new File(fromPath, fromName);
|
|
243
|
-
fromFile.setReadable(true, false);
|
|
239
|
+
boolean fFile = fromFile.setReadable(true, false);
|
|
240
|
+
if (!fFile) {
|
|
241
|
+
Log.e(TAG, "Error: in fromFile " + fromName);
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
244
|
File toFile = context.getDatabasePath(toName);
|
|
245
245
|
try {
|
|
246
246
|
if (!toFile.exists()) {
|
|
247
|
-
toFile.createNewFile();
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
boolean cFile = toFile.createNewFile();
|
|
248
|
+
if (!cFile) {
|
|
249
|
+
Log.e(TAG, "Error: in toFile " + toName);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
250
252
|
}
|
|
251
253
|
copyFileFromFile(fromFile, toFile);
|
|
252
254
|
return true;
|
|
@@ -372,10 +374,20 @@ public class UtilsFile {
|
|
|
372
374
|
}
|
|
373
375
|
|
|
374
376
|
private static void copyFileFromFile(File sourceFile, File destFile) throws IOException {
|
|
375
|
-
if (!destFile.getParentFile().exists())
|
|
377
|
+
if (!destFile.getParentFile().exists()) {
|
|
378
|
+
boolean mDir = destFile.getParentFile().mkdirs();
|
|
379
|
+
if (!mDir) {
|
|
380
|
+
String message = "failed in creating directory";
|
|
381
|
+
throw new IOException(message);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
376
384
|
|
|
377
385
|
if (!destFile.exists()) {
|
|
378
|
-
destFile.createNewFile();
|
|
386
|
+
boolean cFile = destFile.createNewFile();
|
|
387
|
+
if (!cFile) {
|
|
388
|
+
String message = "failed in creating new file";
|
|
389
|
+
throw new IOException(message);
|
|
390
|
+
}
|
|
379
391
|
}
|
|
380
392
|
|
|
381
393
|
FileChannel source = null;
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsMigrate.java
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
package com.getcapacitor.community.database.sqlite.SQLite;
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
|
-
import com.getcapacitor.community.database.sqlite.SQLite.UtilsFile;
|
|
5
4
|
import java.io.File;
|
|
6
5
|
import java.util.ArrayList;
|
|
7
6
|
|
|
@@ -14,7 +13,10 @@ public class UtilsMigrate {
|
|
|
14
13
|
String pathDB = new File(context.getFilesDir().getParentFile(), "databases").getAbsolutePath();
|
|
15
14
|
File dirDB = new File(pathDB);
|
|
16
15
|
if (!dirDB.isDirectory()) {
|
|
17
|
-
dirDB.mkdir();
|
|
16
|
+
boolean nDir = dirDB.mkdir();
|
|
17
|
+
if (!nDir) {
|
|
18
|
+
throw new Exception("Cannot create dir" + pathDB);
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
21
|
String pathFiles = this.getFolder(context, folderPath);
|
|
20
22
|
// check if the path exists
|
|
@@ -30,7 +32,10 @@ public class UtilsMigrate {
|
|
|
30
32
|
String pathDB = new File(context.getFilesDir().getParentFile(), "databases").getAbsolutePath();
|
|
31
33
|
File dirDB = new File(pathDB);
|
|
32
34
|
if (!dirDB.isDirectory()) {
|
|
33
|
-
dirDB.mkdir();
|
|
35
|
+
boolean nDir = dirDB.mkdir();
|
|
36
|
+
if (!nDir) {
|
|
37
|
+
throw new Exception("Cannot create dir" + pathDB);
|
|
38
|
+
}
|
|
34
39
|
}
|
|
35
40
|
String pathFiles = this.getFolder(context, folderPath);
|
|
36
41
|
// check if the path exists
|
|
@@ -129,7 +134,10 @@ public class UtilsMigrate {
|
|
|
129
134
|
String pathDB = new File(context.getFilesDir().getParentFile(), "databases").getAbsolutePath();
|
|
130
135
|
File dirDB = new File(pathDB);
|
|
131
136
|
if (!dirDB.isDirectory()) {
|
|
132
|
-
dirDB.mkdir();
|
|
137
|
+
boolean nDir = dirDB.mkdir();
|
|
138
|
+
if (!nDir) {
|
|
139
|
+
throw new Exception("Cannot create dir" + pathDB);
|
|
140
|
+
}
|
|
133
141
|
}
|
|
134
142
|
String pathFiles = this.getFolder(context, folderPath);
|
|
135
143
|
// check if the path exists
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsNCDatabase.java
CHANGED
|
@@ -12,7 +12,10 @@ public class UtilsNCDatabase {
|
|
|
12
12
|
String pathDB = new File(context.getFilesDir().getParentFile(), "databases").getAbsolutePath();
|
|
13
13
|
File dirDB = new File(pathDB);
|
|
14
14
|
if (!dirDB.isDirectory()) {
|
|
15
|
-
dirDB.mkdir();
|
|
15
|
+
boolean nDir = dirDB.mkdir();
|
|
16
|
+
if (!nDir) {
|
|
17
|
+
throw new Exception("Cannot create dir" + pathDB);
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
String pathFiles = uMigrate.getFolder(context, folderPath);
|
|
18
21
|
// check if the path exists
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLCipher.java
CHANGED
|
@@ -2,13 +2,9 @@ package com.getcapacitor.community.database.sqlite.SQLite;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.content.SharedPreferences;
|
|
5
|
-
import android.text.Editable;
|
|
6
|
-
import android.util.Log;
|
|
7
|
-
import androidx.sqlite.db.SupportSQLiteDatabase;
|
|
8
5
|
import java.io.File;
|
|
9
6
|
import java.io.FileNotFoundException;
|
|
10
7
|
import java.io.IOException;
|
|
11
|
-
import java.util.Arrays;
|
|
12
8
|
import net.sqlcipher.database.SQLiteDatabase;
|
|
13
9
|
import net.sqlcipher.database.SQLiteException;
|
|
14
10
|
import net.sqlcipher.database.SQLiteStatement;
|
|
@@ -125,8 +121,14 @@ public class UtilsSQLCipher {
|
|
|
125
121
|
st.close();
|
|
126
122
|
db.close();
|
|
127
123
|
|
|
128
|
-
originalFile.delete();
|
|
129
|
-
|
|
124
|
+
boolean delFile = originalFile.delete();
|
|
125
|
+
if (!delFile) {
|
|
126
|
+
throw new FileNotFoundException(originalFile.getAbsolutePath() + " not deleted");
|
|
127
|
+
}
|
|
128
|
+
boolean renFile = newFile.renameTo(originalFile);
|
|
129
|
+
if (!renFile) {
|
|
130
|
+
throw new FileNotFoundException(originalFile.getAbsolutePath() + " not renamed");
|
|
131
|
+
}
|
|
130
132
|
} else {
|
|
131
133
|
throw new FileNotFoundException(originalFile.getAbsolutePath() + " not found");
|
|
132
134
|
}
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java
CHANGED
|
@@ -3,8 +3,6 @@ package com.getcapacitor.community.database.sqlite.SQLite;
|
|
|
3
3
|
import android.util.Log;
|
|
4
4
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
|
5
5
|
import com.getcapacitor.JSArray;
|
|
6
|
-
import java.nio.ByteBuffer;
|
|
7
|
-
import java.nio.charset.StandardCharsets;
|
|
8
6
|
import java.util.ArrayList;
|
|
9
7
|
import java.util.Arrays;
|
|
10
8
|
import java.util.List;
|
|
@@ -21,44 +19,32 @@ public class UtilsSQLite {
|
|
|
21
19
|
String SELECT_CHANGE = "SELECT total_changes()";
|
|
22
20
|
Boolean success = true;
|
|
23
21
|
int ret = Integer.valueOf(-1);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (cursor
|
|
27
|
-
|
|
28
|
-
ret = Integer.parseInt(cursor.getString(0));
|
|
29
|
-
}
|
|
22
|
+
Cursor cursor = (Cursor) db.query(SELECT_CHANGE, null);
|
|
23
|
+
if (cursor != null) {
|
|
24
|
+
if (cursor.moveToFirst()) {
|
|
25
|
+
ret = Integer.parseInt(cursor.getString(0));
|
|
30
26
|
}
|
|
31
|
-
cursor.close();
|
|
32
|
-
} catch (Exception e) {
|
|
33
|
-
Log.d(TAG, "Error: dbChanges failed: ", e);
|
|
34
|
-
} finally {
|
|
35
|
-
return ret;
|
|
36
27
|
}
|
|
28
|
+
cursor.close();
|
|
29
|
+
return ret;
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
public long dbLastId(SupportSQLiteDatabase db) {
|
|
40
33
|
String SELECT_CHANGE = "SELECT last_insert_rowid()";
|
|
41
34
|
Boolean success = true;
|
|
42
|
-
long ret =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (cursor.moveToFirst()) {
|
|
47
|
-
ret = Long.parseLong(cursor.getString(0));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
cursor.close();
|
|
51
|
-
} catch (Exception e) {
|
|
52
|
-
Log.d(TAG, "Error: dbLastId failed: ", e);
|
|
53
|
-
} finally {
|
|
54
|
-
return ret;
|
|
35
|
+
long ret = (long) -1;
|
|
36
|
+
Cursor cursor = (Cursor) db.query(SELECT_CHANGE, null);
|
|
37
|
+
if (cursor.moveToFirst()) {
|
|
38
|
+
ret = Long.parseLong(cursor.getString(0));
|
|
55
39
|
}
|
|
40
|
+
cursor.close();
|
|
41
|
+
return ret;
|
|
56
42
|
}
|
|
57
43
|
|
|
58
44
|
public String[] getStatementsArray(String statements) {
|
|
59
|
-
statements.replace("end;", "END;");
|
|
45
|
+
String stmts = statements.replace("end;", "END;");
|
|
60
46
|
// split for each statement
|
|
61
|
-
String[] sqlCmdArray =
|
|
47
|
+
String[] sqlCmdArray = stmts.split(";\n");
|
|
62
48
|
// deal with trigger if any
|
|
63
49
|
sqlCmdArray = dealWithTriggers(sqlCmdArray);
|
|
64
50
|
// split for a single statement on multilines
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSecret.java
CHANGED
|
@@ -9,7 +9,6 @@ import android.content.Context;
|
|
|
9
9
|
import android.content.SharedPreferences;
|
|
10
10
|
import android.text.TextUtils;
|
|
11
11
|
import java.io.File;
|
|
12
|
-
import net.sqlcipher.database.SQLiteDatabase;
|
|
13
12
|
|
|
14
13
|
public class UtilsSecret {
|
|
15
14
|
|
|
@@ -18,7 +17,7 @@ public class UtilsSecret {
|
|
|
18
17
|
private GlobalSQLite globVar = new GlobalSQLite();
|
|
19
18
|
private UtilsSQLCipher uCipher = new UtilsSQLCipher();
|
|
20
19
|
|
|
21
|
-
private SharedPreferences sharedPreferences;
|
|
20
|
+
private static SharedPreferences sharedPreferences;
|
|
22
21
|
private Context context;
|
|
23
22
|
|
|
24
23
|
public UtilsSecret(Context context, SharedPreferences sharedPreferences) {
|
|
@@ -159,7 +158,7 @@ public class UtilsSecret {
|
|
|
159
158
|
sharedPreferences.edit().putString("secret", passphrase).apply();
|
|
160
159
|
}
|
|
161
160
|
|
|
162
|
-
public String getPassphrase() {
|
|
161
|
+
public static String getPassphrase() {
|
|
163
162
|
String passphrase = sharedPreferences.getString("secret", "");
|
|
164
163
|
return passphrase;
|
|
165
164
|
}
|
|
@@ -168,7 +167,7 @@ public class UtilsSecret {
|
|
|
168
167
|
sharedPreferences.edit().remove("secret").commit();
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
public Boolean isPassphrase() {
|
|
170
|
+
public static Boolean isPassphrase() {
|
|
172
171
|
if (!getPassphrase().isEmpty()) {
|
|
173
172
|
return true;
|
|
174
173
|
}
|
|
@@ -112,6 +112,18 @@ export interface CapacitorSQLitePlugin {
|
|
|
112
112
|
* @since 0.0.1
|
|
113
113
|
*/
|
|
114
114
|
close(options: capSQLiteOptions): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Load a SQlite extension
|
|
117
|
+
* @param options :capSQLiteExtensionPath
|
|
118
|
+
* @returns Promise<void>
|
|
119
|
+
* @since 5.0.6
|
|
120
|
+
*/
|
|
121
|
+
/**
|
|
122
|
+
* Enable Or Disable Extension Loading
|
|
123
|
+
* @param options
|
|
124
|
+
* @returns Promise<void>
|
|
125
|
+
* @since 5.0.6
|
|
126
|
+
*/
|
|
115
127
|
/**
|
|
116
128
|
* GetUrl get the database Url
|
|
117
129
|
* @param options: capSQLiteOptions
|
|
@@ -378,6 +390,38 @@ export interface capEchoOptions {
|
|
|
378
390
|
*/
|
|
379
391
|
value?: string;
|
|
380
392
|
}
|
|
393
|
+
export interface capSQLiteExtensionPath {
|
|
394
|
+
/**
|
|
395
|
+
* The database name
|
|
396
|
+
*/
|
|
397
|
+
database?: string;
|
|
398
|
+
/**
|
|
399
|
+
* The extension path
|
|
400
|
+
*/
|
|
401
|
+
path?: string;
|
|
402
|
+
/**
|
|
403
|
+
* ReadOnly / ReadWrite
|
|
404
|
+
* default ReadWrite (false)
|
|
405
|
+
* @since 4.1.0-7
|
|
406
|
+
*/
|
|
407
|
+
readonly?: boolean;
|
|
408
|
+
}
|
|
409
|
+
export interface capSQLiteExtensionEnable {
|
|
410
|
+
/**
|
|
411
|
+
* The database name
|
|
412
|
+
*/
|
|
413
|
+
database?: string;
|
|
414
|
+
/**
|
|
415
|
+
* The enabling toggle (1: ON, 0: OFF)
|
|
416
|
+
*/
|
|
417
|
+
toggle?: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* ReadOnly / ReadWrite
|
|
420
|
+
* default ReadWrite (false)
|
|
421
|
+
* @since 4.1.0-7
|
|
422
|
+
*/
|
|
423
|
+
readonly?: boolean;
|
|
424
|
+
}
|
|
381
425
|
export interface capConnectionOptions {
|
|
382
426
|
/**
|
|
383
427
|
* The database name
|
|
@@ -492,6 +536,14 @@ export interface capSQLiteSetOptions {
|
|
|
492
536
|
* @since 4.1.0-7
|
|
493
537
|
*/
|
|
494
538
|
readonly?: boolean;
|
|
539
|
+
/**
|
|
540
|
+
* return mode
|
|
541
|
+
* default 'no'
|
|
542
|
+
* value 'all'
|
|
543
|
+
* value 'one' for Electron platform
|
|
544
|
+
* @since 5.0.5-3
|
|
545
|
+
*/
|
|
546
|
+
returnMode?: string;
|
|
495
547
|
}
|
|
496
548
|
export interface capSQLiteRunOptions {
|
|
497
549
|
/**
|
|
@@ -518,6 +570,14 @@ export interface capSQLiteRunOptions {
|
|
|
518
570
|
* @since 4.1.0-7
|
|
519
571
|
*/
|
|
520
572
|
readonly?: boolean;
|
|
573
|
+
/**
|
|
574
|
+
* return mode
|
|
575
|
+
* default 'no'
|
|
576
|
+
* value 'all'
|
|
577
|
+
* value 'one' for Electron platform
|
|
578
|
+
* @since 5.0.5-3
|
|
579
|
+
*/
|
|
580
|
+
returnMode?: string;
|
|
521
581
|
}
|
|
522
582
|
export interface capSQLiteQueryOptions {
|
|
523
583
|
/**
|
|
@@ -706,6 +766,10 @@ export interface Changes {
|
|
|
706
766
|
* the lastId created from a run command
|
|
707
767
|
*/
|
|
708
768
|
lastId?: number;
|
|
769
|
+
/**
|
|
770
|
+
* values when RETURNING
|
|
771
|
+
*/
|
|
772
|
+
values?: any[];
|
|
709
773
|
}
|
|
710
774
|
export interface capSQLiteValues {
|
|
711
775
|
/**
|
|
@@ -732,6 +796,12 @@ export interface capSQLiteSyncDate {
|
|
|
732
796
|
*/
|
|
733
797
|
syncDate?: number;
|
|
734
798
|
}
|
|
799
|
+
export interface EncryptJson {
|
|
800
|
+
/**
|
|
801
|
+
* The encrypted JsonSQLite base64 string
|
|
802
|
+
*/
|
|
803
|
+
expData: string;
|
|
804
|
+
}
|
|
735
805
|
export interface JsonSQLite {
|
|
736
806
|
/**
|
|
737
807
|
* The database name
|
|
@@ -1243,6 +1313,20 @@ export interface ISQLiteDBConnection {
|
|
|
1243
1313
|
* @since 3.2.0
|
|
1244
1314
|
*/
|
|
1245
1315
|
getVersion(): Promise<capVersionResult>;
|
|
1316
|
+
/**
|
|
1317
|
+
* Load a SQlite extension
|
|
1318
|
+
* @param path :SQlite extension path
|
|
1319
|
+
* @returns Promise<void>
|
|
1320
|
+
* @since 5.0.6
|
|
1321
|
+
*/
|
|
1322
|
+
loadExtension(path: string): Promise<void>;
|
|
1323
|
+
/**
|
|
1324
|
+
* Enable Or Disable Extension Loading
|
|
1325
|
+
* @param toggle true:on false:off
|
|
1326
|
+
* @returns Promise<void>
|
|
1327
|
+
* @since 5.0.6
|
|
1328
|
+
*/
|
|
1329
|
+
enableLoadExtension(toggle: boolean): Promise<void>;
|
|
1246
1330
|
/**
|
|
1247
1331
|
* Execute SQLite DB Connection Statements
|
|
1248
1332
|
* @param statements
|
|
@@ -1265,14 +1349,14 @@ export interface ISQLiteDBConnection {
|
|
|
1265
1349
|
* @returns Promise<capSQLiteChanges>
|
|
1266
1350
|
* @since 2.9.0 refactor
|
|
1267
1351
|
*/
|
|
1268
|
-
run(statement: string, values?: any[], transaction?: boolean): Promise<capSQLiteChanges>;
|
|
1352
|
+
run(statement: string, values?: any[], transaction?: boolean, returnMode?: string): Promise<capSQLiteChanges>;
|
|
1269
1353
|
/**
|
|
1270
1354
|
* Execute SQLite DB Connection Set
|
|
1271
1355
|
* @param set
|
|
1272
1356
|
* @returns Promise<capSQLiteChanges>
|
|
1273
1357
|
* @since 2.9.0 refactor
|
|
1274
1358
|
*/
|
|
1275
|
-
executeSet(set: capSQLiteSet[], transaction?: boolean): Promise<capSQLiteChanges>;
|
|
1359
|
+
executeSet(set: capSQLiteSet[], transaction?: boolean, returnMode?: string): Promise<capSQLiteChanges>;
|
|
1276
1360
|
/**
|
|
1277
1361
|
* Check if a SQLite DB Connection exists
|
|
1278
1362
|
* @returns Promise<capSQLiteResult>
|
|
@@ -1357,13 +1441,15 @@ export declare class SQLiteDBConnection implements ISQLiteDBConnection {
|
|
|
1357
1441
|
getConnectionReadOnly(): boolean;
|
|
1358
1442
|
open(): Promise<void>;
|
|
1359
1443
|
close(): Promise<void>;
|
|
1444
|
+
loadExtension(path: string): Promise<void>;
|
|
1445
|
+
enableLoadExtension(toggle: boolean): Promise<void>;
|
|
1360
1446
|
getUrl(): Promise<capSQLiteUrl>;
|
|
1361
1447
|
getVersion(): Promise<capVersionResult>;
|
|
1362
1448
|
getTableList(): Promise<DBSQLiteValues>;
|
|
1363
1449
|
execute(statements: string, transaction?: boolean): Promise<capSQLiteChanges>;
|
|
1364
1450
|
query(statement: string, values?: any[]): Promise<DBSQLiteValues>;
|
|
1365
|
-
run(statement: string, values?: any[], transaction?: boolean): Promise<capSQLiteChanges>;
|
|
1366
|
-
executeSet(set: capSQLiteSet[], transaction?: boolean): Promise<capSQLiteChanges>;
|
|
1451
|
+
run(statement: string, values?: any[], transaction?: boolean, returnMode?: string): Promise<capSQLiteChanges>;
|
|
1452
|
+
executeSet(set: capSQLiteSet[], transaction?: boolean, returnMode?: string): Promise<capSQLiteChanges>;
|
|
1367
1453
|
isExists(): Promise<capSQLiteResult>;
|
|
1368
1454
|
isTable(table: string): Promise<capSQLiteResult>;
|
|
1369
1455
|
isDBOpen(): Promise<capSQLiteResult>;
|
|
@@ -1377,4 +1463,5 @@ export declare class SQLiteDBConnection implements ISQLiteDBConnection {
|
|
|
1377
1463
|
statement: string;
|
|
1378
1464
|
values?: any[];
|
|
1379
1465
|
}[]): Promise<void>;
|
|
1466
|
+
private reorderRows;
|
|
1380
1467
|
}
|