odbc_api/handles/
statement_connection.rs

1use odbc_sys::{HStmt, Handle, HandleType};
2
3use crate::handles::{AnyHandle, AsStatementRef, Statement, StatementRef, drop_handle};
4
5/// Statement handle which also takes ownership of Connection
6#[derive(Debug)]
7pub struct StatementConnection<C> {
8    handle: HStmt,
9    /// We do not do anything with the parent, besides keeping it alive.
10    _parent: C,
11}
12
13impl<C> StatementConnection<C>
14where
15    C: StatementParent,
16{
17    /// # Safety
18    ///
19    /// Handle must be a valid statement handle and the parent connection must be valid for the
20    /// lifetime of parent.
21    pub(crate) unsafe fn new(handle: HStmt, parent: C) -> Self {
22        Self {
23            _parent: parent,
24            handle,
25        }
26    }
27
28    pub fn as_stmt_ref(&mut self) -> StatementRef<'_> {
29        unsafe { StatementRef::new(self.handle) }
30    }
31}
32
33impl<C> Drop for StatementConnection<C> {
34    fn drop(&mut self) {
35        unsafe {
36            drop_handle(self.handle.as_handle(), HandleType::Stmt);
37        }
38    }
39}
40
41/// Implementers of this trait are guaranteed to keep a connection alive and in connected state for
42/// the lifetime of the instance.
43///
44/// E.g. [`super::Connection`] is not a [`StatementParent`], since it is not guaranteed to keep the
45/// connection alive. Nor would it close the connection at the end of the lifetime on Drop.
46///
47/// # Safety
48///
49/// Instance must keep the connection it owns alive and open.
50pub unsafe trait StatementParent {}
51
52/// According to the ODBC documentation this is safe. See:
53/// <https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/multithreading>
54///
55/// Operations to a statement imply that interior state of the connection might be mutated,
56/// depending on the implementation detail of the ODBC driver. According to the ODBC documentation
57/// this could always be considered save.
58unsafe impl<C> Send for StatementConnection<C> where C: StatementParent {}
59
60unsafe impl<C> AnyHandle for StatementConnection<C>
61where
62    C: StatementParent,
63{
64    fn as_handle(&self) -> Handle {
65        self.handle.as_handle()
66    }
67
68    fn handle_type(&self) -> HandleType {
69        HandleType::Stmt
70    }
71}
72
73impl<C> Statement for StatementConnection<C>
74where
75    C: StatementParent,
76{
77    fn as_sys(&self) -> HStmt {
78        self.handle
79    }
80}
81
82impl<C> AsStatementRef for StatementConnection<C>
83where
84    C: StatementParent,
85{
86    fn as_stmt_ref(&mut self) -> StatementRef<'_> {
87        self.as_stmt_ref()
88    }
89}