odbc_sys/
handles.rs

1use std::{ffi::c_void, ptr::null_mut};
2
3// ODBC handles are pointers to opaque C types. We do not know their memory layout or other details
4// of their implementation. This RFC suggest how to represent them in Rust:
5// <https://rust-lang.github.io/rfcs/1861-extern-types.html>
6//
7// Until this is stable we could choose to represent them like suggested in the nomicon:
8// <https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs>
9//
10// However, we know in the context of ODBC that we are always interested in the *mut versions of
11// this pointer. For now a strict alias around `*mut c_void` seems to be the most pragmatic
12// solution.
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15#[repr(transparent)]
16pub struct Handle(pub *mut c_void);
17
18impl Handle {
19    pub fn null() -> Self {
20        Self(null_mut())
21    }
22
23    pub fn as_henv(self) -> HEnv {
24        HEnv(self.0)
25    }
26
27    pub fn as_hdbc(self) -> HDbc {
28        HDbc(self.0)
29    }
30
31    pub fn as_hstmt(self) -> HStmt {
32        HStmt(self.0)
33    }
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37#[repr(transparent)]
38pub struct HEnv(pub *mut c_void);
39
40impl HEnv {
41    pub fn null() -> Self {
42        Self(null_mut())
43    }
44
45    pub fn as_handle(self) -> Handle {
46        Handle(self.0)
47    }
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51#[repr(transparent)]
52pub struct HDesc(pub *mut c_void);
53
54/// The connection handle references storage of all information about the connection to the data
55/// source, including status, transaction state, and error information.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[repr(transparent)]
58pub struct HDbc(pub *mut c_void);
59
60impl HDbc {
61    pub fn as_handle(self) -> Handle {
62        Handle(self.0)
63    }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67#[repr(transparent)]
68pub struct HStmt(pub *mut c_void);
69
70impl HStmt {
71    pub fn as_handle(self) -> Handle {
72        Handle(self.0)
73    }
74}
75
76// Handles are `Send` according to ODBC spec, since they must be able to be used from different
77// threads. They even must protect their inner state. This would also make them `Sync`, yet they do
78// have interior mutability for error handling.
79// See: <https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/multithreading>
80
81unsafe impl Send for HEnv {}
82
83unsafe impl Send for HDbc {}
84
85unsafe impl Send for HStmt {}