plugins-workspace icon indicating copy to clipboard operation
plugins-workspace copied to clipboard

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

Open joakim opened this issue 2 years ago • 3 comments

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?

joakim avatar Jan 23 '23 20:01 joakim

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

FabianLars avatar Jan 30 '23 17:01 FabianLars

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 :)

joakim avatar Jan 30 '23 20:01 joakim

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)

patrick91 avatar Feb 13 '24 13:02 patrick91