Skip to main content

odbc_sys/
lib.rs

1//! ODBC types those representation is compatible with the ODBC C API.
2//!
3//! This layer has not been created using automatic code generation. It is incomplete, i.e. it does
4//! not contain every symbol or constant defined in the ODBC C headers. Symbols which are
5//! deprecated since ODBC 3 have been left out intentionally. While some extra type safety has been
6//! added by grouping some of C's `#define` constants into `enum`-types it mostly offers the same
7//! power (all) and safety guarantess(none) as the wrapped C-API.
8//! ODBC 4.0 is still under development by Microsoft, so these symbols are deactivated by default
9//! in the cargo.toml
10
11mod attributes;
12mod bulk_operation;
13mod c_data_type;
14mod connection_attribute;
15mod desc;
16mod fetch_orientation;
17mod functions;
18mod handles;
19mod indicator;
20mod info_type;
21mod interval;
22mod nullability;
23mod param_type;
24mod set_pos;
25mod sql_data_type;
26mod sqlreturn;
27
28pub use self::{
29    attributes::{
30        AttrConnectionPooling, AttrCpMatch, AttrOdbcVersion, EnvironmentAttribute,
31        StatementAttribute,
32    },
33    bulk_operation::BulkOperation,
34    c_data_type::*,
35    connection_attribute::ConnectionAttribute,
36    desc::Desc,
37    fetch_orientation::FetchOrientation,
38    functions::*,
39    handles::{HDbc, HDesc, HEnv, HStmt, Handle},
40    indicator::{len_data_at_exec, DATA_AT_EXEC, NO_TOTAL, NULL_DATA},
41    info_type::InfoType,
42    interval::Interval,
43    nullability::Nullability,
44    param_type::ParamType,
45    set_pos::{Lock, Operation},
46    sql_data_type::SqlDataType,
47    sqlreturn::SqlReturn,
48};
49use std::os::raw::{c_int, c_void};
50
51pub type Pointer = *mut c_void;
52pub type Char = u8;
53pub type SChar = i8;
54pub type WChar = u16;
55
56pub type Len = isize;
57pub type ULen = usize;
58pub type HWnd = Pointer;
59pub type RetCode = i16;
60
61/// Row index parameter for [`crate::SQLSetPos`]
62#[cfg(target_pointer_width = "64")]
63pub type SetPosIRow = u64;
64/// Row index parameter for [`crate::SQLSetPos`]
65#[cfg(not(target_pointer_width = "64"))]
66pub type SetPosIRow = i16;
67
68// flags for null-terminated string
69pub const NTS: isize = -3;
70pub const NTSL: isize = -3;
71
72/// Maximum message length
73pub const MAX_MESSAGE_LENGTH: i16 = 512;
74pub const SQLSTATE_SIZE: usize = 5;
75pub const SQLSTATE_SIZEW: usize = 10;
76
77/// SQL Free Statement options
78#[repr(u16)]
79#[derive(Debug, PartialEq, Eq, Clone, Copy)]
80pub enum FreeStmtOption {
81    /// Closes the cursor associated with StatementHandle (if one was defined) and discards all
82    /// pending results. The application can reopen this cursor later by executing a SELECT
83    /// statement again with the same or different parameter values. If no cursor is open, this
84    /// option has no effect for the application. `SQLCloseCursor` can also be called to close a
85    /// cursor.
86    Close = 0,
87    // SQL_DROP = 1, is deprecated in favour of SQLFreeHandle
88    /// Sets the `SQL_DESC_COUNT` field of the ARD to 0, releasing all column buffers bound by
89    /// `SQLBindCol` for the given StatementHandle. This does not unbind the bookmark column; to do
90    /// that, the `SQL_DESC_DATA_PTR` field of the ARD for the bookmark column is set to NULL.
91    /// Notice that if this operation is performed on an explicitly allocated descriptor that is
92    /// shared by more than one statement, the operation will affect the bindings of all statements
93    /// that share the descriptor.
94    Unbind = 2,
95    /// Sets the `SQL_DESC_COUNT` field of the APD to 0, releasing all parameter buffers set by
96    /// `SQLBindParameter` for the given StatementHandle. If this operation is performed on an
97    /// explicitly allocated descriptor that is shared by more than one statement, this operation
98    /// will affect the bindings of all the statements that share the descriptor.
99    ResetParams = 3,
100}
101
102/// Represented in C headers as SQLSMALLINT
103#[repr(i16)]
104#[derive(Debug, PartialEq, Eq, Clone, Copy)]
105pub enum HandleType {
106    Env = 1,
107    Dbc = 2,
108    Stmt = 3,
109    Desc = 4,
110    // Only used between Drivers and Driver Manager to enable connection pooling.
111    // https://learn.microsoft.com/en-us/sql/odbc/reference/develop-driver/developing-connection-pool-awareness-in-an-odbc-driver?view=sql-server-ver16
112    // Defined in sqlspi.h
113    DbcInfoToken = 6,
114}
115
116/// Options for `SQLDriverConnect`
117#[repr(u16)]
118#[derive(Debug, PartialEq, Eq, Clone, Copy)]
119pub enum DriverConnectOption {
120    NoPrompt = 0,
121    Complete = 1,
122    Prompt = 2,
123    CompleteRequired = 3,
124}
125
126// Attribute for string lengths
127
128/// SQL_IS_POINTER
129pub const IS_POINTER: i32 = -4;
130/// SQL_IS_UINTEGER
131pub const IS_UINTEGER: i32 = -5;
132/// SQL_IS_INTEGER
133pub const IS_INTEGER: i32 = -6;
134/// SQL_IS_USMALLINT
135pub const IS_USMALLINT: i32 = -7;
136/// SQL_IS_SMALLINT
137pub const IS_SMALLINT: i32 = -8;
138
139/// SQL_YEAR_MONTH_STRUCT
140#[repr(C)]
141#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
142pub struct YearMonth {
143    pub year: u32,
144    pub month: u32,
145}
146
147/// SQL_DAY_SECOND_STRUCT
148#[repr(C)]
149#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
150pub struct DaySecond {
151    pub day: u32,
152    pub hour: u32,
153    pub minute: u32,
154    pub second: u32,
155    pub fraction: u32,
156}
157
158/// SQL_INTERVAL_UNION
159#[repr(C)]
160#[derive(Copy, Clone)]
161pub union IntervalUnion {
162    pub year_month: YearMonth,
163    pub day_second: DaySecond,
164}
165
166/// SQL_INTERVAL_STRUCT
167#[repr(C)]
168#[derive(Clone, Copy)]
169pub struct IntervalStruct {
170    pub interval_type: c_int,
171    pub interval_sign: i16,
172    pub interval_value: IntervalUnion,
173}
174
175/// SQL_DATE_STRUCT
176#[repr(C)]
177#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
178pub struct Date {
179    pub year: i16,
180    pub month: u16,
181    pub day: u16,
182}
183
184/// SQL_TIME_STRUCT
185#[repr(C)]
186#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
187pub struct Time {
188    pub hour: u16,
189    pub minute: u16,
190    pub second: u16,
191}
192
193/// SQL_TIMESTAMP_STRUCT
194#[repr(C)]
195#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
196pub struct Timestamp {
197    pub year: i16,
198    pub month: u16,
199    pub day: u16,
200    pub hour: u16,
201    pub minute: u16,
202    pub second: u16,
203    pub fraction: u32,
204}
205
206/// SQLGUID
207#[repr(C)]
208#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Hash)]
209pub struct Guid {
210    pub d1: u32,
211    pub d2: u16,
212    pub d3: u16,
213    pub d4: [u8; 8],
214}
215
216/// `DiagIdentifier` for `SQLGetDiagField`
217#[repr(i32)]
218#[derive(Debug, PartialEq, Eq, Clone, Copy)]
219pub enum HeaderDiagnosticIdentifier {
220    /// SQL_DIAG_RETURNCODE
221    ReturnCode = 1,
222    /// SQL_DIAG_NUMBER
223    Number = 2,
224    /// SQL_DIAG_ROW_COUNT
225    RowCount = 3,
226    /// SQL_DIAG_SQLSTATE
227    SqlState = 4,
228    /// SQL_DIAG_NATIVE
229    Native = 5,
230    /// SQL_DIAG_MESSAGE_TEXT
231    MessageText = 6,
232    /// SQL_DIAG_DYNAMIC_FUNCTION
233    DynamicFunction = 7,
234    /// SQL_DIAG_CLASS_ORIGIN
235    ClassOrigin = 8,
236    /// SQL_DIAG_SUBCLASS_ORIGIN
237    SubclassOrigin = 9,
238    /// SQL_DIAG_CONNECTION_NAME
239    ConnectionName = 10,
240    /// SQL_DIAG_SERVER_NAME
241    ServerName = 11,
242    /// SQL_DIAG_DYNAMIC_FUNCTION_CODE
243    DynamicFunctionCode = 12,
244    /// SQL_DIAG_CURSOR_ROW_COUNT
245    CursorRowCount = -1249,
246    /// SQL_DIAG_ROW_NUMBER
247    RowNumber = -1248,
248    /// SQL_DIAG_COLUMN_NUMBER
249    ColumnNumber = -1247,
250}
251
252#[repr(i32)]
253#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
254pub enum AsyncConnectionBehavior {
255    /// SQL_ASYNC_DBC_ENABLE_ON
256    On = 1,
257    /// SQL_ASYNC_DBC_ENABLE_OFF = 0
258    #[default]
259    Off = 0,
260}
261
262#[repr(i32)]
263#[derive(Debug, PartialEq, Eq, Clone, Copy)]
264pub enum DynamicDiagnosticIdentifier {
265    /// SQL_DIAG_ALTER_DOMAIN
266    AlterDomain = 3,
267    /// SQL_DIAG_ALTER_TABLE,
268    AlterTable = 4,
269    /// SQL_DIAG_CALL
270    Call = 7,
271    /// SQL_DIAG_CREATE_ASSERTION
272    CreateAssertion = 6,
273    /// SQL_DIAG_CREATE_CHARACTER_SET
274    CreateCharacterSet = 8,
275    /// SQL_DIAG_CREATE_COLLATION,
276    CreateCollation = 10,
277    /// SQL_DIAG_CREATE_DOMAIN
278    CreateDomain = 23,
279    /// SQL_DIAG_CREATE_INDEX
280    CreateIndex = -1,
281    /// SQL_DIAG_CREATE_SCHEMA
282    CreateSchema = 64,
283    /// SQL_DIAG_CREATE_TABLE
284    CreateTable = 77,
285    /// SQL_DIAG_CREATE_TRANSLATION
286    CreateTranslation = 79,
287    /// SQL_DIAG_CREATE_VIEW
288    CreateView = 84,
289    /// SQL_DIAG_DELETE_WHERE
290    DeleteWhere = 19,
291    /// SQL_DIAG_DROP_ASSERTION
292    DropAssertion = 24,
293    /// SQL_DIAG_DROP_CHARACTER_SET
294    DropCharacterSet = 25,
295    /// SQL_DIAG_DROP_COLLATION
296    DropCollation = 26,
297    /// SQL_DIAG_DROP_DOMAIN
298    DropDomain = 27,
299    /// SQL_DIAG_DROP_INDEX
300    DropIndex = -2,
301    /// SQL_DIAG_DROP_SCHEMA
302    DropSchema = 31,
303    /// SQL_DIAG_DROP_TABLE
304    DropTable = 32,
305    /// SQL_DIAG_DROP_TRANSLATION
306    DropTranslation = 33,
307    /// SQL_DIAG_DROP_VIEW
308    DropView = 36,
309    /// SQL_DIAG_DYNAMIC_DELETE_CURSOR
310    DynamicDeleteCursor = 38,
311    /// SQL_DIAG_DYNAMIC_UPDATE_CURSOR
312    DynamicUpdateCursor = 81,
313    /// SQL_DIAG_GRANT
314    Grant = 48,
315    /// SQL_DIAG_INSERT
316    Insert = 50,
317    /// SQL_DIAG_REVOKE
318    Revoke = 59,
319    // SQL_DIAG_SELECT_CURSOR
320    SelectCursor = 85,
321    /// SQL_DIAG_UNKNOWN_STATEMENT = 0,
322    UnknownStatement = 0,
323    /// SQL_DIAG_UPDATE_WHERE = 82,
324    UpdateWhere = 82,
325}
326
327/// Completion types for `SQLEndTrans`
328#[repr(i16)]
329#[derive(Debug, PartialEq, Eq, Clone, Copy)]
330pub enum CompletionType {
331    Commit = 0,
332    Rollback = 1,
333}
334
335/// This means we use 128 bits (16 bytes) to for the numeric value. This excludes the sign, which is
336/// stored separetly.
337pub const MAX_NUMERIC_LEN: usize = 16;
338
339/// Equivalent of `SQL_NUMERIC_STRUCT` in the ODBC C API.
340///
341/// # Examples
342///
343/// ## Store value in Numeric
344///
345/// ```
346/// use odbc_sys::Numeric;
347///
348/// /// Store 123.45 in `Numeric`
349/// let mut num = Numeric {
350///     precision: 5, // 123.45 uses five digits
351///     scale: 2,   // two digits after the decimal point
352///     sign: 1,    // positive number
353///     val: 12345u128.to_le_bytes(), // store 12345 as little-endian bytes
354/// };
355/// ```
356///
357/// See:
358/// <https://learn.microsoft.com/en-us/sql/odbc/reference/appendixes/retrieve-numeric-data-sql-numeric-struct-kb222831>
359#[repr(C)]
360#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
361pub struct Numeric {
362    /// Number of significant digits. `precision` and `scale` are ignored then using `Numeric` as
363    /// input.
364    pub precision: u8,
365    /// Number of decimal digits to the right of the decimal point. `precision` and `scale` are
366    /// ignored then using `Numeric` as input.
367    pub scale: i8,
368    /// 1 if positive, 0 if negative
369    pub sign: u8,
370    /// The value of the numeric as a little-endian array of bytes. The value is stored as an
371    /// unsigned integer without any decimal point. For example, the number -123.45 with
372    /// precision 5 and scale 2 is stored as 12345 (0x39 0x30 0x00 0x00 ...).
373    pub val: [u8; MAX_NUMERIC_LEN],
374}