Skip to content

Commit ca2a5d3

Browse files
committed
fix issue#426 & issue#428 iOS & Android
1 parent c994e69 commit ca2a5d3

File tree

19 files changed

+347
-88
lines changed

19 files changed

+347
-88
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1+
# 5.0.3-1 (2023-06-13)
2+
3+
### Added Features
4+
5+
- Add SQLiteBlob.md documentation
6+
7+
### Bug Fixes
8+
9+
- fix issue#426 for Android & iOS returning binary array
10+
- fix Cannot bind buffer in Android issue#428 for Android & iOS
11+
12+
113
# 5.0.2 (2023-06-07)
214

315
### Bug Fixes
416

5-
- fix issue#426 for Android & iOS
17+
- fix issue#426 for Android & iOS with base64 string
618

719
# 5.0.1 (2023-05-31)
820

0 Bytes
Binary file not shown.

android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.getcapacitor.community.database.sqlite.SQLite.UtilsSQLite;
3131
import com.getcapacitor.community.database.sqlite.SQLite.UtilsSecret;
3232
import java.io.File;
33+
import java.nio.ByteBuffer;
3334
import java.security.KeyStore;
3435
import java.util.ArrayList;
3536
import java.util.Collections;

android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -797,12 +797,15 @@ public JSArray selectSQL(String statement, ArrayList<Object> values) throws Exce
797797
row.put(colName, c.getDouble(index));
798798
break;
799799
case FIELD_TYPE_BLOB:
800-
// row.put(colName, c.getBlob(index));
801-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
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) {
802804
row.put(colName, Base64.getEncoder().encodeToString(c.getBlob(index)));
803805
} else {
804806
row.put(colName, JSONObject.NULL);
805807
}
808+
*/
806809
break;
807810
case FIELD_TYPE_NULL:
808811
row.put(colName, JSONObject.NULL);

