odbc_safe/handles/
henv.rs

1use super::{Handle, OutputBuffer, Return, ReturnOption};
2use sys::*;
3use std::ptr::null_mut;
4use std::thread::panicking;
5
6/// An `Environment` is a global context, in which to access data.
7///
8/// Associated with an `Environment` is any information that is global in nature, such as:
9///
10/// * The `Environment`'s state
11/// * The current environment-level diagnostics
12/// * The handles of connections currently allocated on the environment
13/// * The current stetting of each environment attribute
14#[derive(Debug)]
15pub struct HEnv {
16    /// Invariant: Should always point to a valid ODBC Environment
17    handle: SQLHENV,
18}
19
20impl Drop for HEnv {
21    fn drop(&mut self) {
22        unsafe {
23            match SQLFreeHandle(SQL_HANDLE_ENV, self.handle as SQLHANDLE) {
24                SQL_SUCCESS => (),
25                other => {
26                    if !panicking() {
27                        panic!("Unexepected return value of SQLFreeHandle: {:?}", other)
28                    }
29                }
30            }
31        }
32    }
33}
34
35unsafe impl Handle for HEnv {
36    const HANDLE_TYPE: HandleType = SQL_HANDLE_ENV;
37
38    fn handle(&self) -> SQLHANDLE {
39        self.handle as SQLHANDLE
40    }
41}
42
43impl HEnv {
44    /// Allocates a new Environment Handle
45    pub fn allocate() -> Return<HEnv> {
46        let mut out = null_mut();
47        unsafe {
48            let result: Return<()> = SQLAllocHandle(SQL_HANDLE_ENV, null_mut(), &mut out).into();
49            result.map(|()| {
50                HEnv {
51                    handle: out as SQLHENV,
52                }
53            })
54        }
55    }
56
57    pub fn declare_version(&mut self, version: OdbcVersion) -> Return<()> {
58        unsafe { SQLSetEnvAttr(self.handle, SQL_ATTR_ODBC_VERSION, version.into(), 0).into() }
59    }
60
61    /// Fills buffers and returns `(name_length, description_length)`
62    pub fn data_sources(
63        &mut self,
64        direction: FetchOrientation,
65        server_name: &mut [u8],
66        description: &mut [u8],
67    ) -> ReturnOption<(SQLSMALLINT, SQLSMALLINT)> {
68        unsafe {
69            let mut name_length = 0;
70            let mut description_length = 0;
71            let ret: ReturnOption<()> = SQLDataSources(
72                self.handle,
73                direction,
74                server_name.mut_buf_ptr(),
75                server_name.buf_len(),
76                &mut name_length,
77                description.mut_buf_ptr(),
78                description.buf_len(),
79                &mut description_length,
80            ).into();
81            ret.map(|()| (name_length, description_length))
82        }
83    }
84
85    /// Fills buffers and returns `(description_length, attributes_length)`
86    pub fn drivers(
87        &mut self,
88        direction: FetchOrientation,
89        description: &mut [u8],
90        attributes: &mut [u8],
91    ) -> ReturnOption<(SQLSMALLINT, SQLSMALLINT)> {
92        unsafe {
93            let mut description_length = 0;
94            let mut attributes_length = 0;
95            let ret: ReturnOption<()> = SQLDrivers(
96                self.handle,
97                direction,
98                description.mut_buf_ptr(),
99                description.buf_len(),
100                &mut description_length,
101                attributes.mut_buf_ptr(),
102                attributes.buf_len(),
103                &mut attributes_length,
104            ).into();
105            ret.map(|()| (description_length, attributes_length))
106        }
107    }
108
109    /// Provides access to the raw ODBC environment handle.
110    pub fn as_raw(&self) -> SQLHENV {
111        self.handle
112    }
113}