mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-06 17:54:20 +01:00
Merge 'Fix blob type handling in JavaScript' from Pekka Enberg
Closes #2732
This commit is contained in:
@@ -18,6 +18,10 @@ export function bindParams(stmt, params) {
|
||||
bindNamedParams(stmt, param);
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(param)) {
|
||||
bindPositionalParams(stmt, [param]);
|
||||
return;
|
||||
}
|
||||
bindValue(stmt, 1, param);
|
||||
return;
|
||||
}
|
||||
@@ -65,4 +69,4 @@ function bindPositionalParams(stmt, params) {
|
||||
|
||||
function bindValue(stmt, index, value) {
|
||||
stmt.bindAt(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,6 @@ impl Statement {
|
||||
let non_zero_idx = NonZeroUsize::new(index as usize).ok_or_else(|| {
|
||||
Error::new(Status::InvalidArg, "Parameter index must be greater than 0")
|
||||
})?;
|
||||
|
||||
let value_type = value.get_type()?;
|
||||
let turso_value = match value_type {
|
||||
ValueType::Null => turso_core::Value::Null,
|
||||
@@ -320,16 +319,22 @@ impl Statement {
|
||||
turso_core::Value::Integer(if b { 1 } else { 0 })
|
||||
}
|
||||
ValueType::Object => {
|
||||
// Try to cast as Buffer first, fallback to string conversion
|
||||
if let Ok(buffer) = unsafe { value.cast::<Buffer>() } {
|
||||
turso_core::Value::Blob(buffer.to_vec())
|
||||
let obj = value.coerce_to_object()?;
|
||||
|
||||
if obj.is_buffer()? || obj.is_typedarray()? {
|
||||
let length = obj.get_named_property::<u32>("length")?;
|
||||
let mut bytes = Vec::with_capacity(length as usize);
|
||||
for i in 0..length {
|
||||
let byte = obj.get_element::<u32>(i)?;
|
||||
bytes.push(byte as u8);
|
||||
}
|
||||
turso_core::Value::Blob(bytes)
|
||||
} else {
|
||||
let s = value.coerce_to_string()?.into_utf8()?;
|
||||
turso_core::Value::Text(s.as_str()?.to_owned().into())
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Fallback to string conversion for unknown types
|
||||
let s = value.coerce_to_string()?.into_utf8()?;
|
||||
turso_core::Value::Text(s.as_str()?.to_owned().into())
|
||||
}
|
||||
@@ -537,7 +542,10 @@ fn to_js_value<'a>(
|
||||
}
|
||||
turso_core::Value::Float(f) => ToNapiValue::into_unknown(*f, env),
|
||||
turso_core::Value::Text(s) => ToNapiValue::into_unknown(s.as_str(), env),
|
||||
turso_core::Value::Blob(b) => ToNapiValue::into_unknown(b, env),
|
||||
turso_core::Value::Blob(b) => {
|
||||
let buffer = Buffer::from(b.as_slice());
|
||||
ToNapiValue::into_unknown(buffer, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ export function decodeValue(value: Value, safeIntegers: boolean = false): any {
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
return Buffer.from(bytes);
|
||||
}
|
||||
return null;
|
||||
default:
|
||||
|
||||
@@ -290,6 +290,26 @@ test.serial("Statement.get() values", async (t) => {
|
||||
t.deepEqual(await stmt.get(9007199254740991n), [9007199254740991]);
|
||||
});
|
||||
|
||||
test.serial("Statement.get() [blob]", async (t) => {
|
||||
const db = t.context.db;
|
||||
|
||||
// Create table with blob column
|
||||
await db.exec("CREATE TABLE IF NOT EXISTS blobs (id INTEGER PRIMARY KEY, data BLOB)");
|
||||
|
||||
// Test inserting and retrieving blob data
|
||||
const binaryData = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64]); // "Hello World"
|
||||
const insertStmt = await db.prepare("INSERT INTO blobs (data) VALUES (?)");
|
||||
await insertStmt.run([binaryData]);
|
||||
|
||||
// Retrieve the blob data
|
||||
const selectStmt = await db.prepare("SELECT data FROM blobs WHERE id = 1");
|
||||
const result = await selectStmt.get();
|
||||
|
||||
t.truthy(result, "Should return a result");
|
||||
t.true(Buffer.isBuffer(result.data), "Should return Buffer for blob data");
|
||||
t.deepEqual(result.data, binaryData, "Blob data should match original");
|
||||
});
|
||||
|
||||
// ==========================================================================
|
||||
// Statement.iterate()
|
||||
// ==========================================================================
|
||||
|
||||
@@ -345,6 +345,26 @@ test.serial("Statement.get() values", async (t) => {
|
||||
t.deepEqual(stmt.get(9007199254740991n), [9007199254740991]);
|
||||
});
|
||||
|
||||
test.serial("Statement.get() [blob]", (t) => {
|
||||
const db = t.context.db;
|
||||
|
||||
// Create table with blob column
|
||||
db.exec("CREATE TABLE IF NOT EXISTS blobs (id INTEGER PRIMARY KEY, data BLOB)");
|
||||
|
||||
// Test inserting and retrieving blob data
|
||||
const binaryData = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64]); // "Hello World"
|
||||
const insertStmt = db.prepare("INSERT INTO blobs (data) VALUES (?)");
|
||||
insertStmt.run([binaryData]);
|
||||
|
||||
// Retrieve the blob data
|
||||
const selectStmt = db.prepare("SELECT data FROM blobs WHERE id = 1");
|
||||
const result = selectStmt.get();
|
||||
|
||||
t.truthy(result, "Should return a result");
|
||||
t.true(Buffer.isBuffer(result.data), "Should return Buffer for blob data");
|
||||
t.deepEqual(result.data, binaryData, "Blob data should match original");
|
||||
});
|
||||
|
||||
// ==========================================================================
|
||||
// Statement.iterate()
|
||||
// ==========================================================================
|
||||
|
||||
Reference in New Issue
Block a user