mirror of
https://github.com/fluencelabs/fluid
synced 2025-04-29 08:42:16 +00:00
Sync step3
This commit is contained in:
parent
391e9b1d34
commit
b54b030698
@ -4,27 +4,35 @@ use crate::api::AppResult;
|
|||||||
use crate::errors::err_msg;
|
use crate::errors::err_msg;
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
|
|
||||||
|
// Execute query on SQLite
|
||||||
pub fn query(query: String) -> AppResult<String> {
|
pub fn query(query: String) -> AppResult<String> {
|
||||||
log::debug!("executing query: '{}'", query);
|
log::debug!("executing query: '{}'", query);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let bytes = query.as_bytes();
|
// Convert query string to bytes
|
||||||
let query_ptr = ffi::allocate(bytes.len());
|
let query_bytes = query.as_bytes();
|
||||||
|
// Allocate memory for query in SQLite module
|
||||||
|
let query_ptr = ffi::allocate(query_bytes.len());
|
||||||
|
|
||||||
for (i, byte) in bytes.iter().enumerate() {
|
// Store query in SQLite's memory
|
||||||
|
for (i, byte) in query_bytes.iter().enumerate() {
|
||||||
let ptr = query_ptr + i as i32;
|
let ptr = query_ptr + i as i32;
|
||||||
ffi::store(ptr, *byte);
|
ffi::store(ptr, *byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result_ptr = ffi::invoke(query_ptr, bytes.len());
|
// Execute the query, and get pointer to the result
|
||||||
|
let result_ptr = ffi::invoke(query_ptr, query_bytes.len());
|
||||||
|
|
||||||
|
// First 4 bytes at result_ptr location encode result size, read that first
|
||||||
let mut result_size: usize = 0;
|
let mut result_size: usize = 0;
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
let ptr = result_ptr + i as i32;
|
let ptr = result_ptr + i as i32;
|
||||||
let b = ffi::load(ptr) as usize;
|
let b = ffi::load(ptr) as usize;
|
||||||
result_size = result_size + (b << (8 * i));
|
result_size = result_size + (b << (8 * i));
|
||||||
}
|
}
|
||||||
|
// Now we know exact size of the query execution result
|
||||||
|
|
||||||
|
// Read query execution result byte-by-byte
|
||||||
let mut result_bytes = vec![0; result_size as usize];
|
let mut result_bytes = vec![0; result_size as usize];
|
||||||
for i in 4..(result_size + 4) {
|
for i in 4..(result_size + 4) {
|
||||||
let ptr = result_ptr + i as i32;
|
let ptr = result_ptr + i as i32;
|
||||||
@ -32,11 +40,17 @@ pub fn query(query: String) -> AppResult<String> {
|
|||||||
result_bytes[i as usize - 4] = b;
|
result_bytes[i as usize - 4] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deallocate query result
|
||||||
|
ffi::deallocate(result_ptr, result_size + 4);
|
||||||
|
|
||||||
|
// Decode query result to a utf8 string
|
||||||
let result_str = std::str::from_utf8(result_bytes.as_slice());
|
let result_str = std::str::from_utf8(result_bytes.as_slice());
|
||||||
|
|
||||||
|
// Log if there's an error
|
||||||
if result_str.is_err() {
|
if result_str.is_err() {
|
||||||
log::error!("unable to decode result from bytes: {:#x?}", result_bytes);
|
log::error!("unable to decode result from bytes: {:#x?}", result_bytes);
|
||||||
}
|
}
|
||||||
|
// Wrap error with a better message, and return Result
|
||||||
result_str
|
result_str
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
err_msg(&format!(
|
err_msg(&format!(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user