use core::ops::Deref;
use super::{column::Column, driver::codec::StatementCancel, prepare::Prepare, types::Type};
pub struct StatementGuarded<'a, C>
where
C: Prepare,
{
stmt: Option<Statement>,
cli: &'a C,
}
impl<C> AsRef<Statement> for StatementGuarded<'_, C>
where
C: Prepare,
{
#[inline]
fn as_ref(&self) -> &Statement {
self
}
}
impl<C> Deref for StatementGuarded<'_, C>
where
C: Prepare,
{
type Target = Statement;
fn deref(&self) -> &Self::Target {
self.stmt.as_ref().unwrap()
}
}
impl<C> Drop for StatementGuarded<'_, C>
where
C: Prepare,
{
fn drop(&mut self) {
if let Some(stmt) = self.stmt.take() {
let _ = self
.cli
._send_encode_query::<_, crate::ZeroParam>(StatementCancel { name: stmt.name() }, []);
}
}
}
impl<C> StatementGuarded<'_, C>
where
C: Prepare,
{
pub fn leak(mut self) -> Statement {
self.stmt.take().unwrap()
}
}
#[derive(Clone, Default)]
pub struct Statement {
name: Box<str>,
params: Box<[Type]>,
columns: Box<[Column]>,
}
impl Statement {
pub(crate) fn new(name: String, params: Vec<Type>, columns: Vec<Column>) -> Self {
Self {
name: name.into_boxed_str(),
params: params.into_boxed_slice(),
columns: columns.into_boxed_slice(),
}
}
pub(crate) fn name(&self) -> &str {
&self.name
}
pub fn unnamed<'a, C>(cli: &'a C, stmt: &'a str, types: &'a [Type]) -> StatementUnnamed<'a, C> {
StatementUnnamed { stmt, types, cli }
}
#[inline]
pub fn params(&self) -> &[Type] {
&self.params
}
#[inline]
pub fn columns(&self) -> &[Column] {
&self.columns
}
#[inline]
pub fn into_guarded<C>(self, cli: &C) -> StatementGuarded<C>
where
C: Prepare,
{
StatementGuarded { stmt: Some(self), cli }
}
}
pub struct StatementUnnamed<'a, C> {
pub(crate) stmt: &'a str,
pub(crate) types: &'a [Type],
pub(crate) cli: &'a C,
}
impl<C> Clone for StatementUnnamed<'_, C> {
fn clone(&self) -> Self {
*self
}
}
impl<C> Copy for StatementUnnamed<'_, C> {}
#[cfg(feature = "compat")]
pub(crate) mod compat {
use core::ops::Deref;
use std::sync::Arc;
use super::{Prepare, Statement, StatementCancel};
#[derive(Clone)]
pub struct StatementGuarded<C>
where
C: Prepare,
{
inner: Arc<_StatementGuarded<C>>,
}
struct _StatementGuarded<C>
where
C: Prepare,
{
stmt: Statement,
cli: C,
}
impl<C> Drop for _StatementGuarded<C>
where
C: Prepare,
{
fn drop(&mut self) {
let _ = self
.cli
._send_encode_query::<_, crate::ZeroParam>(StatementCancel { name: self.stmt.name() }, []);
}
}
impl<C> Deref for StatementGuarded<C>
where
C: Prepare,
{
type Target = Statement;
fn deref(&self) -> &Self::Target {
&self.inner.stmt
}
}
impl<C> AsRef<Statement> for StatementGuarded<C>
where
C: Prepare,
{
fn as_ref(&self) -> &Statement {
&self.inner.stmt
}
}
impl<C> StatementGuarded<C>
where
C: Prepare,
{
pub fn new(stmt: Statement, cli: C) -> Self {
Self {
inner: Arc::new(_StatementGuarded { stmt, cli }),
}
}
}
}