use crate::{Result, ToSql};
use crate::oci::{SqlType, OCIStmt, OCIError};
use crate::stmt::Params;
pub struct Nvl<T>(Option<T>) where T: ToSql + SqlType;
impl<T> Nvl<T> where T: ToSql + SqlType {
pub const fn new(value: T) -> Self {
Self(Some(value))
}
pub const fn as_ref(&self) -> Option<&T> {
self.0.as_ref()
}
pub fn as_mut(&mut self) -> Option<&mut T> {
self.0.as_mut()
}
pub fn insert(&mut self, value: T) -> &mut T {
self.0.insert(value)
}
pub fn replace(&mut self, value: T) -> Option<T> {
self.0.replace(value)
}
}
impl<T> ToSql for Nvl<T> where T: ToSql + SqlType {
fn bind_to(&mut self, pos: usize, params: &mut Params, stmt: &OCIStmt, err: &OCIError) -> Result<usize> {
params.bind_null(pos, T::sql_null_type(), stmt, err)?;
Ok(pos + 1)
}
}
impl<T> ToSql for &Nvl<T> where T: ToSql + SqlType {
fn bind_to(&mut self, pos: usize, params: &mut Params, stmt: &OCIStmt, err: &OCIError) -> Result<usize> {
params.bind_null(pos, T::sql_null_type(), stmt, err)?;
Ok(pos + 1)
}
}
impl<T> ToSql for &mut Nvl<T> where T: ToSql + SqlType {
fn bind_to(&mut self, pos: usize, params: &mut Params, stmt: &OCIStmt, err: &OCIError) -> Result<usize> {
if let Some(val) = self.as_mut() {
let next_pos = val.bind_to(pos, params, stmt, err)?;
params.mark_as_null(pos);
Ok(next_pos)
} else {
params.bind_null(pos, T::sql_null_type(), stmt, err)?;
Ok(pos + 1)
}
}
fn update_from_bind(&mut self, pos: usize, params: &Params) -> Result<usize> {
if params.is_null(pos)? {
self.0.take();
Ok(pos + 1)
} else if let Some(val) = self.as_mut() {
val.update_from_bind(pos, params)
} else {
Ok(pos + 1)
}
}
}