android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,12 @@ private String createRowStatement(
558558
// Delete
559559
isUpdate = false;
560560
Object key = tColNames.get(0);
561-
StringBuilder sbQuery =
562-
new StringBuilder("DELETE FROM ")
563-
.append(tableName)
564-
.append(" WHERE ")
565-
.append(tColNames.get(0))
566-
.append(" = ");
567-
561+
StringBuilder sbQuery = new StringBuilder("DELETE FROM ")
562+
.append(tableName)
563+
.append(" WHERE ")
564+
.append(tColNames.get(0))
565+
.append(" = ");
566+
568567
if (key instanceof Integer) sbQuery.append(row.get(0)).append(";");
569568
if (key instanceof String) sbQuery.append("'").append(row.get(0)).append("';");
570569
stmt = sbQuery.toString();

android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.util.Arrays;
1010
import java.util.Iterator;
1111
import java.util.List;
12-
1312
import org.json.JSONArray;
1413
import org.json.JSONException;
1514
import org.json.JSONObject;
@@ -39,12 +38,12 @@ public boolean isLastModified(Database db) throws Exception {
3938
JSObject namesTypes = getTableColumnNamesTypes(db, tableName);
4039
ArrayList<String> colNames = new ArrayList<>();
4140
if (namesTypes.has("names")) {
42-
colNames = getColumnNames(namesTypes.get("names"));
41+
colNames = getColumnNames(namesTypes.get("names"));
4342
} else {
44-
throw new Exception("isLastModified: Table " + tableName + " no names");
43+
throw new Exception("isLastModified: Table " + tableName + " no names");
4544
}
4645

47-
if (colNames.size() > 0 && colNames.contains("last_modified")) {
46+
if (colNames.size() > 0 && colNames.contains("last_modified")) {
4847
ret = true;
4948
break;
5049
}
@@ -55,18 +54,18 @@ public boolean isLastModified(Database db) throws Exception {
5554
}
5655
}
5756

58-
/**
59-
* Get Column name's list
60-
* @param obj
61-
* @return
62-
*/
57+
/**
58+
* Get Column name's list
59+
* @param obj
60+
* @return
61+
*/
6362
public ArrayList<String> getColumnNames(Object obj) {
63+
ArrayList<String> colNames = new ArrayList<>();
64+
if (obj instanceof ArrayList) colNames = (ArrayList<String>) obj;
6465

65-
ArrayList<String> colNames = new ArrayList<>();
66-
if (obj instanceof ArrayList) colNames = (ArrayList<String>) obj;
67-
68-
return colNames;
66+
return colNames;
6967
}
68+
7069
/**
7170
* Check existence of sql_deleted column
7271
* @param db
@@ -84,7 +83,7 @@ public boolean isSqlDeleted(Database db) throws Exception {
8483
JSObject namesTypes = getTableColumnNamesTypes(db, tableName);
8584
ArrayList<String> colNames = new ArrayList<>();
8685
if (namesTypes.has("names")) {
87-
colNames = getColumnNames(namesTypes.get("names"));
86+
colNames = getColumnNames(namesTypes.get("names"));
8887
} else {
8988
throw new Exception("isSqlDeleted: Table " + tableName + " no names");
9089
}

android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import android.util.Log;
44
import androidx.sqlite.db.SupportSQLiteDatabase;
55
import com.getcapacitor.JSArray;
6+
import java.nio.ByteBuffer;
7+
import java.nio.charset.StandardCharsets;
68
import java.util.ArrayList;
79
import java.util.Arrays;
810
import java.util.List;
911
import net.sqlcipher.Cursor;
1012
import org.json.JSONArray;
1113
import org.json.JSONException;
14+
import org.json.JSONObject;
1215

1316
public class UtilsSQLite {
1417

@@ -90,7 +93,7 @@ private String[] dealWithTriggers(String[] sqlCmdArray) {
9093
Object[] objectList = listArray.toArray();
9194
String[] retArray = Arrays.copyOf(objectList, objectList.length, String[].class);
9295

93-
// String[] retArray = listArray.toArray(new String[listArray.size()]);
96+
// String[] retArray = listArray.toArray(new String[listArray.size()]);
9497
return retArray;
9598
}
9699

@@ -108,7 +111,7 @@ private List<String> concatRemoveEnd(List<String> listArray) {
108111

109112
private List<String> trimArray(List<String> listArray) {
110113
List<String> trimmedStrings = new ArrayList<String>();
111-
for(String s : listArray) {
114+
for (String s : listArray) {
112115
trimmedStrings.add(s.trim());
113116
}
114117
return trimmedStrings;
@@ -120,7 +123,17 @@ public ArrayList<Object> objectJSArrayToArrayList(JSArray jsArray) throws JSONEx
120123
if (jsArray.isNull(i)) {
121124
list.add(null);
122125
} else {
123-
list.add(jsArray.get(i));
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+
}
124137
}
125138
}
126139
return list;
@@ -139,11 +152,40 @@ public ArrayList<String> stringJSArrayToArrayList(JSArray jsArray) throws JSONEx
139152
return list;
140153
}
141154

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+
142163
public Boolean parse(Object mVar) {
143164
boolean ret = false;
144165
if (mVar instanceof JSONArray) {
145166
ret = true;
146167
}
147168
return ret;
148169
}
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+
}
149191
}

docs/SQLiteBlob.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p>
2+
<h2 align="center">SQLite Blob DOCUMENTATION</h2>
3+
<p align="center"><strong><code>@capacitor-community/sqlite</code></strong></p>
4+
<p align="center">
5+
Capacitor community plugin for Native and Electron SQLite Databases. For <strong>Native</strong> and <strong>Electron</strong> platforms, databases could be encrypted with SQLCipher</p>
6+
7+
## Read a SQLite Blob
8+
9+
### Image Blob
10+
11+
```js
12+
...
13+
const stmt = `SELECT id, name, img FROM testblob;`;
14+
const ret: DBSQLiteValues = await db.query(stmt, []);
15+
const arr = new Uint8Array(ret.values[0].img )
16+
var myBlob = new Blob( [ arr ], { type: this.getMime(arr) } );
17+
var imageUrl = URL.createObjectURL( myBlob );
18+
const imagEL: HTMLImageElement = document.querySelector('#image');
19+
imagEL.src = imageUrl;
20+
21+
...
22+
23+
private getMime = (arr: Uint8Array): string => {
24+
let mime = "";
25+
if (arr.length > 4) {
26+
if (arr[0] == 0x89 && arr[1] == 0x50 && arr[2] == 0x4E && arr[3] == 0x47)
27+
mime = 'image/png';
28+
else if (arr[0] == 0xff && arr[1] == 0xd8)
29+
mime = 'image/jpeg';
30+
else if (arr[0] == 0x47 && arr[1] == 0x49 && arr[2] == 0x46)
31+
mime = 'image/gif';
32+
else if (arr[0] == 0x25 && arr[1] == 0x50 && arr[2] == 0x44 && arr[3] == 0x46)
33+
mime = 'application/pdf';
34+
if (arr[0] == 0x50 && arr[1] == 0x4B && arr[2] == 0x03 && arr[3] == 0x04)
35+
mime = 'application/zip';
36+
else {
37+
mime = 'text/plain';
38+
}
39+
}
40+
return mime;
41+
}
42+
...
43+
```
44+
### Text Blob
45+
46+
```js
47+
...
48+
const stmt = `SELECT id, name, blobtext FROM teach;`;
49+
const bufText = Buffer.from(ret.values[0].blobtext);
50+
const myText = bufText.toString();
51+
console.log(`&&& myText: ${myText}`);
52+
...
53+
```
54+
55+
## Write a SQLite Blob
56+
57+
### Image Blob
58+
59+
```js
60+
...
61+
const imagePath = "YOUR_IMAGE_PATH/favicon.png";
62+
const blob = await(await fetch(imagePath)).blob();
63+
const imageBuffer = Buffer.from(new Uint8Array(await blob.arrayBuffer()));
64+
const imgValues = [1,"test image", imageBuffer];
65+
ret = await db.run(stmt, imgValues);
66+
console.log(`&&& res: ${JSON.stringify(ret)}`);
67+
...
68+
```
69+
70+
### Text Blob
71+
72+
```js
73+
...
74+
const textBuffer = Buffer.from('Hello, World!');
75+
const stmt = "INSERT INTO teach (id, name, blobtext)VALUES( ?,?,?);";
76+
const values = [1,"test text", textBuffer];
77+
let ret: any = await db.run(stmt, values);
78+
console.log(`&&& res: ${JSON.stringify(ret)}`);
79+
80+
```

electron/src/GlobalSQLite.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export class GlobalSQLite {
2-
public secret: string = 'sqlite secret';
3-
public newsecret: string = 'sqlite new secret';
4-
}
2+
public secret = 'sqlite secret';
3+
public newsecret = 'sqlite new secret';
4+
}

electron/src/electron-utils/Database.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class Database {
3838
version: number,
3939
readonly: boolean,
4040
upgDict: Record<number, capSQLiteVersionUpgrade>,
41-
globalUtil?: GlobalSQLite
41+
globalUtil?: GlobalSQLite,
4242
) {
4343
this.dbName = dbName;
4444
this._encrypted = encrypted;
@@ -70,7 +70,7 @@ export class Database {
7070
*/
7171
async open(): Promise<void> {
7272
this._isDbOpen = false;
73-
let password = '';
73+
let password = '';
7474
try {
7575
if (
7676
this._encrypted &&

0 commit comments

Comments
 (0)