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