tauri-apps / plugins-workspace

All of the official Tauri plugins in one place!
https://tauri.app
Apache License 2.0
862 stars 242 forks source link

[sql] Can't save binary data with `execute` (SQLite) #105

Open joakim opened 1 year ago

joakim commented 1 year ago

First of all, thanks for your work on Tauri and essential plugins like this one!

I'm having trouble inserting Uint8Array data into BLOB columns in SQLite. Instead of being inserted as binary data, it's inserted as a stringified JSON object.

My main use case is a uuid column storing the 128-bit binary representation of a UUID.

CREATE TABLE node (
    uuid BLOB PRIMARY KEY
    -- ...
)
const uuid = new Uint8Array(16)  // this would be a generated 128-bit UUID
const result = await db.execute('INSERT INTO node (uuid) VALUES ($1)', [uuid])

What's inserted into node.uuid:

'{"0":0,"1":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}'

If I instead save the ArrayBuffer itself, I get an empty object:

const uuid = new Uint8Array(16).buffer  // its underlying ArrayBuffer
const result = await db.execute('INSERT INTO node (uuid) VALUES ($1)', [uuid])
'{}'

Am I doing something wrong, or does the binary data simply not survive serialization when sent from JS to Rust?

If it's the latter, maybe serde_binary can be of help?

FabianLars commented 1 year ago

uint8array is not an actual array but just a plain JS object which the ipc converts to a json object. what's been necessary so far (and used for the core writeBinaryFile api for examples, is to convert it to an actual array before sending it back -> Array.from(uuid)

so i guess we should at that to the plugin too

joakim commented 1 year ago

Yes, I think the API should support TypedArrays too for representing binary data.

As long it's saved as binary data and returned as binary data by sqlx, Array.from sounds good :)

patrick91 commented 7 months ago

I have this working using something like:

      Object.values(JSON.parse(snapshotTextFromDb))

but I wonder if we should not use JSON to send data to Rust, if I understood correct the new IPC system in Tauri 2 supports sending binary data, should we switch to that?

My issue at the moment is that I'm sending a ~200kb binary document and it's quite slow (and it's also hanging the main thread)