#![cfg(any(feature = "picodata", doc))]
use crate::error::TarantoolError;
use crate::ffi;
use crate::ffi::sql::ObufWrapper;
use serde::Serialize;
use std::io::Read;
use std::os::raw::c_char;
use std::str;
pub fn calculate_hash(sql: &str) -> u32 {
unsafe { ffi::sql::sql_stmt_calculate_id(sql.as_ptr() as *const c_char, sql.len()) }
}
pub fn prepare_and_execute_raw<IN>(
query: &str,
bind_params: &IN,
vdbe_max_steps: u64,
) -> crate::Result<impl Read>
where
IN: Serialize,
{
let mut buf = ObufWrapper::new(1024);
let mut param_data = vec![0x90];
if std::mem::size_of::<IN>() != 0 {
param_data = rmp_serde::to_vec(bind_params)?;
debug_assert!(crate::msgpack::skip_value(&mut std::io::Cursor::new(¶m_data)).is_ok());
}
let param_ptr = param_data.as_ptr() as *const u8;
let execute_result = unsafe {
ffi::sql::sql_prepare_and_execute_ext(
query.as_ptr() as *const u8,
query.len() as i32,
param_ptr,
vdbe_max_steps,
buf.obuf(),
)
};
if execute_result < 0 {
return Err(TarantoolError::last().into());
}
Ok(buf)
}
pub fn prepare(query: String) -> crate::Result<Statement> {
let mut stmt_id: u32 = 0;
if unsafe {
ffi::sql::sql_prepare_ext(query.as_ptr(), query.len() as u32, &mut stmt_id as *mut u32)
} < 0
{
return Err(TarantoolError::last().into());
}
Ok(Statement { query, id: stmt_id })
}
pub fn unprepare(stmt: Statement) {
unsafe {
ffi::sql::sql_unprepare(stmt.id);
}
}
#[derive(Default, Debug)]
pub struct Statement {
query: String,
id: u32,
}
impl Statement {
pub fn source(&self) -> &str {
self.query.as_str()
}
pub fn id(&self) -> u32 {
self.id
}
pub fn execute_raw<IN>(&self, bind_params: &IN, vdbe_max_steps: u64) -> crate::Result<impl Read>
where
IN: Serialize,
{
let mut buf = ObufWrapper::new(1024);
let mut param_data = vec![0x90];
if std::mem::size_of::<IN>() != 0 {
param_data = rmp_serde::to_vec(bind_params)?;
debug_assert!(
crate::msgpack::skip_value(&mut std::io::Cursor::new(¶m_data)).is_ok()
);
}
let param_ptr = param_data.as_ptr() as *const u8;
let execute_result = unsafe {
ffi::sql::sql_execute_prepared_ext(self.id, param_ptr, vdbe_max_steps, buf.obuf())
};
if execute_result < 0 {
return Err(TarantoolError::last().into());
}
Ok(buf)
}
}