use alloc::string::String;
use alloc::vec::Vec;
use myrmic_common::db::{
Cursor, Scope, TbAppendRequest, TbCountRequest, TbCountResponse, TbDeleteRequest, TbGetRequest,
TbGetResponse, TbInsertRequest, TbInsertResponse, TbListRequest, TbListResponse, TbOrderBy,
};
use crate::error::ErrorCode;
use crate::{ApiError, ApiResult};
mod c_functions {
use core::ffi::c_int;
#[link(wasm_import_module = "db")]
unsafe extern "C" {
pub(super) fn tb_insert(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
pub(super) fn tb_count(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
pub(super) fn tb_get(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
pub(super) fn tb_list(
buffer_req: *const u8,
len_req: c_int,
buffer_rsp: *mut u8,
len_rsp: c_int,
) -> c_int;
pub(super) fn tb_delete(buffer_req: *const u8, len_req: c_int) -> c_int;
pub(super) fn tb_append(buffer_req: *const u8, len_req: c_int) -> c_int;
}
}
pub fn tb_insert(
scope: Scope,
table: String,
eid: Option<Vec<u8>>,
value: Vec<u8>,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<Vec<u8>> {
let request = TbInsertRequest {
scope,
table,
eid,
value,
};
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing table insert request"))?
.len();
unsafe {
c_functions::tb_insert(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<TbInsertResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing table insert response"))?;
Ok(response.eid)
}
pub fn tb_count(
scope: Scope,
table: String,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<usize> {
let request = TbCountRequest { scope, table };
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing table count request"))?
.len();
unsafe {
c_functions::tb_count(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<TbCountResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing table count response"))?;
Ok(response.count)
}
pub fn tb_get(
scope: Scope,
table: String,
eid: Vec<u8>,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<Option<Vec<u8>>> {
let request = TbGetRequest { scope, table, eid };
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing table get request"))?
.len();
unsafe {
c_functions::tb_get(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<TbGetResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing table get response"))?;
Ok(response.value)
}
#[allow(clippy::too_many_arguments)]
pub fn tb_list(
scope: Scope,
table: String,
cursor: Option<Cursor>,
limit: Option<usize>,
order: Option<TbOrderBy>,
request_buffer: &mut [u8],
response_buffer: &mut [u8],
) -> ApiResult<Vec<(Vec<u8>, Vec<u8>)>> {
let request = TbListRequest {
scope,
table,
cursor,
limit,
order,
};
let payload_len = postcard::to_slice(&request, request_buffer)
.map_err(|_e| ApiError::Serde("serializing table list request"))?
.len();
unsafe {
c_functions::tb_list(
request_buffer.as_ptr(),
payload_len as i32,
response_buffer.as_mut_ptr(),
response_buffer.len() as i32,
)
}
.to_result()?;
let response = postcard::from_bytes::<TbListResponse>(response_buffer)
.map_err(|_e| ApiError::Serde("deserializing table list response"))?;
Ok(response.entities)
}
pub fn tb_append(
scope: Scope,
table: String,
eid: Option<Vec<u8>>,
value: Vec<u8>,
buffer: &mut [u8],
) -> ApiResult<()> {
let request = TbAppendRequest {
scope,
table,
eid,
value,
};
let payload_len = postcard::to_slice(&request, buffer)
.map_err(|_e| ApiError::Serde("serializing table append request"))?
.len();
unsafe { c_functions::tb_append(buffer.as_ptr(), payload_len as i32) }.to_result()
}
pub fn tb_delete(scope: Scope, table: String, eid: Vec<u8>, buffer: &mut [u8]) -> ApiResult<()> {
let request = TbDeleteRequest { scope, table, eid };
let payload_len = postcard::to_slice(&request, buffer)
.map_err(|_e| ApiError::Serde("serializing table delete request"))?
.len();
unsafe { c_functions::tb_delete(buffer.as_ptr(), payload_len as i32) }.to_result()
}