use error::{ErrorKind, Result};
use lob::Lob;
use object::Object;
use odpi::externs;
use odpi::opaque::ODPIVar;
use odpi::structs::ODPIData;
use rowid::Rowid;
use statement::Statement;
use std::convert::TryFrom;
use std::{ptr, slice};
use util::ODPIStr;
pub struct Var {
inner: *mut ODPIVar,
}
impl Var {
#[doc(hidden)]
pub fn inner(&self) -> *mut ODPIVar {
self.inner
}
pub fn copy_data(&self, src_pos: u32, dst: &mut Self, dst_pos: u32) -> Result<()> {
try_dpi!(
externs::dpiVar_copyData(dst.inner(), dst_pos, self.inner, src_pos),
Ok(()),
ErrorKind::Var("dpiVar_copyData".to_string())
)
}
pub fn get_data(&self) -> Result<&mut [ODPIData]> {
let mut num_elements = 0;
let mut data_arr_ptr = ptr::null_mut();
try_dpi!(
externs::dpiVar_getData(self.inner, &mut num_elements, &mut data_arr_ptr),
{
if data_arr_ptr.is_null() || num_elements == 0 {
Ok(&mut [])
} else {
Ok(unsafe { slice::from_raw_parts_mut(data_arr_ptr, num_elements as usize) })
}
},
ErrorKind::Var("dpiVar_getData".to_string())
)
}
pub fn get_num_elements_in_array(&self) -> Result<u32> {
let mut num_elements = 0;
try_dpi!(
externs::dpiVar_getNumElementsInArray(self.inner, &mut num_elements),
Ok(num_elements),
ErrorKind::Var("dpiVar_getNumElementsInArray".to_string())
)
}
pub fn get_size_in_bytes(&self) -> Result<u32> {
let mut size = 0;
try_dpi!(
externs::dpiVar_getSizeInBytes(self.inner, &mut size),
Ok(size),
ErrorKind::Var("dpiVar_getSizeInBytes".to_string())
)
}
pub fn set_from_bytes(&self, pos: u32, value: &str) -> Result<()> {
let value_s: ODPIStr = TryFrom::try_from(value)?;
try_dpi!(
externs::dpiVar_setFromBytes(self.inner, pos, value_s.ptr(), value_s.len()),
Ok(()),
ErrorKind::Var("dpiVar_setFromBytes".to_string())
)
}
pub fn set_from_lob(&self, pos: u32, lob: &Lob) -> Result<()> {
try_dpi!(
externs::dpiVar_setFromLob(self.inner, pos, lob.inner()),
Ok(()),
ErrorKind::Var("dpiVar_setFromLob".to_string())
)
}
pub fn set_from_object(&self, pos: u32, obj: &Object) -> Result<()> {
try_dpi!(
externs::dpiVar_setFromObject(self.inner, pos, obj.inner()),
Ok(()),
ErrorKind::Var("dpiVar_setFromObject".to_string())
)
}
pub fn set_from_rowid(&self, pos: u32, rowid: &Rowid) -> Result<()> {
try_dpi!(
externs::dpiVar_setFromRowid(self.inner, pos, rowid.inner()),
Ok(()),
ErrorKind::Var("dpiVar_setFromRowid".to_string())
)
}
pub fn set_from_stmt(&self, pos: u32, stmt: &Statement) -> Result<()> {
try_dpi!(
externs::dpiVar_setFromStmt(self.inner, pos, stmt.inner()),
Ok(()),
ErrorKind::Var("dpiVar_setFromStmt".to_string())
)
}
pub fn set_num_elements_in_array(&self, num_elements: u32) -> Result<()> {
try_dpi!(
externs::dpiVar_setNumElementsInArray(self.inner, num_elements),
Ok(()),
ErrorKind::Var("dpiVar_setNumElementsInArray".to_string())
)
}
}
impl From<*mut ODPIVar> for Var {
fn from(inner: *mut ODPIVar) -> Self {
Self { inner }
}
}
impl Drop for Var {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe {
externs::dpiVar_release(self.inner);
}
}
}
}