2019-08-14 13:31:26 +03:00
|
|
|
use fluence::sdk::*;
|
|
|
|
use log::info;
|
|
|
|
|
|
|
|
fn init() {
|
|
|
|
logger::WasmLogger::init_with_level(log::Level::Info).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[invocation_handler(init_fn = init)]
|
2019-08-14 20:19:39 +03:00
|
|
|
fn run(arg: String) -> String {
|
|
|
|
query(arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn query(query: String) -> String {
|
|
|
|
info!("executing query: '{}'", query);
|
2019-08-14 13:31:26 +03:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let bytes = query.as_bytes();
|
2019-08-14 13:46:14 +03:00
|
|
|
let query_ptr = ffi::allocate(bytes.len());
|
2019-08-14 14:02:22 +03:00
|
|
|
|
2019-08-14 13:31:26 +03:00
|
|
|
for (i, byte) in bytes.iter().enumerate() {
|
2019-08-14 14:12:22 +03:00
|
|
|
let ptr = query_ptr + i as i32;
|
2019-08-14 13:46:14 +03:00
|
|
|
ffi::store(ptr, *byte);
|
2019-08-14 13:31:26 +03:00
|
|
|
}
|
|
|
|
|
2019-08-14 13:46:14 +03:00
|
|
|
let result_ptr = ffi::invoke(query_ptr, bytes.len());
|
2019-08-14 13:31:26 +03:00
|
|
|
|
|
|
|
let mut result_size = 0;
|
2019-08-14 13:43:17 +03:00
|
|
|
for i in 0u8..4u8 {
|
2019-08-14 14:12:22 +03:00
|
|
|
let ptr = result_ptr + i as i32;
|
2019-08-14 13:46:14 +03:00
|
|
|
let b = ffi::load(ptr);
|
2019-08-14 13:31:26 +03:00
|
|
|
result_size = result_size | (b >> 8*i)
|
|
|
|
}
|
|
|
|
|
2019-08-14 13:43:17 +03:00
|
|
|
let mut result_bytes = vec![0; result_size as usize];
|
2019-08-14 20:19:39 +03:00
|
|
|
for i in 4u8..result_size {
|
2019-08-14 14:12:22 +03:00
|
|
|
let ptr = result_ptr + i as i32;
|
2019-08-14 13:46:14 +03:00
|
|
|
let b = ffi::load(ptr);
|
2019-08-14 20:19:39 +03:00
|
|
|
result_bytes[i as usize - 4] = b;
|
2019-08-14 13:31:26 +03:00
|
|
|
}
|
|
|
|
|
2019-08-14 13:43:17 +03:00
|
|
|
let result_str = std::str::from_utf8(result_bytes.as_slice());
|
2019-08-14 13:31:26 +03:00
|
|
|
if result_str.is_err() {
|
2019-08-14 13:43:17 +03:00
|
|
|
info!("unable to decode result from result_bytes: {:?}", result_bytes);
|
2019-08-14 13:31:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
result_str.expect("unable to decode result").to_string()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-14 13:46:14 +03:00
|
|
|
pub mod ffi {
|
|
|
|
#[link(wasm_import_module = "sqlite")]
|
|
|
|
extern "C" {
|
2019-08-14 20:19:39 +03:00
|
|
|
#[link_name="sqlite_allocate"]
|
2019-08-14 13:46:14 +03:00
|
|
|
pub fn allocate(size: usize) -> i32;
|
2019-08-14 20:19:39 +03:00
|
|
|
#[link_name="sqlite_deallocate"]
|
2019-08-14 13:46:14 +03:00
|
|
|
pub fn deallocate(ptr: i32, size: usize);
|
2019-08-14 20:19:39 +03:00
|
|
|
#[link_name="sqlite_invoke"]
|
2019-08-14 13:46:14 +03:00
|
|
|
pub fn invoke(ptr: i32, size: usize) -> i32;
|
2019-08-14 20:19:39 +03:00
|
|
|
#[link_name="sqlite_store"]
|
2019-08-14 13:54:40 +03:00
|
|
|
pub fn store(ptr: i32, byte: u8);
|
2019-08-14 20:19:39 +03:00
|
|
|
#[link_name="sqlite_load"]
|
2019-08-14 13:54:40 +03:00
|
|
|
pub fn load(ptr: i32) -> u8;
|
2019-08-14 13:46:14 +03:00
|
|
|
}
|
2019-08-14 13:31:26 +03:00
|
|
|
}
|