@capacitor-community/sqlite 5.0.1 → 5.0.3-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/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +1 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +11 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +6 -7
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java +13 -14
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java +45 -3
- package/electron/dist/plugin.js +37 -42
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorSQLite.swift +25 -0
- package/ios/Plugin/Extensions/Array.swift +13 -0
- package/ios/Plugin/Extensions/Data.swift +13 -0
- package/ios/Plugin/Utils/UtilsBinding.swift +6 -0
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +10 -7
- package/package.json +1 -1
package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java
CHANGED
|
@@ -30,6 +30,7 @@ import com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLCipher;
|
|
|
30
30
|
import com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLite;
|
|
31
31
|
import com.getcapacitor.community.database.sqlite.SQLite.UtilsSecret;
|
|
32
32
|
import java.io.File;
|
|
33
|
+
import java.nio.ByteBuffer;
|
|
33
34
|
import java.security.KeyStore;
|
|
34
35
|
import java.util.ArrayList;
|
|
35
36
|
import java.util.Collections;
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java
CHANGED
|
@@ -8,6 +8,7 @@ import static android.database.Cursor.FIELD_TYPE_STRING;
|
|
|
8
8
|
|
|
9
9
|
import android.content.Context;
|
|
10
10
|
import android.content.SharedPreferences;
|
|
11
|
+
import android.os.Build;
|
|
11
12
|
import android.util.Log;
|
|
12
13
|
import androidx.sqlite.db.SimpleSQLiteQuery;
|
|
13
14
|
import androidx.sqlite.db.SupportSQLiteDatabase;
|
|
@@ -22,6 +23,7 @@ import java.io.File;
|
|
|
22
23
|
import java.text.SimpleDateFormat;
|
|
23
24
|
import java.util.ArrayList;
|
|
24
25
|
import java.util.Arrays;
|
|
26
|
+
import java.util.Base64;
|
|
25
27
|
import java.util.Collections;
|
|
26
28
|
import java.util.Date;
|
|
27
29
|
import java.util.Dictionary;
|
|
@@ -795,7 +797,15 @@ public class Database {
|
|
|
795
797
|
row.put(colName, c.getDouble(index));
|
|
796
798
|
break;
|
|
797
799
|
case FIELD_TYPE_BLOB:
|
|
798
|
-
|
|
800
|
+
byte[] blobVal = c.getBlob(index);
|
|
801
|
+
JSArray arr = this._uSqlite.ByteArrayToJSArray(blobVal);
|
|
802
|
+
row.put(colName, arr);
|
|
803
|
+
/* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
804
|
+
row.put(colName, Base64.getEncoder().encodeToString(c.getBlob(index)));
|
|
805
|
+
} else {
|
|
806
|
+
row.put(colName, JSONObject.NULL);
|
|
807
|
+
}
|
|
808
|
+
*/
|
|
799
809
|
break;
|
|
800
810
|
case FIELD_TYPE_NULL:
|
|
801
811
|
row.put(colName, JSONObject.NULL);
|
|
@@ -558,13 +558,12 @@ public class ImportFromJson {
|
|
|
558
558
|
// Delete
|
|
559
559
|
isUpdate = false;
|
|
560
560
|
Object key = tColNames.get(0);
|
|
561
|
-
StringBuilder sbQuery =
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
561
|
+
StringBuilder sbQuery = new StringBuilder("DELETE FROM ")
|
|
562
|
+
.append(tableName)
|
|
563
|
+
.append(" WHERE ")
|
|
564
|
+
.append(tColNames.get(0))
|
|
565
|
+
.append(" = ");
|
|
566
|
+
|
|
568
567
|
if (key instanceof Integer) sbQuery.append(row.get(0)).append(";");
|
|
569
568
|
if (key instanceof String) sbQuery.append("'").append(row.get(0)).append("';");
|
|
570
569
|
stmt = sbQuery.toString();
|
|
@@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|
|
9
9
|
import java.util.Arrays;
|
|
10
10
|
import java.util.Iterator;
|
|
11
11
|
import java.util.List;
|
|
12
|
-
|
|
13
12
|
import org.json.JSONArray;
|
|
14
13
|
import org.json.JSONException;
|
|
15
14
|
import org.json.JSONObject;
|
|
@@ -39,12 +38,12 @@ public class UtilsJson {
|
|
|
39
38
|
JSObject namesTypes = getTableColumnNamesTypes(db, tableName);
|
|
40
39
|
ArrayList<String> colNames = new ArrayList<>();
|
|
41
40
|
if (namesTypes.has("names")) {
|
|
42
|
-
|
|
41
|
+
colNames = getColumnNames(namesTypes.get("names"));
|
|
43
42
|
} else {
|
|
44
|
-
|
|
43
|
+
throw new Exception("isLastModified: Table " + tableName + " no names");
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
if (colNames.size() > 0
|
|
46
|
+
if (colNames.size() > 0 && colNames.contains("last_modified")) {
|
|
48
47
|
ret = true;
|
|
49
48
|
break;
|
|
50
49
|
}
|
|
@@ -55,18 +54,18 @@ public class UtilsJson {
|
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Get Column name's list
|
|
59
|
+
* @param obj
|
|
60
|
+
* @return
|
|
61
|
+
*/
|
|
63
62
|
public ArrayList<String> getColumnNames(Object obj) {
|
|
63
|
+
ArrayList<String> colNames = new ArrayList<>();
|
|
64
|
+
if (obj instanceof ArrayList) colNames = (ArrayList<String>) obj;
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
if (obj instanceof ArrayList) colNames = (ArrayList<String>) obj;
|
|
67
|
-
|
|
68
|
-
return colNames;
|
|
66
|
+
return colNames;
|
|
69
67
|
}
|
|
68
|
+
|
|
70
69
|
/**
|
|
71
70
|
* Check existence of sql_deleted column
|
|
72
71
|
* @param db
|
|
@@ -84,7 +83,7 @@ public class UtilsJson {
|
|
|
84
83
|
JSObject namesTypes = getTableColumnNamesTypes(db, tableName);
|
|
85
84
|
ArrayList<String> colNames = new ArrayList<>();
|
|
86
85
|
if (namesTypes.has("names")) {
|
|
87
|
-
|
|
86
|
+
colNames = getColumnNames(namesTypes.get("names"));
|
|
88
87
|
} else {
|
|
89
88
|
throw new Exception("isSqlDeleted: Table " + tableName + " no names");
|
|
90
89
|
}
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java
CHANGED
|
@@ -3,12 +3,15 @@ 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;
|
|
6
8
|
import java.util.ArrayList;
|
|
7
9
|
import java.util.Arrays;
|
|
8
10
|
import java.util.List;
|
|
9
11
|
import net.sqlcipher.Cursor;
|
|
10
12
|
import org.json.JSONArray;
|
|
11
13
|
import org.json.JSONException;
|
|
14
|
+
import org.json.JSONObject;
|
|
12
15
|
|
|
13
16
|
public class UtilsSQLite {
|
|
14
17
|
|
|
@@ -90,7 +93,7 @@ public class UtilsSQLite {
|
|
|
90
93
|
Object[] objectList = listArray.toArray();
|
|
91
94
|
String[] retArray = Arrays.copyOf(objectList, objectList.length, String[].class);
|
|
92
95
|
|
|
93
|
-
// String[] retArray = listArray.toArray(new String[listArray.size()]);
|
|
96
|
+
// String[] retArray = listArray.toArray(new String[listArray.size()]);
|
|
94
97
|
return retArray;
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -108,7 +111,7 @@ public class UtilsSQLite {
|
|
|
108
111
|
|
|
109
112
|
private List<String> trimArray(List<String> listArray) {
|
|
110
113
|
List<String> trimmedStrings = new ArrayList<String>();
|
|
111
|
-
for(String s : listArray) {
|
|
114
|
+
for (String s : listArray) {
|
|
112
115
|
trimmedStrings.add(s.trim());
|
|
113
116
|
}
|
|
114
117
|
return trimmedStrings;
|
|
@@ -120,7 +123,17 @@ public class UtilsSQLite {
|
|
|
120
123
|
if (jsArray.isNull(i)) {
|
|
121
124
|
list.add(null);
|
|
122
125
|
} else {
|
|
123
|
-
|
|
126
|
+
Object obj = jsArray.get(i);
|
|
127
|
+
if (obj.getClass() == JSONObject.class) {
|
|
128
|
+
if (((JSONObject) obj).getString("type").equals("Buffer")) {
|
|
129
|
+
byte[] bArr = JSONArrayToByteArray(((JSONObject) obj).getJSONArray("data"));
|
|
130
|
+
list.add(bArr);
|
|
131
|
+
} else {
|
|
132
|
+
throw new JSONException("Object not implemented");
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
list.add(obj);
|
|
136
|
+
}
|
|
124
137
|
}
|
|
125
138
|
}
|
|
126
139
|
return list;
|
|
@@ -139,6 +152,14 @@ public class UtilsSQLite {
|
|
|
139
152
|
return list;
|
|
140
153
|
}
|
|
141
154
|
|
|
155
|
+
public byte[] JSONArrayToByteArray(JSONArray arr) throws JSONException {
|
|
156
|
+
byte[] bArr = new byte[arr.length()];
|
|
157
|
+
for (int i = 0; i < arr.length(); i++) {
|
|
158
|
+
bArr[i] = (byte) (((int) arr.get(i)) & 0xFF);
|
|
159
|
+
}
|
|
160
|
+
return bArr;
|
|
161
|
+
}
|
|
162
|
+
|
|
142
163
|
public Boolean parse(Object mVar) {
|
|
143
164
|
boolean ret = false;
|
|
144
165
|
if (mVar instanceof JSONArray) {
|
|
@@ -146,4 +167,25 @@ public class UtilsSQLite {
|
|
|
146
167
|
}
|
|
147
168
|
return ret;
|
|
148
169
|
}
|
|
170
|
+
|
|
171
|
+
public int ByteToInt(byte BVal) {
|
|
172
|
+
String comb;
|
|
173
|
+
int out = 0;
|
|
174
|
+
comb = BVal + "";
|
|
175
|
+
out = Integer.parseInt(comb);
|
|
176
|
+
// Get Unsigned Int
|
|
177
|
+
if (out < 0) {
|
|
178
|
+
out += 256;
|
|
179
|
+
}
|
|
180
|
+
return out;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public JSArray ByteArrayToJSArray(byte[] BArr) {
|
|
184
|
+
JSArray arr = new JSArray();
|
|
185
|
+
|
|
186
|
+
for (int i = 0; i < BArr.length; i++) {
|
|
187
|
+
arr.put(ByteToInt(BArr[i]));
|
|
188
|
+
}
|
|
189
|
+
return arr;
|
|
190
|
+
}
|
|
149
191
|
}
|
package/electron/dist/plugin.js
CHANGED
|
@@ -101,7 +101,7 @@ class UtilsSQLite {
|
|
|
101
101
|
* @param password
|
|
102
102
|
*/
|
|
103
103
|
async setCipherPragma(mDB, password) {
|
|
104
|
-
console.log(
|
|
104
|
+
console.log('setCipherPragma');
|
|
105
105
|
return new Promise((resolve, reject) => {
|
|
106
106
|
mDB.serialize(() => {
|
|
107
107
|
mDB.run('PRAGMA cipher_compatibility = 4');
|
|
@@ -3277,30 +3277,28 @@ class UtilsEncryption {
|
|
|
3277
3277
|
* @param pathDB
|
|
3278
3278
|
* @param password
|
|
3279
3279
|
*/
|
|
3280
|
-
encryptDatabase(pathDB, password) {
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
resolve();
|
|
3295
|
-
}
|
|
3296
|
-
catch (err) {
|
|
3297
|
-
reject(new Error(`${msg} ${err.message} `));
|
|
3298
|
-
}
|
|
3280
|
+
async encryptDatabase(pathDB, password) {
|
|
3281
|
+
const msg = 'EncryptDatabase: ';
|
|
3282
|
+
const retB = this.fileUtil.isPathExists(pathDB);
|
|
3283
|
+
if (retB) {
|
|
3284
|
+
const tempPath = this.fileUtil.getFilePath('temp.db');
|
|
3285
|
+
try {
|
|
3286
|
+
await this.fileUtil.renameFilePath(pathDB, tempPath);
|
|
3287
|
+
const oDB = await this.sqliteUtil.openOrCreateDatabase(tempPath, '', false);
|
|
3288
|
+
const mDB = await this.sqliteUtil.openOrCreateDatabase(pathDB, password, false);
|
|
3289
|
+
await this.sqlcipherEncrypt(oDB, pathDB, password);
|
|
3290
|
+
oDB.close();
|
|
3291
|
+
this.fileUtil.deleteFilePath(tempPath);
|
|
3292
|
+
mDB.close();
|
|
3293
|
+
return Promise.resolve();
|
|
3299
3294
|
}
|
|
3300
|
-
|
|
3301
|
-
reject(new Error(`${msg}
|
|
3295
|
+
catch (err) {
|
|
3296
|
+
return Promise.reject(new Error(`${msg} ${err.message} `));
|
|
3302
3297
|
}
|
|
3303
|
-
}
|
|
3298
|
+
}
|
|
3299
|
+
else {
|
|
3300
|
+
return Promise.reject(new Error(`${msg}file path ${pathDB} ` + 'does not exist'));
|
|
3301
|
+
}
|
|
3304
3302
|
}
|
|
3305
3303
|
/**
|
|
3306
3304
|
* SqlcipherEncrypt
|
|
@@ -3308,17 +3306,15 @@ class UtilsEncryption {
|
|
|
3308
3306
|
* @param pathDB
|
|
3309
3307
|
* @param password
|
|
3310
3308
|
*/
|
|
3311
|
-
sqlcipherEncrypt(oDB, pathDB, password) {
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
oDB.run('DETACH DATABASE encrypted;');
|
|
3319
|
-
});
|
|
3320
|
-
resolve();
|
|
3309
|
+
async sqlcipherEncrypt(oDB, pathDB, password) {
|
|
3310
|
+
oDB.serialize(() => {
|
|
3311
|
+
let stmt = `ATTACH DATABASE '${pathDB}' `;
|
|
3312
|
+
stmt += `AS encrypted KEY '${password}';`;
|
|
3313
|
+
oDB.run(stmt);
|
|
3314
|
+
oDB.run("SELECT sqlcipher_export('encrypted');");
|
|
3315
|
+
oDB.run('DETACH DATABASE encrypted;');
|
|
3321
3316
|
});
|
|
3317
|
+
return Promise.resolve();
|
|
3322
3318
|
}
|
|
3323
3319
|
}
|
|
3324
3320
|
utilsEncryption.UtilsEncryption = UtilsEncryption;
|
|
@@ -3949,13 +3945,11 @@ class CapacitorSQLite {
|
|
|
3949
3945
|
const version = options.version ? options.version : 1;
|
|
3950
3946
|
// const encrypted = false;
|
|
3951
3947
|
// const inMode = "no-encryption";
|
|
3952
|
-
const encrypted = options.encrypted
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
: options.mode === "encryption"
|
|
3958
|
-
? "encryption"
|
|
3948
|
+
const encrypted = options.encrypted ? options.encrypted : false;
|
|
3949
|
+
const inMode = options.mode === 'secret'
|
|
3950
|
+
? 'secret'
|
|
3951
|
+
: options.mode === 'encryption'
|
|
3952
|
+
? 'encryption'
|
|
3959
3953
|
: 'no-encryption';
|
|
3960
3954
|
const readonly = options.readonly ? options.readonly : false;
|
|
3961
3955
|
let upgrades = {};
|
|
@@ -4621,7 +4615,8 @@ class CapacitorSQLite {
|
|
|
4621
4615
|
var _a;
|
|
4622
4616
|
if (this.globalUtil != null) {
|
|
4623
4617
|
let capSQLiteResult = { result: false };
|
|
4624
|
-
if (((_a = this.globalUtil) === null || _a === void 0 ? void 0 : _a.secret) != null &&
|
|
4618
|
+
if (((_a = this.globalUtil) === null || _a === void 0 ? void 0 : _a.secret) != null &&
|
|
4619
|
+
this.globalUtil.secret !== 'sqlite secret') {
|
|
4625
4620
|
capSQLiteResult = { result: true };
|
|
4626
4621
|
}
|
|
4627
4622
|
return Promise.resolve(capSQLiteResult);
|
|
@@ -4647,7 +4642,7 @@ class CapacitorSQLite {
|
|
|
4647
4642
|
const pathDatabase = this.fileUtil.getDatabasesPath();
|
|
4648
4643
|
// get the list of databases
|
|
4649
4644
|
const files = await this.fileUtil.getFileList(pathDatabase);
|
|
4650
|
-
files.forEach(
|
|
4645
|
+
files.forEach(dbName => {
|
|
4651
4646
|
const connName = 'RW_' + dbName;
|
|
4652
4647
|
const database = this.getDatabaseConnectionOrThrowError(connName);
|
|
4653
4648
|
database.changeSecret();
|