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}