Skip to main content

odbc_safe/data_source/
connected.rs

1use super::*;
2use std::mem::forget;
3use std::ops::Deref;
4use std::ptr;
5use std::thread::panicking;
6use std::marker::PhantomData;
7
8/// State used by `Connected`. Means that autocommit is enabled
9#[derive(Debug)]
10#[allow(missing_copy_implementations)]
11pub enum AutocommitOn {}
12
13/// State used by `Connected`. Means that autocommit is disabled
14#[derive(Debug)]
15#[allow(missing_copy_implementations)]
16pub enum AutocommitOff {}
17
18/// Marker trait for autocommit mode state types
19pub trait AutocommitMode {}
20
21impl AutocommitMode for AutocommitOn {}
22impl AutocommitMode for AutocommitOff {}
23
24/// An `HDbc` with the additional invariant of being 'connected'.
25#[derive(Debug)]
26pub struct Connected<'env, AC: AutocommitMode>(HDbc<'env>, PhantomData<AC>);
27
28impl<'env, AC: AutocommitMode> Drop for Connected<'env, AC> {
29    fn drop(&mut self) {
30        match self.0.disconnect() {
31            Success(()) | Info(()) => (),
32            Error(()) => if !panicking() {
33                panic!("SQLDisconnect returned error")
34            },
35        }
36    }
37}
38
39impl<'env, AC: AutocommitMode> Connected<'env, AC> {
40    /// Releases inner Connection Handle without calling disconnect.
41    pub fn into_hdbc(self) -> HDbc<'env> {
42        unsafe {
43            let hdbc = ptr::read(&self.0);
44            forget(self); // do not call drop
45            hdbc
46        }
47    }
48}
49
50impl<'env, AC: AutocommitMode> Deref for Connected<'env, AC> {
51    type Target = HDbc<'env>;
52    fn deref(&self) -> &Self::Target {
53        &self.0
54    }
55}
56
57impl<'env, AC: AutocommitMode> DerefMut for Connected<'env, AC> {
58    fn deref_mut(&mut self) -> &mut Self::Target {
59        &mut self.0
60    }
61}
62
63impl<'env, AC: AutocommitMode> HDbcWrapper<'env> for Connected<'env, AC> {
64    type Handle = Connected<'env, AC>;
65
66    fn into_hdbc(self) -> HDbc<'env> {
67        self.into_hdbc()
68    }
69
70    fn from_hdbc(hdbc: HDbc<'env>) -> Self::Handle {
71        Connected(hdbc, PhantomData)
72    }
73}