rs_odbc/
api.rs

1use crate::handle::*;
2use crate::{
3    attr::{AttrGet, AttrSet, StrLen},
4    c_types::CData,
5    c_types::DeferredBuf,
6    col::ColAttr,
7    conn::{BrowseConnect, ConnAttr, ConnState, Disconnect, C2, C3, C4},
8    convert::{
9        AsMutPtr, AsMutRawSlice, AsMutSQLPOINTER, AsRawSlice, AsSQLHANDLE, AsSQLPOINTER,
10        IntoSQLPOINTER,
11    },
12    desc::{AppDesc, DescField, DescType, IPD, IRD},
13    diag::{DiagField, SQLSTATE},
14    env::{EnvAttr, OdbcVersion, SQL_OV_ODBC3_80, SQL_OV_ODBC4},
15    handle::{RefSQLHDESC, UnsafeSQLHSTMT, SQLHDBC, SQLHDESC, SQLHENV, SQLHSTMT, SQL_HANDLE_STMT},
16    info::InfoType,
17    sql_types::SqlType,
18    sqlreturn::{SQLRETURN, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_SUCCEEDED},
19    stmt::{private::BaseStmtAttr, StmtAttr},
20    str::{Ansi, OdbcStr, Unicode},
21    BulkOperation, CompletionType, DatetimeIntervalCode, DriverCompletion, FreeStmtOption,
22    FunctionId, IOType, Ident, IdentifierType, LockType, NullAllowed, Operation, Ref, Reserved,
23    Scope, StrLenOrInd, Unique, RETCODE, SQLCHAR, SQLINTEGER, SQLLEN, SQLPOINTER, SQLSETPOSIROW,
24    SQLSMALLINT, SQLULEN, SQLUSMALLINT, SQLWCHAR,
25};
26use core::{cell::UnsafeCell, mem::MaybeUninit, ptr};
27#[cfg(test)]
28use mockall::automock;
29
30/// ODBC handle such as environment, connection, statement or descriptor.
31///
32/// For complete documentation, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/handles).
33pub trait Handle: AsSQLHANDLE + Sized {
34    type Ident: Ident<Type = SQLSMALLINT>;
35}
36
37#[allow(non_snake_case)]
38pub trait Allocate<'src, SRC: AsSQLHANDLE>: Handle {
39    /// Creates handle from a raw pointer
40    ///
41    /// # Safety
42    ///
43    /// The given raw pointer must point to a valid handle of the required type
44    unsafe fn from_raw(output_handle: ptr::NonNull<RawHandle>) -> Self;
45
46    /// Allocates an environment, connection, statement, or descriptor handle.
47    ///
48    /// For complete documentation on `SQLAllocHandle`, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlallochandle-function).
49    ///
50    /// # Returns
51    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.
52    #[inline]
53    fn SQLAllocHandle(InputHandle: &'src SRC) -> (Result<Self, ()>, SQLRETURN) {
54        let mut output_handle = MaybeUninit::uninit();
55
56        unsafe {
57            let sql_return = ffi::SQLAllocHandle(
58                Self::Ident::IDENTIFIER,
59                InputHandle.as_SQLHANDLE(),
60                output_handle.as_mut_ptr(),
61            );
62
63            if SQL_SUCCEEDED(sql_return) {
64                let output_handle = ptr::NonNull::new_unchecked(output_handle.assume_init());
65                (Ok(Self::from_raw(output_handle)), sql_return)
66            } else {
67                (Err(()), sql_return)
68            }
69        }
70    }
71
72    /// Frees resources associated with a specific environment, connection, statement, or descriptor handle.
73    ///
74    /// For complete documentation on SQLFreeHandle, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreehandle-function).
75    ///
76    /// # Panics
77    ///
78    /// Panics if the DM returns value other than SQL_SUCCESS
79    #[inline]
80    fn SQLFreeHandle(self) {}
81}
82
83#[allow(non_snake_case, unused_variables)]
84pub trait Diagnostics: Handle {
85    /// Returns the current value of a field of a record of the diagnostic data structure (associated with a specified handle) that contains error, warning, and status information.
86    ///
87    /// For complete documentation on SQLGetDiagFieldA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagfield-function).
88    ///
89    /// # Returns
90    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_NO_DATA.
91    #[inline]
92    fn SQLGetDiagFieldA<A: Ident<Type = SQLSMALLINT>, T: DiagField<Self, A>>(
93        &self,
94        // TODO: Use NoneZeroI16?
95        RecNumber: core::num::NonZeroI16,
96        DiagIdentifier: A,
97        DiagInfoPtr: Option<&mut T>,
98        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
99    ) -> SQLRETURN
100    where
101        T: AttrGet<A> + Ansi + ?Sized,
102        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
103    {
104        let DiagInfoPtr = DiagInfoPtr.map_or((ptr::null_mut(), 0), |DiagInfoPtr| {
105            if cfg!(feature = "odbc_debug") {
106                DiagInfoPtr.assert_zeroed();
107            }
108
109            (DiagInfoPtr.as_mut_SQLPOINTER(), DiagInfoPtr.len())
110        });
111
112        unsafe {
113            ffi::SQLGetDiagFieldA(
114                Self::Ident::IDENTIFIER,
115                self.as_SQLHANDLE(),
116                RecNumber.get(),
117                A::IDENTIFIER,
118                DiagInfoPtr.0,
119                DiagInfoPtr.1,
120                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
121            )
122        }
123    }
124
125    /// Returns the current value of a field of a record of the diagnostic data structure (associated with a specified handle) that contains error, warning, and status information.
126    ///
127    /// For complete documentation on SQLGetDiagFieldW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagfield-function).
128    ///
129    /// # Returns
130    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_NO_DATA.
131    #[inline]
132    fn SQLGetDiagFieldW<A: Ident<Type = SQLSMALLINT>, T: DiagField<Self, A>>(
133        &self,
134        // TODO: Use NoneZeroI16?
135        RecNumber: core::num::NonZeroI16,
136        DiagIdentifier: A,
137        DiagInfoPtr: Option<&mut T>,
138        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
139    ) -> SQLRETURN
140    where
141        T: AttrGet<A> + Unicode + ?Sized,
142        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
143    {
144        let DiagInfoPtr = DiagInfoPtr.map_or((ptr::null_mut(), 0), |DiagInfoPtr| {
145            if cfg!(feature = "odbc_debug") {
146                DiagInfoPtr.assert_zeroed();
147            }
148
149            (DiagInfoPtr.as_mut_SQLPOINTER(), DiagInfoPtr.len())
150        });
151
152        unsafe {
153            ffi::SQLGetDiagFieldW(
154                Self::Ident::IDENTIFIER,
155                self.as_SQLHANDLE(),
156                RecNumber.get(),
157                A::IDENTIFIER,
158                DiagInfoPtr.0,
159                DiagInfoPtr.1,
160                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
161            )
162        }
163    }
164
165    /// Returns the current values of multiple fields of a diagnostic record that contains error, warning, and status information. Unlike **SQLGetDiagField**, which returns one diagnostic field per call, **SQLGetDiagRec** returns several commonly used fields of a diagnostic record, including the SQLSTATE, the native error code, and the diagnostic message text.
166    ///
167    /// For complete documentation on SQLGetDiagRecA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagrec-function).
168    ///
169    /// # Returns
170    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
171    #[inline]
172    fn SQLGetDiagRecA(
173        &self,
174        // TODO: Use NoneZeroI16?
175        RecNumber: core::num::NonZeroI16,
176        SQLState: &mut MaybeUninit<SQLSTATE<SQLCHAR>>,
177        NativeErrorPtr: &mut impl AsMutPtr<SQLINTEGER>,
178        MessageText: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
179        TextLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
180    ) -> SQLRETURN {
181        let MessageText = MessageText.as_mut_raw_slice();
182
183        unsafe {
184            ffi::SQLGetDiagRecA(
185                Self::Ident::IDENTIFIER,
186                self.as_SQLHANDLE(),
187                RecNumber.get(),
188                SQLState.as_mut_ptr().cast(),
189                NativeErrorPtr.as_mut_ptr(),
190                MessageText.0,
191                MessageText.1,
192                TextLengthPtr.as_mut_ptr(),
193            )
194        }
195    }
196
197    /// Returns the current values of multiple fields of a diagnostic record that contains error, warning, and status information. Unlike **SQLGetDiagField**, which returns one diagnostic field per call, **SQLGetDiagRec** returns several commonly used fields of a diagnostic record, including the SQLSTATE, the native error code, and the diagnostic message text.
198    ///
199    /// For complete documentation on SQLGetDiagRecW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdiagrec-function).
200    ///
201    /// # Returns
202    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
203    #[inline]
204    fn SQLGetDiagRecW(
205        &self,
206        // TODO: Use NoneZeroI16?
207        RecNumber: core::num::NonZeroI16,
208        SQLState: &mut MaybeUninit<SQLSTATE<SQLWCHAR>>,
209        NativeErrorPtr: &mut impl AsMutPtr<SQLINTEGER>,
210        MessageText: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
211        TextLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
212    ) -> SQLRETURN {
213        let MessageText = MessageText.as_mut_raw_slice();
214
215        unsafe {
216            ffi::SQLGetDiagRecW(
217                Self::Ident::IDENTIFIER,
218                self.as_SQLHANDLE(),
219                RecNumber.get(),
220                SQLState.as_mut_ptr().cast(),
221                NativeErrorPtr.as_mut_ptr(),
222                MessageText.0,
223                MessageText.1,
224                TextLengthPtr.as_mut_ptr(),
225            )
226        }
227    }
228}
229
230#[allow(non_snake_case)]
231pub trait Statement<'desc, 'buf, V: OdbcVersion>: Handle {
232    type ARD: Descriptor<'buf, AppDesc<'buf>, V>;
233    type APD: Descriptor<'buf, AppDesc<'buf>, V>;
234    type IRD: Descriptor<'buf, IRD, V>;
235    type IPD: Descriptor<'buf, IPD, V>;
236
237    type ExplicitARD: Descriptor<'buf, AppDesc<'buf>, V>;
238    type ExplicitAPD: Descriptor<'buf, AppDesc<'buf>, V>;
239
240    fn bind_col<TT: Ident, B: DeferredBuf<Self::ARD, TT, V>>(
241        &self,
242        TargetValuePtr: Option<&'buf B>,
243    ) where
244        B: ?Sized;
245    fn bind_param<TT: Ident, B: DeferredBuf<Self::APD, TT, V>>(
246        &self,
247        TargetValuePtr: Option<&'buf B>,
248    ) where
249        B: ?Sized;
250    fn bind_strlen_or_ind(&self, StrLen_or_IndPtr: Option<&'buf UnsafeCell<StrLenOrInd>>);
251
252    /// Binds application data buffers to columns in the result set.
253    ///
254    /// For complete documentation on SQLBindCol, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindcol-function).
255    ///
256    /// # Returns
257    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
258    #[inline]
259    #[allow(unused_variables)]
260    fn SQLBindCol<TT: Ident<Type = SQLSMALLINT>, B: DeferredBuf<Self::ARD, TT, V>>(
261        &self,
262        ColumnNumber: SQLUSMALLINT,
263        TargetType: TT,
264        TargetValuePtr: Option<&'buf B>,
265        StrLen_or_IndPtr: Option<&'buf UnsafeCell<StrLenOrInd>>,
266    ) -> SQLRETURN
267    where
268        B: ?Sized,
269    {
270        let sql_return = unsafe {
271            let TargetValuePtr = TargetValuePtr.map_or((ptr::null_mut(), 0), |TargetValuePtr| {
272                (TargetValuePtr.as_SQLPOINTER(), TargetValuePtr.len())
273            });
274
275            ffi::SQLBindCol(
276                self.as_SQLHANDLE(),
277                ColumnNumber,
278                TT::IDENTIFIER,
279                TargetValuePtr.0,
280                TargetValuePtr.1,
281                StrLen_or_IndPtr.map_or_else(ptr::null_mut, |StrLen_or_IndPtr| {
282                    StrLen_or_IndPtr.get().cast()
283                }),
284            )
285        };
286
287        if SQL_SUCCEEDED(sql_return) {
288            self.bind_col(TargetValuePtr);
289            self.bind_strlen_or_ind(StrLen_or_IndPtr);
290        }
291
292        sql_return
293    }
294
295    /// Binds a buffer to a parameter marker in an SQL statement. **SQLBindParameter** supports binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
296    ///
297    /// For complete documentation on SQLBindParameter, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function).
298    ///
299    /// # Returns
300    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
301    #[inline]
302    #[allow(unused_variables)]
303    fn SQLBindParameter<
304        TT: Ident<Type = SQLSMALLINT>,
305        // TODO: Check which type is used for ParameterType
306        ST: SqlType<V>,
307        B: DeferredBuf<Self::APD, TT, V>,
308    >(
309        &self,
310        ParameterNumber: SQLUSMALLINT,
311        InputOutputType: IOType,
312        ValueType: TT,
313        ParameterType: ST,
314        ColumnSize: SQLULEN,
315        DecimalDigits: SQLSMALLINT,
316        ParameterValuePtr: Option<&'buf B>,
317        StrLen_or_IndPtr: Option<&'buf UnsafeCell<StrLenOrInd>>,
318    ) -> SQLRETURN
319    where
320        B: ?Sized,
321    {
322        let sql_return = unsafe {
323            let ParameterValuePtr = ParameterValuePtr
324                .map_or((ptr::null_mut(), 0), |ParameterValuePtr| {
325                    (ParameterValuePtr.as_SQLPOINTER(), ParameterValuePtr.len())
326                });
327
328            ffi::SQLBindParameter(
329                self.as_SQLHANDLE(),
330                ParameterNumber,
331                InputOutputType.identifier(),
332                TT::IDENTIFIER,
333                ParameterType.identifier(),
334                ColumnSize,
335                DecimalDigits,
336                ParameterValuePtr.0,
337                ParameterValuePtr.1,
338                StrLen_or_IndPtr.map_or_else(ptr::null_mut, |StrLen_or_IndPtr| {
339                    StrLen_or_IndPtr.get().cast()
340                }),
341            )
342        };
343
344        if SQL_SUCCEEDED(sql_return) {
345            self.bind_param(ParameterValuePtr);
346            self.bind_strlen_or_ind(StrLen_or_IndPtr);
347        }
348
349        sql_return
350    }
351    /// Performs bulk insertions and bulk bookmark operations, including update, delete, and fetch by bookmark.
352    ///
353    /// For complete documentation on SQLBulkOperations, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbulkoperations-function).
354    ///
355    /// # Returns
356    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
357    #[inline]
358    fn SQLBulkOperations(&self, Operation: BulkOperation) -> SQLRETURN {
359        unsafe { ffi::SQLBulkOperations(self.as_SQLHANDLE(), Operation as SQLUSMALLINT) }
360    }
361
362    /// Closes a cursor that has been opened on a statement and discards pending results.
363    ///
364    /// For complete documentation on SQLCloseCursor, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlclosecursor-function).
365    ///
366    /// # Returns
367    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
368    #[inline]
369    fn SQLCloseCursor(&self) -> SQLRETURN {
370        unsafe { ffi::SQLCloseCursor(self.as_SQLHANDLE()) }
371    }
372
373    /// Returns descriptor information for a column in a result set. Descriptor information is returned as a character string, a descriptor-dependent value, or an integer value.
374    ///
375    /// For complete documentation on SQLColAttributeA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function).
376    ///
377    /// # Returns
378    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
379    #[inline]
380    #[allow(unused_variables)]
381    fn SQLColAttributeA<A: Ident<Type = SQLUSMALLINT>, T: ColAttr<A, V>>(
382        &self,
383        ColumnNumber: SQLUSMALLINT,
384        FieldIdentifier: A,
385        CharacterAttributePtr: Option<&mut T>,
386        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
387        NumericAttributePtr: &mut impl AsMutPtr<SQLLEN>,
388    ) -> SQLRETURN
389    where
390        T: AttrGet<A> + Ansi + ?Sized,
391        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
392    {
393        // TODO: With MaybeUninit it's not possible to check that value is zeroed
394        //if cfg!(feature = "odbc_debug") {
395        //    NumericAttributePtr.assert_zeroed();
396        //}
397
398        let CharacterAttributePtr =
399            CharacterAttributePtr.map_or((ptr::null_mut(), 0), |CharacterAttributePtr| {
400                (
401                    CharacterAttributePtr.as_mut_SQLPOINTER(),
402                    CharacterAttributePtr.len(),
403                )
404            });
405
406        unsafe {
407            ffi::SQLColAttributeA(
408                self.as_SQLHANDLE(),
409                ColumnNumber,
410                A::IDENTIFIER,
411                CharacterAttributePtr.0,
412                CharacterAttributePtr.1,
413                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
414                NumericAttributePtr.as_mut_ptr(),
415            )
416        }
417    }
418
419    /// Returns descriptor information for a column in a result set. Descriptor information is returned as a character string, a descriptor-dependent value, or an integer value.
420    ///
421    /// For complete documentation on SQLColAttributeW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function).
422    ///
423    /// # Returns
424    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
425    #[inline]
426    #[allow(unused_variables)]
427    fn SQLColAttributeW<A: Ident<Type = SQLUSMALLINT>, T: ColAttr<A, V>>(
428        &self,
429        ColumnNumber: SQLUSMALLINT,
430        FieldIdentifier: A,
431        CharacterAttributePtr: Option<&mut T>,
432        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
433        NumericAttributePtr: &mut impl AsMutPtr<SQLLEN>,
434    ) -> SQLRETURN
435    where
436        T: AttrGet<A> + Unicode + ?Sized,
437        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
438    {
439        // TODO: With MaybeUninit it's not possible to check that value is zeroed
440        //if cfg!(feature = "odbc_debug") {
441        //    NumericAttributePtr.assert_zeroed();
442        //}
443
444        let CharacterAttributePtr =
445            CharacterAttributePtr.map_or((ptr::null_mut(), 0), |CharacterAttributePtr| {
446                (
447                    CharacterAttributePtr.as_mut_SQLPOINTER(),
448                    CharacterAttributePtr.len(),
449                )
450            });
451
452        unsafe {
453            ffi::SQLColAttributeW(
454                self.as_SQLHANDLE(),
455                ColumnNumber,
456                A::IDENTIFIER,
457                CharacterAttributePtr.0,
458                CharacterAttributePtr.1,
459                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
460                NumericAttributePtr.as_mut_ptr(),
461            )
462        }
463    }
464
465    /// Returns a list of columns and associated privileges for the specified table. The driver returns the information as a result set on the specified `self`.
466    ///
467    /// For complete documentation on SQLColumnPrivilegesA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumnprivileges-function).
468    ///
469    /// # Returns
470    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
471    #[inline]
472    fn SQLColumnPrivilegesA(
473        &self,
474        CatalogName: &OdbcStr<SQLCHAR>,
475        SchemaName: &OdbcStr<SQLCHAR>,
476        TableName: &OdbcStr<SQLCHAR>,
477        ColumnName: &OdbcStr<SQLCHAR>,
478    ) -> SQLRETURN {
479        let CatalogName = CatalogName.as_raw_slice();
480        let SchemaName = SchemaName.as_raw_slice();
481        let TableName = TableName.as_raw_slice();
482        let ColumnName = ColumnName.as_raw_slice();
483
484        unsafe {
485            ffi::SQLColumnPrivilegesA(
486                self.as_SQLHANDLE(),
487                CatalogName.0,
488                CatalogName.1,
489                SchemaName.0,
490                SchemaName.1,
491                TableName.0,
492                TableName.1,
493                ColumnName.0,
494                ColumnName.1,
495            )
496        }
497    }
498
499    /// Returns a list of columns and associated privileges for the specified table. The driver returns the information as a result set on the specified `self`.
500    ///
501    /// For complete documentation on SQLColumnPrivilegesW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumnprivileges-function).
502    ///
503    /// # Returns
504    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
505    #[inline]
506    fn SQLColumnPrivilegesW(
507        &self,
508        CatalogName: &OdbcStr<SQLWCHAR>,
509        SchemaName: &OdbcStr<SQLWCHAR>,
510        TableName: &OdbcStr<SQLWCHAR>,
511        ColumnName: &OdbcStr<SQLWCHAR>,
512    ) -> SQLRETURN {
513        let CatalogName = CatalogName.as_raw_slice();
514        let SchemaName = SchemaName.as_raw_slice();
515        let TableName = TableName.as_raw_slice();
516        let ColumnName = ColumnName.as_raw_slice();
517
518        unsafe {
519            ffi::SQLColumnPrivilegesW(
520                self.as_SQLHANDLE(),
521                CatalogName.0,
522                CatalogName.1,
523                SchemaName.0,
524                SchemaName.1,
525                TableName.0,
526                TableName.1,
527                ColumnName.0,
528                ColumnName.1,
529            )
530        }
531    }
532
533    /// Returns the list of column names in specified tables. The driver returns this information as a result set on the specified `self`.
534    ///
535    /// For complete documentation on SQLColumnsA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumns-function).
536    ///
537    /// # Returns
538    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
539    #[inline]
540    fn SQLColumnsA(
541        &self,
542        CatalogName: &OdbcStr<SQLCHAR>,
543        SchemaName: &OdbcStr<SQLCHAR>,
544        TableName: &OdbcStr<SQLCHAR>,
545        ColumnName: &OdbcStr<SQLCHAR>,
546    ) -> SQLRETURN {
547        let CatalogName = CatalogName.as_raw_slice();
548        let SchemaName = SchemaName.as_raw_slice();
549        let TableName = TableName.as_raw_slice();
550        let ColumnName = ColumnName.as_raw_slice();
551
552        unsafe {
553            ffi::SQLColumnsA(
554                self.as_SQLHANDLE(),
555                CatalogName.0,
556                CatalogName.1,
557                SchemaName.0,
558                SchemaName.1,
559                TableName.0,
560                TableName.1,
561                ColumnName.0,
562                ColumnName.1,
563            )
564        }
565    }
566
567    /// Returns the list of column names in specified tables. The driver returns this information as a result set on the specified `self`.
568    ///
569    /// For complete documentation on SQLColumnsW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumns-function).
570    ///
571    /// # Returns
572    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
573    #[inline]
574    fn SQLColumnsW(
575        &self,
576        CatalogName: &OdbcStr<SQLWCHAR>,
577        SchemaName: &OdbcStr<SQLWCHAR>,
578        TableName: &OdbcStr<SQLWCHAR>,
579        ColumnName: &OdbcStr<SQLWCHAR>,
580    ) -> SQLRETURN {
581        let CatalogName = CatalogName.as_raw_slice();
582        let SchemaName = SchemaName.as_raw_slice();
583        let TableName = TableName.as_raw_slice();
584        let ColumnName = ColumnName.as_raw_slice();
585
586        unsafe {
587            ffi::SQLColumnsW(
588                self.as_SQLHANDLE(),
589                CatalogName.0,
590                CatalogName.1,
591                SchemaName.0,
592                SchemaName.1,
593                TableName.0,
594                TableName.1,
595                ColumnName.0,
596                ColumnName.1,
597            )
598        }
599    }
600
601    /// Returns the result descriptor - column name,type, column size, decimal digits, and nullability - for one column in the result set. This information also is available in the fields of the IRD.
602    ///
603    /// For complete documentation on SQLDescribeColA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldescribecol-function).
604    ///
605    /// # Returns
606    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
607    #[inline]
608    fn SQLDescribeColA(
609        &self,
610        ColumnNumber: SQLUSMALLINT,
611        ColumnName: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
612        NameLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
613        DataTypePtr: &mut impl AsMutPtr<SQLSMALLINT>,
614        ColumnSizePtr: &mut impl AsMutPtr<SQLULEN>,
615        DecimalDigitsPtr: &mut impl AsMutPtr<SQLSMALLINT>,
616        NullablePtr: &mut impl AsMutPtr<NullAllowed>,
617    ) -> SQLRETURN {
618        let ColumnName = ColumnName.as_mut_raw_slice();
619
620        unsafe {
621            ffi::SQLDescribeColA(
622                self.as_SQLHANDLE(),
623                ColumnNumber,
624                ColumnName.0,
625                ColumnName.1,
626                NameLengthPtr.as_mut_ptr(),
627                DataTypePtr.as_mut_ptr(),
628                ColumnSizePtr.as_mut_ptr(),
629                DecimalDigitsPtr.as_mut_ptr(),
630                NullablePtr.as_mut_ptr().cast(),
631            )
632        }
633    }
634
635    /// Returns the result descriptor - column name,type, column size, decimal digits, and nullability - for one column in the result set. This information also is available in the fields of the IRD.
636    ///
637    /// For complete documentation on SQLDescribeColW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldescribecol-function).
638    ///
639    /// # Returns
640    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
641    #[inline]
642    fn SQLDescribeColW(
643        &self,
644        ColumnNumber: SQLUSMALLINT,
645        ColumnName: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
646        NameLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
647        DataTypePtr: &mut impl AsMutPtr<SQLSMALLINT>,
648        ColumnSizePtr: &mut impl AsMutPtr<SQLULEN>,
649        DecimalDigitsPtr: &mut impl AsMutPtr<SQLSMALLINT>,
650        NullablePtr: &mut impl AsMutPtr<NullAllowed>,
651    ) -> SQLRETURN {
652        let ColumnName = ColumnName.as_mut_raw_slice();
653
654        unsafe {
655            ffi::SQLDescribeColW(
656                self.as_SQLHANDLE(),
657                ColumnNumber,
658                ColumnName.0,
659                ColumnName.1,
660                NameLengthPtr.as_mut_ptr(),
661                DataTypePtr.as_mut_ptr(),
662                ColumnSizePtr.as_mut_ptr(),
663                DecimalDigitsPtr.as_mut_ptr(),
664                NullablePtr.as_mut_ptr().cast(),
665            )
666        }
667    }
668
669    /// Returns the description of a parameter marker associated with a prepared SQL statement. This information is also available in the fields of the IPD.
670    ///
671    /// For complete documentation on SQLDescribeParam, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldescribeparam-function).
672    ///
673    /// # Returns
674    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
675    #[inline]
676    fn SQLDescribeParam(
677        &self,
678        ParameterNumber: SQLUSMALLINT,
679        DataTypePtr: &mut impl AsMutPtr<SQLSMALLINT>,
680        ParameterSizePtr: &mut impl AsMutPtr<SQLULEN>,
681        DecimalDigitsPtr: &mut impl AsMutPtr<SQLSMALLINT>,
682        NullablePtr: &mut impl AsMutPtr<NullAllowed>,
683    ) -> SQLRETURN {
684        unsafe {
685            ffi::SQLDescribeParam(
686                self.as_SQLHANDLE(),
687                ParameterNumber,
688                DataTypePtr.as_mut_ptr(),
689                ParameterSizePtr.as_mut_ptr(),
690                DecimalDigitsPtr.as_mut_ptr(),
691                NullablePtr.as_mut_ptr().cast(),
692            )
693        }
694    }
695
696    /// Can return:
697    ///
698    /// * A list of foreign keys in the specified table (columns in the specified table that refer to primary keys in other tables).
699    /// * A list of foreign keys in other tables that refer to the primary key in the specified table.
700    ///
701    /// The driver returns each list as a result set on the specified statement.
702    ///
703    /// For complete documentation on SQLForeignKeysA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function).
704    ///
705    /// # Returns
706    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
707    #[inline]
708    fn SQLForeignKeysA(
709        &self,
710        PKCatalogName: &OdbcStr<SQLCHAR>,
711        PKSchemaName: &OdbcStr<SQLCHAR>,
712        PKTableName: &OdbcStr<SQLCHAR>,
713        FKCatalogName: &OdbcStr<SQLCHAR>,
714        FKSchemaName: &OdbcStr<SQLCHAR>,
715        FKTableName: &OdbcStr<SQLCHAR>,
716    ) -> SQLRETURN {
717        let PKCatalogName = PKCatalogName.as_raw_slice();
718        let PKSchemaName = PKSchemaName.as_raw_slice();
719        let PKTableName = PKTableName.as_raw_slice();
720        let FKCatalogName = FKCatalogName.as_raw_slice();
721        let FKSchemaName = FKSchemaName.as_raw_slice();
722        let FKTableName = FKTableName.as_raw_slice();
723
724        unsafe {
725            ffi::SQLForeignKeysA(
726                self.as_SQLHANDLE(),
727                PKCatalogName.0,
728                PKCatalogName.1,
729                PKSchemaName.0,
730                PKSchemaName.1,
731                PKTableName.0,
732                PKTableName.1,
733                FKCatalogName.0,
734                FKCatalogName.1,
735                FKSchemaName.0,
736                FKSchemaName.1,
737                FKTableName.0,
738                FKTableName.1,
739            )
740        }
741    }
742
743    /// Can return:
744    ///
745    /// * A list of foreign keys in the specified table (columns in the specified table that refer to primary keys in other tables).
746    /// * A list of foreign keys in other tables that refer to the primary key in the specified table.
747    ///
748    /// The driver returns each list as a result set on the specified statement.
749    ///
750    /// For complete documentation on SQLForeignKeysW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function).
751    ///
752    /// # Returns
753    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
754    #[inline]
755    fn SQLForeignKeysW(
756        &self,
757        PKCatalogName: &OdbcStr<SQLWCHAR>,
758        PKSchemaName: &OdbcStr<SQLWCHAR>,
759        PKTableName: &OdbcStr<SQLWCHAR>,
760        FKCatalogName: &OdbcStr<SQLWCHAR>,
761        FKSchemaName: &OdbcStr<SQLWCHAR>,
762        FKTableName: &OdbcStr<SQLWCHAR>,
763    ) -> SQLRETURN {
764        let PKCatalogName = PKCatalogName.as_raw_slice();
765        let PKSchemaName = PKSchemaName.as_raw_slice();
766        let PKTableName = PKTableName.as_raw_slice();
767        let FKCatalogName = FKCatalogName.as_raw_slice();
768        let FKSchemaName = FKSchemaName.as_raw_slice();
769        let FKTableName = FKTableName.as_raw_slice();
770
771        unsafe {
772            ffi::SQLForeignKeysW(
773                self.as_SQLHANDLE(),
774                PKCatalogName.0,
775                PKCatalogName.1,
776                PKSchemaName.0,
777                PKSchemaName.1,
778                PKTableName.0,
779                PKTableName.1,
780                FKCatalogName.0,
781                FKCatalogName.1,
782                FKSchemaName.0,
783                FKSchemaName.1,
784                FKTableName.0,
785                FKTableName.1,
786            )
787        }
788    }
789
790    /// Stops processing associated with a specific statement, closes any open cursors associated with the statement, discards pending results, or, optionally, frees all resources associated with the statement handle.
791    ///
792    /// For complete documentation on SQLFreeStmt, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfreestmt-function).
793    ///
794    /// # Returns
795    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
796    #[inline]
797    fn SQLFreeStmt(&self, Option: FreeStmtOption) -> SQLRETURN {
798        unsafe { ffi::SQLFreeStmt(self.as_SQLHANDLE(), Option as SQLUSMALLINT) }
799    }
800
801    /// Returns the cursor name associated with a specified statement.
802    ///
803    /// For complete documentation on SQLGetCursorNameA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetcursorname-function).
804    ///
805    /// # Returns
806    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
807    #[inline]
808    fn SQLGetCursorNameA(
809        &self,
810        CursorName: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
811        NameLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
812    ) -> SQLRETURN {
813        let CursorName = CursorName.as_mut_raw_slice();
814
815        unsafe {
816            ffi::SQLGetCursorNameA(
817                self.as_SQLHANDLE(),
818                CursorName.0,
819                CursorName.1,
820                NameLengthPtr.as_mut_ptr(),
821            )
822        }
823    }
824
825    /// Returns the cursor name associated with a specified statement.
826    ///
827    /// For complete documentation on SQLGetCursorNameW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetcursorname-function).
828    ///
829    /// # Returns
830    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
831    #[inline]
832    fn SQLGetCursorNameW(
833        &self,
834        CursorName: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
835        NameLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
836    ) -> SQLRETURN {
837        let CursorName = CursorName.as_mut_raw_slice();
838
839        unsafe {
840            ffi::SQLGetCursorNameW(
841                self.as_SQLHANDLE(),
842                CursorName.0,
843                CursorName.1,
844                NameLengthPtr.as_mut_ptr(),
845            )
846        }
847    }
848
849    /// Retrieves data for a single column in the result set or for a single parameter after **SQLParamData** returns SQL_PARAM_DATA_AVAILABLE. It can be called multiple times to retrieve variable-length data in parts.
850    ///
851    /// For complete documentation on SQLGetData, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdata-function).
852    ///
853    /// # Returns
854    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
855    #[inline]
856    #[allow(unused_variables)]
857    // TODO: This function must be unsafe if SQL_ARD_TYPE and SQL_APD_TYPE are allowed to be used
858    fn SQLGetData<TT: Ident<Type = SQLSMALLINT>, B: CData<TT, V>>(
859        &self,
860        Col_or_Param_Num: SQLUSMALLINT,
861        TargetType: TT,
862        TargetValuePtr: &mut B,
863        StrLen_or_IndPtr: Option<&mut MaybeUninit<StrLenOrInd>>,
864    ) -> SQLRETURN
865    where
866        B: AsMutSQLPOINTER + ?Sized,
867        MaybeUninit<StrLenOrInd>: StrLen<SQLLEN>,
868    {
869        unsafe {
870            ffi::SQLGetData(
871                self.as_SQLHANDLE(),
872                Col_or_Param_Num,
873                TT::IDENTIFIER,
874                TargetValuePtr.as_mut_SQLPOINTER(),
875                TargetValuePtr.len(),
876                StrLen_or_IndPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
877            )
878        }
879    }
880
881    /// Returns the current setting of a statement attribute.
882    ///
883    /// For complete documentation on SQLGetStmtAttrA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetstmtattr-function).
884    ///
885    /// # Returns
886    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
887    #[inline]
888    fn SQLGetStmtAttrA<'stmt, A: Ident<Type = SQLINTEGER>, T: StmtAttr<'desc, 'buf, Self, A, V>>(
889        &'stmt self,
890        Attribute: A,
891        ValuePtr: Option<&mut T>,
892        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
893    ) -> SQLRETURN
894    where
895        T: AttrGet<A> + Ansi + Ref<'stmt> + ?Sized,
896        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
897    {
898        SQLGetStmtAttrA(self, Attribute, ValuePtr, StringLengthPtr)
899    }
900
901    /// Returns the current setting of a statement attribute.
902    ///
903    /// For complete documentation on SQLGetStmtAttrW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetstmtattr-function).
904    ///
905    /// # Returns
906    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
907    #[inline]
908    fn SQLGetStmtAttrW<'stmt, A: Ident<Type = SQLINTEGER>, T: StmtAttr<'desc, 'buf, Self, A, V>>(
909        &'stmt self,
910        Attribute: A,
911        ValuePtr: Option<&mut T>,
912        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
913    ) -> SQLRETURN
914    where
915        T: AttrGet<A> + Unicode + Ref<'stmt> + ?Sized,
916        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
917    {
918        SQLGetStmtAttrW(self, Attribute, ValuePtr, StringLengthPtr)
919    }
920
921    /// Returns information about data types supported by the data source. The driver returns the information in the form of an SQL result set. The data types are intended for use in Data Definition Language (DDL) statements.
922    ///
923    /// For complete documentation on SQLGetTypeInfoA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgettypeinfo-function).
924    ///
925    /// # Returns
926    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
927    #[inline]
928    fn SQLGetTypeInfoA<ST: SqlType<V>>(&self, DataType: ST) -> SQLRETURN {
929        unsafe { ffi::SQLGetTypeInfoA(self.as_SQLHANDLE(), DataType.identifier()) }
930    }
931
932    /// Returns information about data types supported by the data source. The driver returns the information in the form of an SQL result set. The data types are intended for use in Data Definition Language (DDL) statements.
933    ///
934    /// For complete documentation on SQLGetTypeInfoW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgettypeinfo-function).
935    ///
936    /// # Returns
937    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
938    #[inline]
939    fn SQLGetTypeInfoW<ST: SqlType<V>>(&self, DataType: ST) -> SQLRETURN {
940        unsafe { ffi::SQLGetTypeInfoW(self.as_SQLHANDLE(), DataType.identifier()) }
941    }
942
943    /// Determines whether more results are available on a statement containing **SELECT**, **UPDATE**, **INSERT**, or **DELETE** statements and, if so, initializes processing for those results.
944    ///
945    /// For complete documentation on SQLMoreResults, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlmoreresults-function).
946    ///
947    /// # Returns
948    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_NO_DATA, SQL_ERROR, SQL_INVALID_HANDLE, OR SQL_PARAM_DATA_AVAILABLE.
949    #[inline]
950    // TODO: Maybe this fn should be unsafe
951    fn SQLMoreResults(&self) -> SQLRETURN {
952        unsafe { ffi::SQLMoreResults(self.as_SQLHANDLE()) }
953    }
954
955    /// Returns the number of parameters in an SQL statement.
956    ///
957    /// For complete documentation on SQLNumParams, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnumparams-function).
958    ///
959    /// # Returns
960    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
961    #[inline]
962    fn SQLNumParams(&self, ParameterCountPtr: &mut impl AsMutPtr<SQLSMALLINT>) -> SQLRETURN {
963        unsafe { ffi::SQLNumParams(self.as_SQLHANDLE(), ParameterCountPtr.as_mut_ptr()) }
964    }
965
966    /// Returns the number of columns in a result set.
967    ///
968    /// For complete documentation on SQLNumResultCols, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnumresultcols-function).
969    ///
970    /// # Returns
971    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
972    #[inline]
973    fn SQLNumResultCols(&self, ColumnCountPtr: &mut impl AsMutPtr<SQLSMALLINT>) -> SQLRETURN {
974        unsafe { ffi::SQLNumResultCols(self.as_SQLHANDLE(), ColumnCountPtr.as_mut_ptr()) }
975    }
976
977    /// Used together with **SQLPutData** to supply parameter data at statement execution time, and with **SQLGetData** to retrieve streamed output parameter data.
978    ///
979    /// For complete documentation on SQLParamData, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlparamdata-function).
980    ///
981    /// # Returns
982    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
983    #[inline]
984    fn SQLParamData(&self, ValuePtrPtr: &mut MaybeUninit<SQLPOINTER>) -> SQLRETURN {
985        unsafe { ffi::SQLParamData(self.as_SQLHANDLE(), ValuePtrPtr.as_mut_ptr()) }
986    }
987
988    /// Prepares an SQL string for execution.
989    ///
990    /// For complete documentation on SQLPrepareA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function).
991    ///
992    /// # Returns
993    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
994    #[inline]
995    fn SQLPrepareA(&self, StatementText: &OdbcStr<SQLCHAR>) -> SQLRETURN {
996        let StatementText = StatementText.as_raw_slice();
997
998        unsafe { ffi::SQLPrepareA(self.as_SQLHANDLE(), StatementText.0, StatementText.1) }
999    }
1000
1001    /// Prepares an SQL string for execution.
1002    ///
1003    /// For complete documentation on SQLPrepareW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function).
1004    ///
1005    /// # Returns
1006    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1007    #[inline]
1008    fn SQLPrepareW(&self, StatementText: &OdbcStr<SQLWCHAR>) -> SQLRETURN {
1009        let StatementText = StatementText.as_raw_slice();
1010
1011        unsafe { ffi::SQLPrepareW(self.as_SQLHANDLE(), StatementText.0, StatementText.1) }
1012    }
1013
1014    /// Returns the column names that make up the primary key for a table. The driver returns the information as a result set. This function does not support returning primary keys from multiple tables in a single call.
1015    ///
1016    /// For complete documentation on SQLPrimaryKeysA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprimarykeys-function).
1017    ///
1018    /// # Returns
1019    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1020    #[inline]
1021    fn SQLPrimaryKeysA(
1022        &self,
1023        CatalogName: &OdbcStr<SQLCHAR>,
1024        SchemaName: &OdbcStr<SQLCHAR>,
1025        TableName: &OdbcStr<SQLCHAR>,
1026    ) -> SQLRETURN {
1027        let CatalogName = CatalogName.as_raw_slice();
1028        let SchemaName = SchemaName.as_raw_slice();
1029        let TableName = TableName.as_raw_slice();
1030
1031        unsafe {
1032            ffi::SQLPrimaryKeysA(
1033                self.as_SQLHANDLE(),
1034                CatalogName.0,
1035                CatalogName.1,
1036                SchemaName.0,
1037                SchemaName.1,
1038                TableName.0,
1039                TableName.1,
1040            )
1041        }
1042    }
1043
1044    /// Returns the column names that make up the primary key for a table. The driver returns the information as a result set. This function does not support returning primary keys from multiple tables in a single call.
1045    ///
1046    /// For complete documentation on SQLPrimaryKeysW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprimarykeys-function).
1047    ///
1048    /// # Returns
1049    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1050    #[inline]
1051    fn SQLPrimaryKeysW(
1052        &self,
1053        CatalogName: &OdbcStr<SQLWCHAR>,
1054        SchemaName: &OdbcStr<SQLWCHAR>,
1055        TableName: &OdbcStr<SQLWCHAR>,
1056    ) -> SQLRETURN {
1057        let CatalogName = CatalogName.as_raw_slice();
1058        let SchemaName = SchemaName.as_raw_slice();
1059        let TableName = TableName.as_raw_slice();
1060
1061        unsafe {
1062            ffi::SQLPrimaryKeysW(
1063                self.as_SQLHANDLE(),
1064                CatalogName.0,
1065                CatalogName.1,
1066                SchemaName.0,
1067                SchemaName.1,
1068                TableName.0,
1069                TableName.1,
1070            )
1071        }
1072    }
1073
1074    /// Returns the list of input and output parameters, as well as the columns that make up the result set for the specified procedures. The driver returns the information as a result set on the specified statement.
1075    ///
1076    /// For complete documentation on SQLProcedureColumnsA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedurecolumns-function).
1077    ///
1078    /// # Returns
1079    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1080    #[inline]
1081    fn SQLProcedureColumnsA(
1082        &self,
1083        CatalogName: &OdbcStr<SQLCHAR>,
1084        SchemaName: &OdbcStr<SQLCHAR>,
1085        ProcName: &OdbcStr<SQLCHAR>,
1086        ColumnName: &OdbcStr<SQLCHAR>,
1087    ) -> SQLRETURN {
1088        let CatalogName = CatalogName.as_raw_slice();
1089        let SchemaName = SchemaName.as_raw_slice();
1090        let ProcName = ProcName.as_raw_slice();
1091        let ColumnName = ColumnName.as_raw_slice();
1092
1093        unsafe {
1094            ffi::SQLProcedureColumnsA(
1095                self.as_SQLHANDLE(),
1096                CatalogName.0,
1097                CatalogName.1,
1098                SchemaName.0,
1099                SchemaName.1,
1100                ProcName.0,
1101                ProcName.1,
1102                ColumnName.0,
1103                ColumnName.1,
1104            )
1105        }
1106    }
1107
1108    /// Returns the list of input and output parameters, as well as the columns that make up the result set for the specified procedures. The driver returns the information as a result set on the specified statement.
1109    ///
1110    /// For complete documentation on SQLProcedureColumnsW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedurecolumns-function).
1111    ///
1112    /// # Returns
1113    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1114    #[inline]
1115    fn SQLProcedureColumnsW(
1116        &self,
1117        CatalogName: &OdbcStr<SQLWCHAR>,
1118        SchemaName: &OdbcStr<SQLWCHAR>,
1119        ProcName: &OdbcStr<SQLWCHAR>,
1120        ColumnName: &OdbcStr<SQLWCHAR>,
1121    ) -> SQLRETURN {
1122        let CatalogName = CatalogName.as_raw_slice();
1123        let SchemaName = SchemaName.as_raw_slice();
1124        let ProcName = ProcName.as_raw_slice();
1125        let ColumnName = ColumnName.as_raw_slice();
1126
1127        unsafe {
1128            ffi::SQLProcedureColumnsW(
1129                self.as_SQLHANDLE(),
1130                CatalogName.0,
1131                CatalogName.1,
1132                SchemaName.0,
1133                SchemaName.1,
1134                ProcName.0,
1135                ProcName.1,
1136                ColumnName.0,
1137                ColumnName.1,
1138            )
1139        }
1140    }
1141
1142    /// Returns the list of procedure names stored in a specific data source. `Procedure` is a generic term used to describe an `executable object`, or a named entity that can be invoked using input and output parameters. For more information on procedures, see the Procedures.
1143    ///
1144    /// For complete documentation on SQLProceduresA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedures-function).
1145    ///
1146    /// # Returns
1147    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1148    #[inline]
1149    fn SQLProceduresA(
1150        &self,
1151        CatalogName: &OdbcStr<SQLCHAR>,
1152        SchemaName: &OdbcStr<SQLCHAR>,
1153        ProcName: &OdbcStr<SQLCHAR>,
1154    ) -> SQLRETURN {
1155        let CatalogName = CatalogName.as_raw_slice();
1156        let SchemaName = SchemaName.as_raw_slice();
1157        let ProcName = ProcName.as_raw_slice();
1158
1159        unsafe {
1160            ffi::SQLProceduresA(
1161                self.as_SQLHANDLE(),
1162                CatalogName.0,
1163                CatalogName.1,
1164                SchemaName.0,
1165                SchemaName.1,
1166                ProcName.0,
1167                ProcName.1,
1168            )
1169        }
1170    }
1171
1172    /// Returns the list of procedure names stored in a specific data source. `Procedure` is a generic term used to describe an `executable object`, or a named entity that can be invoked using input and output parameters. For more information on procedures, see the Procedures.
1173    ///
1174    /// For complete documentation on SQLProceduresW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprocedures-function).
1175    ///
1176    /// # Returns
1177    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1178    #[inline]
1179    fn SQLProceduresW(
1180        &self,
1181        CatalogName: &OdbcStr<SQLWCHAR>,
1182        SchemaName: &OdbcStr<SQLWCHAR>,
1183        ProcName: &OdbcStr<SQLWCHAR>,
1184    ) -> SQLRETURN {
1185        let CatalogName = CatalogName.as_raw_slice();
1186        let SchemaName = SchemaName.as_raw_slice();
1187        let ProcName = ProcName.as_raw_slice();
1188
1189        unsafe {
1190            ffi::SQLProceduresW(
1191                self.as_SQLHANDLE(),
1192                CatalogName.0,
1193                CatalogName.1,
1194                SchemaName.0,
1195                SchemaName.1,
1196                ProcName.0,
1197                ProcName.1,
1198            )
1199        }
1200    }
1201
1202    /// Allows an application to send data for a parameter or column to the driver at statement execution time. This function can be used to send character or binary data values in parts to a column with a character, binary, or data source-specific data type (for example, parameters of the SQL_LONGVARBINARY or SQL_LONGVARCHAR types). **SQLPutData** supports binding to a Unicode C data type, even if the underlying driver does not support Unicode data.
1203    ///
1204    /// For complete documentation on SQLPutData, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlputdata-function).
1205    ///
1206    /// # Returns
1207    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1208    #[inline]
1209    // TODO: Is it unsafe if odbc_debug is used?
1210    unsafe fn SQLPutData<TT: Ident, B: CData<TT, V>>(&self, DataPtr: Option<&B>) -> SQLRETURN
1211    where
1212        B: AsSQLPOINTER + ?Sized,
1213    {
1214        let DataPtr = DataPtr.map_or((ptr::null_mut(), 0), |DataPtr| {
1215            (DataPtr.as_SQLPOINTER(), DataPtr.len())
1216        });
1217
1218        ffi::SQLPutData(self.as_SQLHANDLE(), DataPtr.0, DataPtr.1)
1219    }
1220
1221    /// Returns the number of rows affected by an **UPDATE**, **INSERT**, or **DELETE** statement; an SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK operation in **SQLBulkOperations**; or an SQL_UPDATE or SQL_DELETE operation in **SQLSetPos**.
1222    ///
1223    /// For complete documentation on SQLRowCount, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlrowcount-function).
1224    ///
1225    /// # Returns
1226    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1227    #[inline]
1228    fn SQLRowCount(&self, RowCountPtr: &mut impl AsMutPtr<SQLLEN>) -> SQLRETURN {
1229        unsafe { ffi::SQLRowCount(self.as_SQLHANDLE(), RowCountPtr.as_mut_ptr()) }
1230    }
1231
1232    /// Associates a cursor name with an active statement. If an application does not call **SQLSetCursorName**, the driver generates cursor names as needed for SQL statement processing.
1233    ///
1234    /// For complete documentation on SQLSetCursorNameA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetcursorname-function).
1235    ///
1236    /// # Returns
1237    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1238    #[inline]
1239    fn SQLSetCursorNameA(&self, CursorName: &OdbcStr<SQLCHAR>) -> SQLRETURN {
1240        let CursorName = CursorName.as_raw_slice();
1241
1242        unsafe { ffi::SQLSetCursorNameA(self.as_SQLHANDLE(), CursorName.0, CursorName.1) }
1243    }
1244
1245    /// Associates a cursor name with an active statement. If an application does not call **SQLSetCursorName**, the driver generates cursor names as needed for SQL statement processing.
1246    ///
1247    /// For complete documentation on SQLSetCursorNameW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetcursorname-function).
1248    ///
1249    /// # Returns
1250    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1251    #[inline]
1252    fn SQLSetCursorNameW(&self, CursorName: &OdbcStr<SQLWCHAR>) -> SQLRETURN {
1253        let CursorName = CursorName.as_raw_slice();
1254
1255        unsafe { ffi::SQLSetCursorNameW(self.as_SQLHANDLE(), CursorName.0, CursorName.1) }
1256    }
1257
1258    /// Sets attributes related to a statement.
1259    ///
1260    /// For complete documentation on SQLSetStmtAttrA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetstmtattr-function).
1261    ///
1262    /// # Returns
1263    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1264    #[inline]
1265    fn SQLSetStmtAttrA<A: Ident<Type = SQLINTEGER>, T: StmtAttr<'desc, 'buf, Self, A, V>>(
1266        &self,
1267        Attribute: A,
1268        ValuePtr: T,
1269    ) -> SQLRETURN
1270    where
1271        T: AttrSet<A> + Ansi,
1272    {
1273        SQLSetStmtAttrA(self, Attribute, ValuePtr)
1274    }
1275
1276    /// Sets attributes related to a statement.
1277    ///
1278    /// For complete documentation on SQLSetStmtAttrW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetstmtattr-function).
1279    ///
1280    /// # Returns
1281    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1282    #[inline]
1283    fn SQLSetStmtAttrW<A: Ident<Type = SQLINTEGER>, T: StmtAttr<'desc, 'buf, Self, A, V>>(
1284        &self,
1285        Attribute: A,
1286        ValuePtr: T,
1287    ) -> SQLRETURN
1288    where
1289        T: AttrSet<A> + Unicode,
1290    {
1291        SQLSetStmtAttrW(self, Attribute, ValuePtr)
1292    }
1293
1294    /// Retrieves the following information about columns within a specified table:
1295    ///
1296    /// * The optimal set of columns that uniquely identifies a row in the table.
1297    /// * Columns that are automatically updated when any value in the row is updated by a transaction.
1298    ///
1299    /// For complete documentation on SQLSpecialColumnsA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlspecialcolumns-function).
1300    ///
1301    /// # Returns
1302    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1303    #[inline]
1304    fn SQLSpecialColumnsA(
1305        &self,
1306        IdentifierType: IdentifierType,
1307        CatalogName: &OdbcStr<SQLCHAR>,
1308        SchemaName: &OdbcStr<SQLCHAR>,
1309        TableName: &OdbcStr<SQLCHAR>,
1310        Scope: Scope,
1311        Nullable: NullAllowed,
1312    ) -> SQLRETURN {
1313        let CatalogName = CatalogName.as_raw_slice();
1314        let SchemaName = SchemaName.as_raw_slice();
1315        let TableName = TableName.as_raw_slice();
1316
1317        unsafe {
1318            ffi::SQLSpecialColumnsA(
1319                self.as_SQLHANDLE(),
1320                IdentifierType as SQLSMALLINT,
1321                CatalogName.0,
1322                CatalogName.1,
1323                SchemaName.0,
1324                SchemaName.1,
1325                TableName.0,
1326                TableName.1,
1327                Scope as SQLSMALLINT,
1328                Nullable.identifier(),
1329            )
1330        }
1331    }
1332
1333    /// Retrieves the following information about columns within a specified table:
1334    ///
1335    /// * The optimal set of columns that uniquely identifies a row in the table.
1336    /// * Columns that are automatically updated when any value in the row is updated by a transaction.
1337    ///
1338    /// For complete documentation on SQLSpecialColumnsW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlspecialcolumns-function).
1339    ///
1340    /// # Returns
1341    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1342    #[inline]
1343    fn SQLSpecialColumnsW(
1344        &self,
1345        IdentifierType: IdentifierType,
1346        CatalogName: &OdbcStr<SQLWCHAR>,
1347        SchemaName: &OdbcStr<SQLWCHAR>,
1348        TableName: &OdbcStr<SQLWCHAR>,
1349        Scope: Scope,
1350        Nullable: NullAllowed,
1351    ) -> SQLRETURN {
1352        let CatalogName = CatalogName.as_raw_slice();
1353        let SchemaName = SchemaName.as_raw_slice();
1354        let TableName = TableName.as_raw_slice();
1355
1356        unsafe {
1357            ffi::SQLSpecialColumnsW(
1358                self.as_SQLHANDLE(),
1359                IdentifierType as SQLSMALLINT,
1360                CatalogName.0,
1361                CatalogName.1,
1362                SchemaName.0,
1363                SchemaName.1,
1364                TableName.0,
1365                TableName.1,
1366                Scope as SQLSMALLINT,
1367                Nullable.identifier(),
1368            )
1369        }
1370    }
1371
1372    /// Retrieves a list of statistics about a single table and the indexes associated with the table. The driver returns the information as a result set.
1373    ///
1374    /// For complete documentation on SQLStatisticsA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlstatistics-function).
1375    ///
1376    /// # Returns
1377    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1378    #[inline]
1379    fn SQLStatisticsA(
1380        &self,
1381        CatalogName: &OdbcStr<SQLCHAR>,
1382        SchemaName: &OdbcStr<SQLCHAR>,
1383        TableName: &OdbcStr<SQLCHAR>,
1384        Unique: Unique,
1385        Reserved: Reserved,
1386    ) -> SQLRETURN {
1387        let CatalogName = CatalogName.as_raw_slice();
1388        let SchemaName = SchemaName.as_raw_slice();
1389        let TableName = TableName.as_raw_slice();
1390
1391        unsafe {
1392            ffi::SQLStatisticsA(
1393                self.as_SQLHANDLE(),
1394                CatalogName.0,
1395                CatalogName.1,
1396                SchemaName.0,
1397                SchemaName.1,
1398                TableName.0,
1399                TableName.1,
1400                Unique as SQLUSMALLINT,
1401                Reserved as SQLUSMALLINT,
1402            )
1403        }
1404    }
1405
1406    /// Retrieves a list of statistics about a single table and the indexes associated with the table. The driver returns the information as a result set.
1407    ///
1408    /// For complete documentation on SQLStatisticsW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlstatistics-function).
1409    ///
1410    /// # Returns
1411    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1412    #[inline]
1413    fn SQLStatisticsW(
1414        &self,
1415        CatalogName: &OdbcStr<SQLWCHAR>,
1416        SchemaName: &OdbcStr<SQLWCHAR>,
1417        TableName: &OdbcStr<SQLWCHAR>,
1418        Unique: Unique,
1419        Reserved: Reserved,
1420    ) -> SQLRETURN {
1421        let CatalogName = CatalogName.as_raw_slice();
1422        let SchemaName = SchemaName.as_raw_slice();
1423        let TableName = TableName.as_raw_slice();
1424
1425        unsafe {
1426            ffi::SQLStatisticsW(
1427                self.as_SQLHANDLE(),
1428                CatalogName.0,
1429                CatalogName.1,
1430                SchemaName.0,
1431                SchemaName.1,
1432                TableName.0,
1433                TableName.1,
1434                Unique as SQLUSMALLINT,
1435                Reserved as SQLUSMALLINT,
1436            )
1437        }
1438    }
1439
1440    /// Returns a list of tables and the privileges associated with each table. The driver returns the information as a result set on the specified statement.
1441    ///
1442    /// For complete documentation on SQLTablePrivilegesA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltableprivileges-function).
1443    ///
1444    /// # Returns
1445    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1446    #[inline]
1447    fn SQLTablePrivilegesA(
1448        &self,
1449        CatalogName: &OdbcStr<SQLCHAR>,
1450        SchemaName: &OdbcStr<SQLCHAR>,
1451        TableName: &OdbcStr<SQLCHAR>,
1452    ) -> SQLRETURN {
1453        let CatalogName = CatalogName.as_raw_slice();
1454        let SchemaName = SchemaName.as_raw_slice();
1455        let TableName = TableName.as_raw_slice();
1456
1457        unsafe {
1458            ffi::SQLTablePrivilegesA(
1459                self.as_SQLHANDLE(),
1460                CatalogName.0,
1461                CatalogName.1,
1462                SchemaName.0,
1463                SchemaName.1,
1464                TableName.0,
1465                TableName.1,
1466            )
1467        }
1468    }
1469
1470    /// Returns a list of tables and the privileges associated with each table. The driver returns the information as a result set on the specified statement.
1471    ///
1472    /// For complete documentation on SQLTablePrivilegesW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltableprivileges-function).
1473    ///
1474    /// # Returns
1475    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1476    #[inline]
1477    fn SQLTablePrivilegesW(
1478        &self,
1479        CatalogName: &OdbcStr<SQLWCHAR>,
1480        SchemaName: &OdbcStr<SQLWCHAR>,
1481        TableName: &OdbcStr<SQLWCHAR>,
1482    ) -> SQLRETURN {
1483        let CatalogName = CatalogName.as_raw_slice();
1484        let SchemaName = SchemaName.as_raw_slice();
1485        let TableName = TableName.as_raw_slice();
1486
1487        unsafe {
1488            ffi::SQLTablePrivilegesW(
1489                self.as_SQLHANDLE(),
1490                CatalogName.0,
1491                CatalogName.1,
1492                SchemaName.0,
1493                SchemaName.1,
1494                TableName.0,
1495                TableName.1,
1496            )
1497        }
1498    }
1499
1500    /// Returns the list of table, catalog, or schema names, and table types, stored in a specific data source. The driver returns the information as a result set.
1501    ///
1502    /// For complete documentation on SQLTablesA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltables-function).
1503    ///
1504    /// # Returns
1505    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1506    #[inline]
1507    fn SQLTablesA(
1508        &self,
1509        CatalogName: &OdbcStr<SQLCHAR>,
1510        SchemaName: &OdbcStr<SQLCHAR>,
1511        TableName: &OdbcStr<SQLCHAR>,
1512        TableType: &OdbcStr<SQLCHAR>,
1513    ) -> SQLRETURN {
1514        let CatalogName = CatalogName.as_raw_slice();
1515        let SchemaName = SchemaName.as_raw_slice();
1516        let TableName = TableName.as_raw_slice();
1517        let TableType = TableType.as_raw_slice();
1518
1519        unsafe {
1520            ffi::SQLTablesA(
1521                self.as_SQLHANDLE(),
1522                CatalogName.0,
1523                CatalogName.1,
1524                SchemaName.0,
1525                SchemaName.1,
1526                TableName.0,
1527                TableName.1,
1528                TableType.0,
1529                TableType.1,
1530            )
1531        }
1532    }
1533
1534    /// Returns the list of table, catalog, or schema names, and table types, stored in a specific data source. The driver returns the information as a result set.
1535    ///
1536    /// For complete documentation on SQLTablesW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltables-function).
1537    ///
1538    /// # Returns
1539    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
1540    #[inline]
1541    fn SQLTablesW(
1542        &self,
1543        CatalogName: &OdbcStr<SQLWCHAR>,
1544        SchemaName: &OdbcStr<SQLWCHAR>,
1545        TableName: &OdbcStr<SQLWCHAR>,
1546        TableType: &OdbcStr<SQLWCHAR>,
1547    ) -> SQLRETURN {
1548        let CatalogName = CatalogName.as_raw_slice();
1549        let SchemaName = SchemaName.as_raw_slice();
1550        let TableName = TableName.as_raw_slice();
1551        let TableType = TableType.as_raw_slice();
1552
1553        unsafe {
1554            ffi::SQLTablesW(
1555                self.as_SQLHANDLE(),
1556                CatalogName.0,
1557                CatalogName.1,
1558                SchemaName.0,
1559                SchemaName.1,
1560                TableName.0,
1561                TableName.1,
1562                TableType.0,
1563                TableType.1,
1564            )
1565        }
1566    }
1567}
1568
1569#[allow(non_snake_case)]
1570pub trait Descriptor<'buf, DT, V: OdbcVersion>: Handle {
1571    /// Copies descriptor information from one descriptor handle to another.
1572    ///
1573    /// For complete documentation on SQLCopyDesc, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcopydesc-function).
1574    ///
1575    /// # Returns
1576    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1577    #[inline]
1578    // TODO: Not sure if application and implementation descriptors can be interchangeably copied
1579    // TODO: Do they have to have the same version?
1580    // TODO: Is lifetime the same?
1581    fn SQLCopyDesc<DT2: DescType<'buf>>(&self, TargetDescHandle: &SQLHDESC<DT2, V>) -> SQLRETURN {
1582        unsafe { ffi::SQLCopyDesc(self.as_SQLHANDLE(), TargetDescHandle.as_SQLHANDLE()) }
1583    }
1584
1585    /// Returns the current setting or value of a single field of a descriptor record.
1586    ///
1587    /// For complete documentation on SQLGetDescFieldA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescfield-function).
1588    ///
1589    /// # Returns
1590    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
1591    #[inline]
1592    #[allow(unused_variables)]
1593    fn SQLGetDescFieldA<A: Ident<Type = SQLSMALLINT>, T: DescField<'buf, Self, DT, A, V>>(
1594        &self,
1595        RecNumber: SQLSMALLINT,
1596        FieldIdentifier: A,
1597        ValuePtr: Option<&mut T>,
1598        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
1599    ) -> SQLRETURN
1600    where
1601        T: AttrGet<A> + Ansi + ?Sized,
1602        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
1603    {
1604        let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
1605            if cfg!(feature = "odbc_debug") {
1606                ValuePtr.assert_zeroed();
1607            }
1608
1609            (ValuePtr.as_mut_SQLPOINTER(), ValuePtr.len())
1610        });
1611
1612        unsafe {
1613            ffi::SQLGetDescFieldA(
1614                self.as_SQLHANDLE(),
1615                RecNumber,
1616                A::IDENTIFIER,
1617                ValuePtr.0,
1618                ValuePtr.1,
1619                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
1620            )
1621        }
1622    }
1623
1624    /// Returns the current setting or value of a single field of a descriptor record.
1625    ///
1626    /// For complete documentation on SQLGetDescFieldW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescfield-function).
1627    ///
1628    /// # Returns
1629    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
1630    #[inline]
1631    #[allow(unused_variables)]
1632    fn SQLGetDescFieldW<A: Ident<Type = SQLSMALLINT>, T: DescField<'buf, Self, DT, A, V>>(
1633        &self,
1634        RecNumber: SQLSMALLINT,
1635        FieldIdentifier: A,
1636        ValuePtr: Option<&mut T>,
1637        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
1638    ) -> SQLRETURN
1639    where
1640        T: AttrGet<A> + Unicode + ?Sized,
1641        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
1642    {
1643        let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
1644            if cfg!(feature = "odbc_debug") {
1645                ValuePtr.assert_zeroed();
1646            }
1647
1648            (ValuePtr.as_mut_SQLPOINTER(), ValuePtr.len())
1649        });
1650
1651        unsafe {
1652            ffi::SQLGetDescFieldW(
1653                self.as_SQLHANDLE(),
1654                RecNumber,
1655                A::IDENTIFIER,
1656                ValuePtr.0,
1657                ValuePtr.1,
1658                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
1659            )
1660        }
1661    }
1662
1663    /// Returns the current settings or values of multiple fields of a descriptor record. The fields returned describe the name, data type, and storage of column or parameter data.
1664    ///
1665    /// For complete documentation on SQLGetDescRecA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescrec-function).
1666    ///
1667    /// # Returns
1668    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
1669    #[inline]
1670    fn SQLGetDescRecA<ST: SqlType<V>>(
1671        &self,
1672        RecNumber: SQLSMALLINT,
1673        Name: Option<&mut OdbcStr<MaybeUninit<SQLCHAR>>>,
1674        StringLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1675        TypePtr: &mut impl AsMutPtr<ST>,
1676        SubTypePtr: &mut impl AsMutPtr<DatetimeIntervalCode>,
1677        LengthPtr: &mut impl AsMutPtr<SQLLEN>,
1678        PrecisionPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1679        ScalePtr: &mut impl AsMutPtr<SQLSMALLINT>,
1680        NullablePtr: &mut impl AsMutPtr<NullAllowed>,
1681    ) -> SQLRETURN {
1682        let Name = Name.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
1683
1684        unsafe {
1685            ffi::SQLGetDescRecA(
1686                self.as_SQLHANDLE(),
1687                RecNumber,
1688                Name.0,
1689                Name.1,
1690                StringLengthPtr.as_mut_ptr(),
1691                TypePtr.as_mut_ptr().cast(),
1692                SubTypePtr.as_mut_ptr().cast(),
1693                LengthPtr.as_mut_ptr(),
1694                PrecisionPtr.as_mut_ptr(),
1695                ScalePtr.as_mut_ptr(),
1696                NullablePtr.as_mut_ptr().cast(),
1697            )
1698        }
1699    }
1700
1701    /// Returns the current settings or values of multiple fields of a descriptor record. The fields returned describe the name, data type, and storage of column or parameter data.
1702    ///
1703    /// For complete documentation on SQLGetDescRecW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdescrec-function).
1704    ///
1705    /// # Returns
1706    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
1707    #[inline]
1708    fn SQLGetDescRecW<ST: SqlType<V>>(
1709        &self,
1710        RecNumber: SQLSMALLINT,
1711        Name: Option<&mut OdbcStr<MaybeUninit<SQLWCHAR>>>,
1712        StringLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1713        TypePtr: &mut impl AsMutPtr<ST>,
1714        SubTypePtr: &mut impl AsMutPtr<DatetimeIntervalCode>,
1715        LengthPtr: &mut impl AsMutPtr<SQLLEN>,
1716        PrecisionPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1717        ScalePtr: &mut impl AsMutPtr<SQLSMALLINT>,
1718        NullablePtr: &mut impl AsMutPtr<NullAllowed>,
1719    ) -> SQLRETURN {
1720        let Name = Name.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
1721
1722        unsafe {
1723            ffi::SQLGetDescRecW(
1724                self.as_SQLHANDLE(),
1725                RecNumber,
1726                Name.0,
1727                Name.1,
1728                StringLengthPtr.as_mut_ptr(),
1729                TypePtr.as_mut_ptr().cast(),
1730                SubTypePtr.as_mut_ptr().cast(),
1731                LengthPtr.as_mut_ptr(),
1732                PrecisionPtr.as_mut_ptr(),
1733                ScalePtr.as_mut_ptr(),
1734                NullablePtr.as_mut_ptr().cast(),
1735            )
1736        }
1737    }
1738
1739    /// Sets the value of a single field of a descriptor record.
1740    ///
1741    /// For complete documentation on SQLSetDescFieldA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetdescfield-function).
1742    ///
1743    /// # Returns
1744    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1745    #[inline]
1746    #[allow(unused_variables)]
1747    fn SQLSetDescFieldA<A: Ident<Type = SQLSMALLINT>, T: DescField<'buf, Self, DT, A, V>>(
1748        &self,
1749        RecNumber: SQLSMALLINT,
1750        FieldIdentifier: A,
1751        ValuePtr: Option<T>,
1752    ) -> SQLRETURN
1753    where
1754        T: AttrSet<A> + Ansi,
1755    {
1756        let sql_return = unsafe {
1757            let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
1758                (ValuePtr.into_SQLPOINTER(), ValuePtr.len())
1759            });
1760
1761            ffi::SQLSetDescFieldA(
1762                self.as_SQLHANDLE(),
1763                RecNumber,
1764                A::IDENTIFIER,
1765                ValuePtr.0,
1766                ValuePtr.1,
1767            )
1768        };
1769
1770        if SQL_SUCCEEDED(sql_return) {
1771            ValuePtr.map(|v| v.update_handle(self));
1772        }
1773
1774        sql_return
1775    }
1776
1777    /// Sets the value of a single field of a descriptor record.
1778    ///
1779    /// For complete documentation on SQLSetDescFieldW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetdescfield-function).
1780    ///
1781    /// # Returns
1782    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1783    #[inline]
1784    #[allow(unused_variables)]
1785    fn SQLSetDescFieldW<A: Ident<Type = SQLSMALLINT>, T: DescField<'buf, Self, DT, A, V>>(
1786        &self,
1787        RecNumber: SQLSMALLINT,
1788        FieldIdentifier: A,
1789        ValuePtr: Option<T>,
1790    ) -> SQLRETURN
1791    where
1792        T: AttrSet<A> + Unicode,
1793    {
1794        let sql_return = unsafe {
1795            let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
1796                (ValuePtr.into_SQLPOINTER(), ValuePtr.len())
1797            });
1798
1799            ffi::SQLSetDescFieldW(
1800                self.as_SQLHANDLE(),
1801                RecNumber,
1802                A::IDENTIFIER,
1803                ValuePtr.0,
1804                ValuePtr.1,
1805            )
1806        };
1807
1808        if SQL_SUCCEEDED(sql_return) {
1809            ValuePtr.map(|v| v.update_handle(self));
1810        }
1811
1812        sql_return
1813    }
1814
1815    /// Sets multiple descriptor fields that affect the data type and buffer bound to a column or parameter data.
1816    ///
1817    /// For complete documentation on SQLSetDescRec, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetdescrec-function).
1818    ///
1819    /// # Returns
1820    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1821    #[inline]
1822    // TODO: Must not be allowed for IRD. Handle here or with DescField
1823    fn SQLSetDescRec<ST: SqlType<V>, PTR>(
1824        &self,
1825        RecNumber: SQLSMALLINT,
1826        Type: ST,
1827        SubType: Option<DatetimeIntervalCode>,
1828        Length: SQLLEN,
1829        Precision: SQLSMALLINT,
1830        Scale: SQLSMALLINT,
1831        // TODO: Input or Output for both? I guess it depends on which descriptor was given
1832        DataPtr: Option<&'buf PTR>,
1833        // TODO: Shouldn't following two be UnsafeCell
1834        StringLengthPtr: &'buf mut impl AsMutPtr<SQLLEN>,
1835        IndicatorPtr: &'buf mut impl AsMutPtr<SQLLEN>,
1836    ) -> SQLRETURN
1837    where
1838        &'buf PTR: IntoSQLPOINTER,
1839    {
1840        unsafe {
1841            ffi::SQLSetDescRec(
1842                self.as_SQLHANDLE(),
1843                RecNumber,
1844                Type.identifier(),
1845                SubType.map_or(0, |v| v.identifier()),
1846                Length,
1847                Precision,
1848                Scale,
1849                DataPtr.map_or_else(ptr::null_mut, IntoSQLPOINTER::into_SQLPOINTER),
1850                StringLengthPtr.as_mut_ptr(),
1851                IndicatorPtr.as_mut_ptr(),
1852            )
1853        }
1854    }
1855}
1856
1857#[allow(non_snake_case)]
1858pub trait Cancel<V: OdbcVersion>: Handle {
1859    /// Cancels the processing on a statement.
1860    /// To cancel processing on a connection or statement, use SQLCancelHandle Function.
1861    ///
1862    /// For complete documentation on SQLCancel, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcancel-function).
1863    ///
1864    /// # Returns
1865    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1866    #[inline]
1867    fn SQLCancel(&self) -> SQLRETURN
1868    where
1869        Self: Handle<Ident = SQL_HANDLE_STMT>,
1870    {
1871        unsafe { ffi::SQLCancel(self.as_SQLHANDLE()) }
1872    }
1873
1874    /// Cancels the processing on a connection or statement. The Driver Manager maps a call to **SQLCancelHandle** to a call to **SQLCancel** when `HandleType` is SQL_HANDLE_STMT.
1875    ///
1876    /// For complete documentation on SQLCancelHandle, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcancelhandle-function).
1877    ///
1878    /// # Returns
1879    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
1880    #[inline]
1881    fn SQLCancelHandle(&self) -> SQLRETURN {
1882        unsafe { ffi::SQLCancelHandle(<Self as Handle>::Ident::IDENTIFIER, self.as_SQLHANDLE()) }
1883    }
1884}
1885
1886#[allow(non_snake_case)]
1887pub trait Async<V: OdbcVersion>: Handle {
1888    /// Can be used to determine when an asynchronous function is complete using either notification- or polling-based processing. For more information about asynchronous operations, see Asynchronous Execution.
1889    /// **SQLCompleteAsync** is only implemented in the ODBC Driver Manager.
1890    /// In notification based asynchronous processing mode, **SQLCompleteAsync** must be called after the Driver Manager raises the event object used for notification. **SQLCompleteAsync** completes the asynchronous processing and the asynchronous function will generate a return code.
1891    /// In polling based asynchronous processing mode, **SQLCompleteAsync** is an alternative to calling the original asynchronous function, without needing to specify the arguments in the original asynchronous function call. **SQLCompleteAsync** can be used regardless whether the ODBC Cursor Library is enabled.
1892    ///
1893    /// For complete documentation on SQLCompleteAsync, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcompleteasync-function).
1894    ///
1895    /// # Returns
1896    /// SQL_SUCCESS, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE.
1897    #[inline]
1898    // TODO: Should this handle be mutable or not?
1899    fn SQLCompleteAsync(&mut self, AsyncRetCodePtr: &mut impl AsMutPtr<RETCODE>) -> SQLRETURN {
1900        unsafe {
1901            ffi::SQLCompleteAsync(
1902                Self::Ident::IDENTIFIER,
1903                self.as_SQLHANDLE(),
1904                AsyncRetCodePtr.as_mut_ptr(),
1905            )
1906        }
1907    }
1908}
1909
1910#[allow(non_snake_case)]
1911impl<V: OdbcVersion> SQLHENV<V> {
1912    /// Returns information about a data source. This function is implemented only by the Driver Manager.
1913    ///
1914    /// For complete documentation on SQLDataSourcesA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldatasources-function).
1915    ///
1916    /// # Returns
1917    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
1918    #[inline]
1919    pub fn SQLDataSourcesA(
1920        &self,
1921        Direction: SQLUSMALLINT,
1922        ServerName: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
1923        NameLength1Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
1924        Description: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
1925        NameLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
1926    ) -> SQLRETURN {
1927        let ServerName = ServerName.as_mut_raw_slice();
1928        let Description = Description.as_mut_raw_slice();
1929
1930        unsafe {
1931            ffi::SQLDataSourcesA(
1932                self.as_SQLHANDLE(),
1933                Direction,
1934                ServerName.0,
1935                ServerName.1,
1936                NameLength1Ptr.as_mut_ptr(),
1937                Description.0,
1938                Description.1,
1939                NameLength2Ptr.as_mut_ptr(),
1940            )
1941        }
1942    }
1943
1944    /// Returns information about a data source. This function is implemented only by the Driver Manager.
1945    ///
1946    /// For complete documentation on SQLDataSourcesW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldatasources-function).
1947    ///
1948    /// # Returns
1949    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
1950    #[inline]
1951    pub fn SQLDataSourcesW(
1952        &self,
1953        Direction: SQLUSMALLINT,
1954        ServerName: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
1955        NameLength1Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
1956        Description: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
1957        NameLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
1958    ) -> SQLRETURN {
1959        let ServerName = ServerName.as_mut_raw_slice();
1960        let Description = Description.as_mut_raw_slice();
1961
1962        unsafe {
1963            ffi::SQLDataSourcesW(
1964                self.as_SQLHANDLE(),
1965                Direction,
1966                ServerName.0,
1967                ServerName.1,
1968                NameLength1Ptr.as_mut_ptr(),
1969                Description.0,
1970                Description.1,
1971                NameLength2Ptr.as_mut_ptr(),
1972            )
1973        }
1974    }
1975
1976    /// Lists driver descriptions and driver attribute keywords. This function is implemented only by the Driver Manager.
1977    ///
1978    /// For complete documentation on SQLDriversA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldrivers-function).
1979    ///
1980    /// # Returns
1981    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
1982    #[inline]
1983    pub fn SQLDriversA(
1984        &self,
1985        Direction: SQLUSMALLINT,
1986        DriverDescription: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
1987        DescriptionLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1988        DriverAttributes: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
1989        AttributesLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
1990    ) -> SQLRETURN {
1991        let DriverDescription = DriverDescription.as_mut_raw_slice();
1992        let DriverAttributes = DriverAttributes.as_mut_raw_slice();
1993
1994        unsafe {
1995            ffi::SQLDriversA(
1996                self.as_SQLHANDLE(),
1997                Direction,
1998                DriverDescription.0,
1999                DriverDescription.1,
2000                DescriptionLengthPtr.as_mut_ptr(),
2001                DriverAttributes.0,
2002                DriverAttributes.1,
2003                AttributesLengthPtr.as_mut_ptr(),
2004            )
2005        }
2006    }
2007
2008    /// Lists driver descriptions and driver attribute keywords. This function is implemented only by the Driver Manager.
2009    ///
2010    /// For complete documentation on SQLDriversW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldrivers-function).
2011    ///
2012    /// # Returns
2013    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
2014    #[inline]
2015    pub fn SQLDriversW(
2016        &self,
2017        Direction: SQLUSMALLINT,
2018        DriverDescription: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
2019        DescriptionLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
2020        DriverAttributes: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
2021        AttributesLengthPtr: &mut impl AsMutPtr<SQLSMALLINT>,
2022    ) -> SQLRETURN {
2023        let DriverDescription = DriverDescription.as_mut_raw_slice();
2024        let DriverAttributes = DriverAttributes.as_mut_raw_slice();
2025
2026        unsafe {
2027            ffi::SQLDriversW(
2028                self.as_SQLHANDLE(),
2029                Direction,
2030                DriverDescription.0,
2031                DriverDescription.1,
2032                DescriptionLengthPtr.as_mut_ptr(),
2033                DriverAttributes.0,
2034                DriverAttributes.1,
2035                AttributesLengthPtr.as_mut_ptr(),
2036            )
2037        }
2038    }
2039
2040    /// Returns the current setting of an environment attribute.
2041    ///
2042    /// For complete documentation on SQLGetEnvAttr, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetenvattr-function).
2043    ///
2044    /// # Returns
2045    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
2046    #[inline]
2047    #[allow(unused_variables)]
2048    pub fn SQLGetEnvAttr<A: Ident<Type = SQLINTEGER>, T: EnvAttr<A, V>>(
2049        &self,
2050        Attribute: A,
2051        ValuePtr: Option<&mut T>,
2052        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2053    ) -> SQLRETURN
2054    where
2055        T: AttrGet<A> + ?Sized,
2056        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
2057    {
2058        let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
2059            (ValuePtr.as_mut_SQLPOINTER(), ValuePtr.len())
2060        });
2061
2062        unsafe {
2063            ffi::SQLGetEnvAttr(
2064                self.as_SQLHANDLE(),
2065                A::IDENTIFIER,
2066                ValuePtr.0,
2067                ValuePtr.1,
2068                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
2069            )
2070        }
2071    }
2072
2073    /// Sets attributes that govern aspects of environments.
2074    ///
2075    /// For complete documentation on SQLSetEnvAttr, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetenvattr-function).
2076    ///
2077    /// # Returns
2078    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2079    #[inline]
2080    #[allow(unused_variables)]
2081    pub fn SQLSetEnvAttr<A: Ident<Type = SQLINTEGER>, T: EnvAttr<A, V>>(
2082        // Reference to SQLHENV is mutable to make it impossible to have a connection
2083        // handle allocated on the environment handle when calling this function
2084        &mut self,
2085        Attribute: A,
2086        ValuePtr: T,
2087    ) -> SQLRETURN
2088    where
2089        T: AttrSet<A>,
2090    {
2091        unsafe {
2092            ffi::SQLSetEnvAttr(
2093                self.as_SQLHANDLE(),
2094                A::IDENTIFIER,
2095                ValuePtr.into_SQLPOINTER(),
2096                ValuePtr.len(),
2097            )
2098        }
2099    }
2100}
2101
2102#[allow(non_snake_case)]
2103impl<'env, C: ConnState, V: OdbcVersion> SQLHDBC<'env, C, V> {
2104    /// Supports an iterative method of discovering and enumerating the attributes and attribute values required to connect to a data source. Each call to **SQLBrowseConnect** returns successive levels of attributes and attribute values. When all levels have been enumerated, a connection to the data source is completed and a complete connection string is returned by **SQLBrowseConnect**. A return code of SQL_SUCCESS or SQL_SUCCESS_WITH_INFO indicates that all connection information has been specified and the application is now connected to the data source.
2105    ///
2106    /// For complete documentation on SQLBrowseConnectA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbrowseconnect-function).
2107    ///
2108    /// # Returns
2109    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2110    #[inline]
2111    #[allow(unused_variables)]
2112    pub fn SQLBrowseConnectA(
2113        self,
2114        InConnectionString: &OdbcStr<SQLCHAR>,
2115        OutConnectionString: Option<&mut OdbcStr<MaybeUninit<SQLCHAR>>>,
2116        StringLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
2117    ) -> (
2118        Result<SQLHDBC<'env, C4, V>, Result<SQLHDBC<'env, C3, V>, SQLHDBC<'env, C2, V>>>,
2119        SQLRETURN,
2120    )
2121    where
2122        Self: BrowseConnect,
2123    {
2124        let InConnectionString = InConnectionString.as_raw_slice();
2125        let OutConnectionString =
2126            OutConnectionString.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
2127
2128        let sql_return = unsafe {
2129            ffi::SQLBrowseConnectA(
2130                self.as_SQLHANDLE(),
2131                InConnectionString.0,
2132                InConnectionString.1,
2133                OutConnectionString.0,
2134                OutConnectionString.1,
2135                StringLength2Ptr.as_mut_ptr(),
2136            )
2137        };
2138
2139        if SQL_SUCCEEDED(sql_return) {
2140            (Ok(self.connect()), sql_return)
2141        } else if sql_return == SQL_NEED_DATA {
2142            (Err(Ok(self.need_data())), sql_return)
2143        } else if sql_return == SQL_STILL_EXECUTING {
2144            unimplemented!("Asynchronous execution not supported")
2145        } else {
2146            (Err(Err(self.disconnect())), sql_return)
2147        }
2148    }
2149
2150    /// Supports an iterative method of discovering and enumerating the attributes and attribute values required to connect to a data source. Each call to **SQLBrowseConnect** returns successive levels of attributes and attribute values. When all levels have been enumerated, a connection to the data source is completed and a complete connection string is returned by **SQLBrowseConnect**. A return code of SQL_SUCCESS or SQL_SUCCESS_WITH_INFO indicates that all connection information has been specified and the application is now connected to the data source.
2151    ///
2152    /// For complete documentation on SQLBrowseConnectW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbrowseconnect-function).
2153    ///
2154    /// # Returns
2155    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2156    #[inline]
2157    pub fn SQLBrowseConnectW(
2158        self,
2159        InConnectionString: &OdbcStr<SQLWCHAR>,
2160        OutConnectionString: Option<&mut OdbcStr<MaybeUninit<SQLWCHAR>>>,
2161        StringLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
2162    ) -> (
2163        Result<SQLHDBC<'env, C4, V>, Result<SQLHDBC<'env, C3, V>, SQLHDBC<'env, C2, V>>>,
2164        SQLRETURN,
2165    )
2166    where
2167        Self: BrowseConnect,
2168    {
2169        let InConnectionString = InConnectionString.as_raw_slice();
2170        let OutConnectionString =
2171            OutConnectionString.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
2172
2173        let sql_return = unsafe {
2174            ffi::SQLBrowseConnectW(
2175                self.as_SQLHANDLE(),
2176                InConnectionString.0,
2177                InConnectionString.1,
2178                OutConnectionString.0,
2179                OutConnectionString.1,
2180                StringLength2Ptr.as_mut_ptr(),
2181            )
2182        };
2183
2184        if SQL_SUCCEEDED(sql_return) {
2185            (Ok(self.connect()), sql_return)
2186        } else if sql_return == SQL_NEED_DATA {
2187            (Err(Ok(self.need_data())), sql_return)
2188        } else if sql_return == SQL_STILL_EXECUTING {
2189            unimplemented!("Asynchronous execution not supported")
2190        } else {
2191            (Err(Err(self.disconnect())), sql_return)
2192        }
2193    }
2194
2195    /// Closes the connection associated with a specific connection handle.
2196    ///
2197    /// For complete documentation on SQLDisconnect, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldisconnect-function).
2198    ///
2199    /// # Returns
2200    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2201    #[inline]
2202    pub fn SQLDisconnect(self) -> (Result<SQLHDBC<'env, C2, V>, Self>, SQLRETURN)
2203    where
2204        Self: Disconnect,
2205    {
2206        let sql_return = unsafe { ffi::SQLDisconnect(self.as_SQLHANDLE()) };
2207
2208        if SQL_SUCCEEDED(sql_return) {
2209            (Ok(self.disconnect()), sql_return)
2210        } else {
2211            (Err(self), sql_return)
2212        }
2213    }
2214
2215    /// Returns the current setting of a connection attribute.
2216    ///
2217    /// For complete documentation on SQLGetConnectAttrA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetconnectattr-function).
2218    ///
2219    /// # Returns
2220    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
2221    #[inline]
2222    #[allow(unused_variables)]
2223    pub fn SQLGetConnectAttrA<A: Ident<Type = SQLINTEGER>, T: ConnAttr<C, A, V>>(
2224        // TODO: Not sure whether attributes should be checked when getting them with SQLGetConnectAttr
2225        &self,
2226        Attribute: A,
2227        ValuePtr: Option<&mut T>,
2228        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2229    ) -> SQLRETURN
2230    where
2231        T: AttrGet<A> + Ansi + ?Sized,
2232        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
2233    {
2234        let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
2235            if cfg!(feature = "odbc_debug") {
2236                ValuePtr.assert_zeroed();
2237            }
2238
2239            (ValuePtr.as_mut_SQLPOINTER(), ValuePtr.len())
2240        });
2241
2242        unsafe {
2243            ffi::SQLGetConnectAttrA(
2244                self.as_SQLHANDLE(),
2245                A::IDENTIFIER,
2246                ValuePtr.0,
2247                ValuePtr.1,
2248                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
2249            )
2250        }
2251    }
2252
2253    /// Returns the current setting of a connection attribute.
2254    ///
2255    /// For complete documentation on SQLGetConnectAttrW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetconnectattr-function).
2256    ///
2257    /// # Returns
2258    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
2259    #[inline]
2260    #[allow(unused_variables)]
2261    pub fn SQLGetConnectAttrW<A: Ident<Type = SQLINTEGER>, T: ConnAttr<C, A, V>>(
2262        // TODO: Not really sure whether attributes should be checked when getting them with SQLGetConnectAttr
2263        &self,
2264        Attribute: A,
2265        ValuePtr: Option<&mut T>,
2266        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2267    ) -> SQLRETURN
2268    where
2269        T: AttrGet<A> + Unicode + ?Sized,
2270        MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
2271    {
2272        let ValuePtr = ValuePtr.map_or((ptr::null_mut(), 0), |ValuePtr| {
2273            if cfg!(feature = "odbc_debug") {
2274                ValuePtr.assert_zeroed();
2275            }
2276
2277            (ValuePtr.as_mut_SQLPOINTER(), ValuePtr.len())
2278        });
2279
2280        unsafe {
2281            ffi::SQLGetConnectAttrW(
2282                self.as_SQLHANDLE(),
2283                A::IDENTIFIER,
2284                ValuePtr.0,
2285                ValuePtr.1,
2286                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
2287            )
2288        }
2289    }
2290
2291    /// Sets attributes that govern aspects of connections.
2292    ///
2293    /// For complete documentation on SQLSetConnectAttrA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetconnectattr-function).
2294    ///
2295    /// # Returns
2296    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2297    #[inline]
2298    #[allow(unused_variables)]
2299    pub fn SQLSetConnectAttrA<A: Ident<Type = SQLINTEGER>, T: ConnAttr<C, A, V>>(
2300        &self,
2301        Attribute: A,
2302        ValuePtr: T,
2303    ) -> SQLRETURN
2304    where
2305        T: AttrSet<A> + Ansi,
2306    {
2307        unsafe {
2308            ffi::SQLSetConnectAttrA(
2309                self.as_SQLHANDLE(),
2310                A::IDENTIFIER,
2311                ValuePtr.into_SQLPOINTER(),
2312                ValuePtr.len(),
2313            )
2314        }
2315    }
2316
2317    /// Sets attributes that govern aspects of connections.
2318    ///
2319    /// For complete documentation on SQLSetConnectAttrW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetconnectattr-function).
2320    ///
2321    /// # Returns
2322    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2323    #[inline]
2324    #[allow(unused_variables)]
2325    pub fn SQLSetConnectAttrW<A: Ident<Type = SQLINTEGER>, T: ConnAttr<C, A, V>>(
2326        &self,
2327        Attribute: A,
2328        ValuePtr: T,
2329    ) -> SQLRETURN
2330    where
2331        T: AttrSet<A> + Unicode,
2332    {
2333        unsafe {
2334            ffi::SQLSetConnectAttrW(
2335                self.as_SQLHANDLE(),
2336                A::IDENTIFIER,
2337                ValuePtr.into_SQLPOINTER(),
2338                ValuePtr.len(),
2339            )
2340        }
2341    }
2342}
2343
2344#[allow(non_snake_case)]
2345impl<'env, V: OdbcVersion> SQLHDBC<'env, C2, V> {
2346    /// Establishes connections to a driver and a data source. The connection handle references storage of all information about the connection to the data source, including status, transaction state, and error information.
2347    ///
2348    /// For complete documentation on SQLConnectA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconnect-function).
2349    ///
2350    /// # Returns
2351    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2352    #[inline]
2353    pub fn SQLConnectA(
2354        self,
2355        ServerName: &OdbcStr<SQLCHAR>,
2356        UserName: &OdbcStr<SQLCHAR>,
2357        Authentication: &OdbcStr<SQLCHAR>,
2358    ) -> (
2359        Result<SQLHDBC<'env, C4, V>, SQLHDBC<'env, C2, V>>,
2360        SQLRETURN,
2361    ) {
2362        let ServerName = ServerName.as_raw_slice();
2363        let UserName = UserName.as_raw_slice();
2364        let Authentication = Authentication.as_raw_slice();
2365
2366        let sql_return = unsafe {
2367            ffi::SQLConnectA(
2368                self.as_SQLHANDLE(),
2369                ServerName.0,
2370                ServerName.1,
2371                UserName.0,
2372                UserName.1,
2373                Authentication.0,
2374                Authentication.1,
2375            )
2376        };
2377
2378        if SQL_SUCCEEDED(sql_return) {
2379            (Ok(self.connect()), sql_return)
2380        } else {
2381            (Err(self), sql_return)
2382        }
2383    }
2384
2385    /// Establishes connections to a driver and a data source. The connection handle references storage of all information about the connection to the data source, including status, transaction state, and error information.
2386    ///
2387    /// For complete documentation on SQLConnectW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconnect-function).
2388    ///
2389    /// # Returns
2390    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2391    #[inline]
2392    pub fn SQLConnectW(
2393        self,
2394        ServerName: &OdbcStr<SQLWCHAR>,
2395        UserName: &OdbcStr<SQLWCHAR>,
2396        Authentication: &OdbcStr<SQLWCHAR>,
2397    ) -> (
2398        Result<SQLHDBC<'env, C4, V>, SQLHDBC<'env, C2, V>>,
2399        SQLRETURN,
2400    ) {
2401        let ServerName = ServerName.as_raw_slice();
2402        let UserName = UserName.as_raw_slice();
2403        let Authentication = Authentication.as_raw_slice();
2404
2405        let sql_return = unsafe {
2406            ffi::SQLConnectW(
2407                self.as_SQLHANDLE(),
2408                ServerName.0,
2409                ServerName.1,
2410                UserName.0,
2411                UserName.1,
2412                Authentication.0,
2413                Authentication.1,
2414            )
2415        };
2416
2417        if SQL_SUCCEEDED(sql_return) {
2418            (Ok(self.connect()), sql_return)
2419        } else {
2420            (Err(self), sql_return)
2421        }
2422    }
2423
2424    /// An alternative to **SQLConnect**. It supports data sources that require more connection information than the three arguments in **SQLConnect**, dialog boxes to prompt the user for all connection information, and data sources that are not defined in the system information. For more information, see Connecting with SQLDriverConnect.
2425    ///
2426    /// For complete documentation on SQLDriverConnectA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldriverconnect-function).
2427    ///
2428    /// # Returns
2429    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2430    #[inline]
2431    pub fn SQLDriverConnectA(
2432        self,
2433        _WindowHandle: Option<SQLHWND>,
2434        InConnectionString: &OdbcStr<SQLCHAR>,
2435        OutConnectionString: Option<&mut OdbcStr<MaybeUninit<SQLCHAR>>>,
2436        StringLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
2437        DriverCompletion: DriverCompletion,
2438    ) -> (
2439        Result<SQLHDBC<'env, C4, V>, SQLHDBC<'env, C2, V>>,
2440        SQLRETURN,
2441    ) {
2442        let InConnectionString = InConnectionString.as_raw_slice();
2443        let OutConnectionString =
2444            OutConnectionString.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
2445
2446        let sql_return = unsafe {
2447            ffi::SQLDriverConnectA(
2448                self.as_SQLHANDLE(),
2449                // TODO: Fix this
2450                ptr::null_mut(),
2451                InConnectionString.0,
2452                InConnectionString.1,
2453                OutConnectionString.0,
2454                OutConnectionString.1,
2455                StringLength2Ptr.as_mut_ptr(),
2456                DriverCompletion as SQLUSMALLINT,
2457            )
2458        };
2459
2460        if SQL_SUCCEEDED(sql_return) {
2461            (Ok(self.connect()), sql_return)
2462        } else {
2463            (Err(self), sql_return)
2464        }
2465    }
2466
2467    /// An alternative to **SQLConnect**. It supports data sources that require more connection information than the three arguments in **SQLConnect**, dialog boxes to prompt the user for all connection information, and data sources that are not defined in the system information. For more information, see Connecting with SQLDriverConnect.
2468    ///
2469    /// For complete documentation on SQLDriverConnectW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqldriverconnect-function).
2470    ///
2471    /// # Returns
2472    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2473    #[inline]
2474    pub fn SQLDriverConnectW(
2475        self,
2476        _WindowHandle: Option<SQLHWND>,
2477        InConnectionString: &OdbcStr<SQLWCHAR>,
2478        OutConnectionString: Option<&mut OdbcStr<MaybeUninit<SQLWCHAR>>>,
2479        StringLength2Ptr: &mut impl AsMutPtr<SQLSMALLINT>,
2480        DriverCompletion: DriverCompletion,
2481    ) -> (
2482        Result<SQLHDBC<'env, C4, V>, SQLHDBC<'env, C2, V>>,
2483        SQLRETURN,
2484    ) {
2485        let InConnectionString = InConnectionString.as_raw_slice();
2486        let OutConnectionString =
2487            OutConnectionString.map_or((ptr::null_mut(), 0), AsMutRawSlice::as_mut_raw_slice);
2488
2489        let sql_return = unsafe {
2490            ffi::SQLDriverConnectW(
2491                self.as_SQLHANDLE(),
2492                // TODO: Fix this
2493                ptr::null_mut(),
2494                InConnectionString.0,
2495                InConnectionString.1,
2496                OutConnectionString.0,
2497                OutConnectionString.1,
2498                StringLength2Ptr.as_mut_ptr(),
2499                DriverCompletion as SQLUSMALLINT,
2500            )
2501        };
2502
2503        if SQL_SUCCEEDED(sql_return) {
2504            (Ok(self.connect()), sql_return)
2505        } else {
2506            (Err(self), sql_return)
2507        }
2508    }
2509}
2510
2511#[allow(non_snake_case)]
2512impl<'env, V: OdbcVersion> SQLHDBC<'env, C4, V> {
2513    /// Returns information about whether a driver supports a specific ODBC function. This function is implemented in the Driver Manager; it can also be implemented in drivers. If a driver implements **SQLGetFunctions**, the Driver Manager calls the function in the driver. Otherwise, it executes the function itself.
2514    ///
2515    /// For complete documentation on SQLGetFunctions, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetfunctions-function).
2516    ///
2517    /// # Returns
2518    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2519    #[inline]
2520    pub fn SQLGetFunctions(
2521        &self,
2522        FunctionId: FunctionId,
2523        SupportedPtr: &mut impl AsMutPtr<SQLUSMALLINT>,
2524    ) -> SQLRETURN {
2525        unsafe {
2526            ffi::SQLGetFunctions(
2527                self.as_SQLHANDLE(),
2528                FunctionId as SQLUSMALLINT,
2529                SupportedPtr.as_mut_ptr(),
2530            )
2531        }
2532    }
2533
2534    /// Returns general information about the driver and data source associated with a connection.
2535    ///
2536    /// For complete documentation on SQLGetInfoA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function).
2537    ///
2538    /// # Returns
2539    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2540    #[inline]
2541    #[allow(unused_variables)]
2542    pub fn SQLGetInfoA<A: Ident<Type = SQLUSMALLINT>, T: InfoType<A, V>>(
2543        // TODO: SQL_ODBC_VER can be called on connection that is not open
2544        &self,
2545        InfoType: A,
2546        InfoValuePtr: Option<&mut T>,
2547        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2548    ) -> SQLRETURN
2549    where
2550        T: AttrGet<A> + Ansi + ?Sized,
2551        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
2552    {
2553        let InfoValuePtr = InfoValuePtr.map_or((ptr::null_mut(), 0), |InfoValuePtr| {
2554            (InfoValuePtr.as_mut_SQLPOINTER(), InfoValuePtr.len())
2555        });
2556
2557        unsafe {
2558            ffi::SQLGetInfoA(
2559                self.as_SQLHANDLE(),
2560                A::IDENTIFIER,
2561                InfoValuePtr.0,
2562                InfoValuePtr.1,
2563                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
2564            )
2565        }
2566    }
2567
2568    /// Returns general information about the driver and data source associated with a connection.
2569    ///
2570    /// For complete documentation on SQLGetInfoW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function).
2571    ///
2572    /// # Returns
2573    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2574    #[inline]
2575    #[allow(unused_variables)]
2576    pub fn SQLGetInfoW<A: Ident<Type = SQLUSMALLINT>, T: InfoType<A, V>>(
2577        // TODO: SQL_ODBC_VER can be called on connection that is not open
2578        &self,
2579        InfoType: A,
2580        InfoValuePtr: Option<&mut T>,
2581        StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2582    ) -> SQLRETURN
2583    where
2584        T: AttrGet<A> + Unicode + ?Sized,
2585        MaybeUninit<T::StrLen>: StrLen<SQLSMALLINT>,
2586    {
2587        let InfoValuePtr = InfoValuePtr.map_or((ptr::null_mut(), 0), |InfoValuePtr| {
2588            (InfoValuePtr.as_mut_SQLPOINTER(), InfoValuePtr.len())
2589        });
2590
2591        unsafe {
2592            ffi::SQLGetInfoW(
2593                self.as_SQLHANDLE(),
2594                A::IDENTIFIER,
2595                InfoValuePtr.0,
2596                InfoValuePtr.1,
2597                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
2598            )
2599        }
2600    }
2601
2602    /// Returns the SQL string as modified by the driver. **SQLNativeSql** does not execute the SQL statement.
2603    ///
2604    /// For complete documentation on SQLNativeSqlA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnativesql-function).
2605    ///
2606    /// # Returns
2607    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2608    #[inline]
2609    pub fn SQLNativeSqlA(
2610        &self,
2611        InStatementText: &OdbcStr<SQLCHAR>,
2612        OutStatementText: &mut OdbcStr<MaybeUninit<SQLCHAR>>,
2613        TextLength2Ptr: &mut impl AsMutPtr<SQLINTEGER>,
2614    ) -> SQLRETURN {
2615        let InStatementText = InStatementText.as_raw_slice();
2616        let OutStatementText = OutStatementText.as_mut_raw_slice();
2617
2618        unsafe {
2619            ffi::SQLNativeSqlA(
2620                self.as_SQLHANDLE(),
2621                InStatementText.0,
2622                InStatementText.1,
2623                OutStatementText.0,
2624                OutStatementText.1,
2625                TextLength2Ptr.as_mut_ptr(),
2626            )
2627        }
2628    }
2629
2630    /// Returns the SQL string as modified by the driver. **SQLNativeSql** does not execute the SQL statement.
2631    ///
2632    /// For complete documentation on SQLNativeSqlW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlnativesql-function).
2633    ///
2634    /// # Returns
2635    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
2636    #[inline]
2637    pub fn SQLNativeSqlW(
2638        &self,
2639        InStatementText: &OdbcStr<SQLWCHAR>,
2640        OutStatementText: &mut OdbcStr<MaybeUninit<SQLWCHAR>>,
2641        TextLength2Ptr: &mut impl AsMutPtr<SQLINTEGER>,
2642    ) -> SQLRETURN {
2643        let InStatementText = InStatementText.as_raw_slice();
2644        let OutStatementText = OutStatementText.as_mut_raw_slice();
2645
2646        unsafe {
2647            ffi::SQLNativeSqlW(
2648                self.as_SQLHANDLE(),
2649                InStatementText.0,
2650                InStatementText.1,
2651                OutStatementText.0,
2652                OutStatementText.1,
2653                TextLength2Ptr.as_mut_ptr(),
2654            )
2655        }
2656    }
2657
2658    /// Requests a commit or rollback operation for all active operations on all statements associated with a connection. **SQLEndTran** can also request that a commit or rollback operation be performed for all connections associated with an environment.
2659    ///
2660    /// For complete documentation on SQLEndTran, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlendtran-function).
2661    ///
2662    /// # Returns
2663    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE, or SQL_STILL_EXECUTING.
2664    #[inline]
2665    pub fn SQLEndTran(&self, CompletionType: CompletionType) -> SQLRETURN {
2666        // Not implemented on SQLHENV so as to to avoid confusion, considering that the same
2667        // functionality can be achieved by calling SQLEndTran repeatedly on SQLHDBC handle
2668
2669        unsafe {
2670            ffi::SQLEndTran(
2671                <Self as Handle>::Ident::IDENTIFIER,
2672                self.as_SQLHANDLE(),
2673                CompletionType as SQLSMALLINT,
2674            )
2675        }
2676    }
2677}
2678
2679#[allow(non_snake_case)]
2680impl<'desc, 'buf, V: OdbcVersion> SQLHSTMT<'_, 'desc, 'buf, V> {
2681    /// Executes a preparable statement, using the current values of the parameter marker variables if any parameters exist in the statement. **SQLExecDirect** is the fastest way to submit an SQL statement for one-time execution.
2682    ///
2683    /// For complete documentation on SQLExecDirectA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function).
2684    ///
2685    /// # Returns
2686    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2687    #[inline]
2688    pub fn SQLExecDirectA(&self, StatementText: &OdbcStr<SQLCHAR>) -> SQLRETURN {
2689        let StatementText = StatementText.as_raw_slice();
2690
2691        unsafe { ffi::SQLExecDirectA(self.as_SQLHANDLE(), StatementText.0, StatementText.1) }
2692    }
2693
2694    /// Executes a preparable statement, using the current values of the parameter marker variables if any parameters exist in the statement. **SQLExecDirect** is the fastest way to submit an SQL statement for one-time execution.
2695    ///
2696    /// For complete documentation on SQLExecDirectW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function).
2697    ///
2698    /// # Returns
2699    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2700    #[inline]
2701    pub fn SQLExecDirectW(&self, StatementText: &OdbcStr<SQLWCHAR>) -> SQLRETURN {
2702        let StatementText = StatementText.as_raw_slice();
2703
2704        unsafe { ffi::SQLExecDirectW(self.as_SQLHANDLE(), StatementText.0, StatementText.1) }
2705    }
2706
2707    /// Executes a prepared statement, using the current values of the parameter marker variables if any parameter markers exist in the statement.
2708    ///
2709    /// For complete documentation on SQLExecute, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecute-function).
2710    ///
2711    /// # Returns
2712    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2713    #[inline]
2714    pub fn SQLExecute(&self) -> SQLRETURN {
2715        unsafe { ffi::SQLExecute(self.as_SQLHANDLE()) }
2716    }
2717
2718    /// Fetches the next rowset of data from the result set and returns data for all bound columns.
2719    ///
2720    /// For complete documentation on SQLFetch, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetch-function).
2721    ///
2722    /// # Returns
2723    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2724    #[inline]
2725    pub fn SQLFetch(&self) -> SQLRETURN {
2726        unsafe { ffi::SQLFetch(self.as_SQLHANDLE()) }
2727    }
2728
2729    /// Fetches the specified rowset of data from the result set and returns data for all bound columns. Rowsets can be specified at an absolute or relative position or by bookmark.
2730    ///
2731    /// For complete documentation on SQLFetchScroll, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetchscroll-function).
2732    ///
2733    /// # Returns
2734    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2735    #[inline]
2736    pub fn SQLFetchScroll(&self, FetchOrientation: SQLSMALLINT, FetchOffset: SQLLEN) -> SQLRETURN {
2737        unsafe { ffi::SQLFetchScroll(self.as_SQLHANDLE(), FetchOrientation, FetchOffset) }
2738    }
2739
2740    /// Sets the cursor position in a rowset and allows an application to refresh data in the rowset or to update or delete data in the result set.
2741    ///
2742    /// For complete documentation on SQLSetPos, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetpos-function).
2743    ///
2744    /// # Returns
2745    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2746    #[inline]
2747    pub fn SQLSetPos(
2748        &self,
2749        RowNumber: SQLSETPOSIROW,
2750        Operation: Operation,
2751        LockType: LockType,
2752    ) -> SQLRETURN {
2753        unsafe {
2754            ffi::SQLSetPos(
2755                self.as_SQLHANDLE(),
2756                RowNumber,
2757                Operation as SQLUSMALLINT,
2758                LockType as SQLUSMALLINT,
2759            )
2760        }
2761    }
2762}
2763
2764#[allow(non_snake_case)]
2765impl<'desc, 'buf, V: OdbcVersion> UnsafeSQLHSTMT<'_, 'desc, 'buf, V> {
2766    /// Executes a preparable statement, using the current values of the parameter marker variables if any parameters exist in the statement. **SQLExecDirect** is the fastest way to submit an SQL statement for one-time execution.
2767    ///
2768    /// For complete documentation on SQLExecDirectA, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function).
2769    ///
2770    /// # Returns
2771    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2772    #[inline]
2773    pub unsafe fn SQLExecDirectA(&self, StatementText: &OdbcStr<SQLCHAR>) -> SQLRETURN {
2774        let StatementText = StatementText.as_raw_slice();
2775
2776        ffi::SQLExecDirectA(self.as_SQLHANDLE(), StatementText.0, StatementText.1)
2777    }
2778
2779    /// Executes a preparable statement, using the current values of the parameter marker variables if any parameters exist in the statement. **SQLExecDirect** is the fastest way to submit an SQL statement for one-time execution.
2780    ///
2781    /// For complete documentation on SQLExecDirectW, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function).
2782    ///
2783    /// # Returns
2784    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2785    #[inline]
2786    pub unsafe fn SQLExecDirectW(&self, StatementText: &OdbcStr<SQLWCHAR>) -> SQLRETURN {
2787        let StatementText = StatementText.as_raw_slice();
2788
2789        ffi::SQLExecDirectW(self.as_SQLHANDLE(), StatementText.0, StatementText.1)
2790    }
2791
2792    /// Executes a prepared statement, using the current values of the parameter marker variables if any parameter markers exist in the statement.
2793    ///
2794    /// For complete documentation on SQLExecute, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecute-function).
2795    ///
2796    /// # Returns
2797    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE, or SQL_PARAM_DATA_AVAILABLE.
2798    #[inline]
2799    pub unsafe fn SQLExecute(&self) -> SQLRETURN {
2800        ffi::SQLExecute(self.as_SQLHANDLE())
2801    }
2802
2803    /// Fetches the next rowset of data from the result set and returns data for all bound columns.
2804    ///
2805    /// For complete documentation on SQLFetch, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetch-function).
2806    ///
2807    /// # Returns
2808    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2809    #[inline]
2810    pub unsafe fn SQLFetch(&self) -> SQLRETURN {
2811        ffi::SQLFetch(self.as_SQLHANDLE())
2812    }
2813
2814    /// Fetches the specified rowset of data from the result set and returns data for all bound columns. Rowsets can be specified at an absolute or relative position or by bookmark.
2815    ///
2816    /// For complete documentation on SQLFetchScroll, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlfetchscroll-function).
2817    ///
2818    /// # Returns
2819    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2820    #[inline]
2821    pub unsafe fn SQLFetchScroll(
2822        &self,
2823        FetchOrientation: SQLSMALLINT,
2824        FetchOffset: SQLLEN,
2825    ) -> SQLRETURN {
2826        ffi::SQLFetchScroll(self.as_SQLHANDLE(), FetchOrientation, FetchOffset)
2827    }
2828
2829    /// Sets the cursor position in a rowset and allows an application to refresh data in the rowset or to update or delete data in the result set.
2830    ///
2831    /// For complete documentation on SQLSetPos, see [API reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetpos-function).
2832    ///
2833    /// # Returns
2834    /// SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
2835    #[inline]
2836    pub unsafe fn SQLSetPos(
2837        &self,
2838        RowNumber: SQLSETPOSIROW,
2839        Operation: Operation,
2840        LockType: LockType,
2841    ) -> SQLRETURN {
2842        ffi::SQLSetPos(
2843            self.as_SQLHANDLE(),
2844            RowNumber,
2845            Operation as SQLUSMALLINT,
2846            LockType as SQLUSMALLINT,
2847        )
2848    }
2849}
2850
2851#[allow(non_snake_case)]
2852impl<'conn, 'desc, 'buf, V: OdbcVersion> Statement<'desc, 'buf, V>
2853    for SQLHSTMT<'conn, 'desc, 'buf, V>
2854{
2855    // TODO: When GATs are implemented use 'stmt instead of 'conn
2856    // because implicit descriptors are managed by the DM
2857    type ARD = RefSQLHDESC<'conn, AppDesc<'buf>, V>;
2858    type APD = RefSQLHDESC<'conn, AppDesc<'buf>, V>;
2859    type IRD = RefSQLHDESC<'conn, IRD, V>;
2860    type IPD = RefSQLHDESC<'conn, IPD, V>;
2861
2862    type ExplicitARD = SQLHDESC<'conn, AppDesc<'buf>, V>;
2863    type ExplicitAPD = SQLHDESC<'conn, AppDesc<'buf>, V>;
2864
2865    fn bind_col<TT: Ident, B: DeferredBuf<Self::ARD, TT, V>>(&self, _: Option<&'buf B>)
2866    where
2867        B: ?Sized,
2868    {
2869        //TODO:
2870        //self.0.bind_col(TargetValuePtr)
2871    }
2872
2873    fn bind_param<TT: Ident, B: DeferredBuf<Self::APD, TT, V>>(&self, _: Option<&'buf B>)
2874    where
2875        B: ?Sized,
2876    {
2877        // TODO:
2878        //self.0.bind_param(TargetValuePtr)
2879    }
2880
2881    fn bind_strlen_or_ind(&self, StrLen_or_IndPtr: Option<&'buf UnsafeCell<StrLenOrInd>>) {
2882        self.0.bind_strlen_or_ind(StrLen_or_IndPtr)
2883    }
2884}
2885
2886#[allow(non_snake_case)]
2887impl<'conn, 'desc, 'buf, V: OdbcVersion> Statement<'desc, 'buf, V>
2888    for UnsafeSQLHSTMT<'conn, 'desc, 'buf, V>
2889{
2890    // TODO: When GATs are implemented use 'stmt instead of 'conn
2891    // because implicit descriptors are managed by the DM
2892    type ARD = RefUnsafeSQLHDESC<'conn, AppDesc<'buf>, V>;
2893    type APD = RefUnsafeSQLHDESC<'conn, AppDesc<'buf>, V>;
2894    type IRD = RefUnsafeSQLHDESC<'conn, IRD, V>;
2895    type IPD = RefUnsafeSQLHDESC<'conn, IPD, V>;
2896
2897    type ExplicitARD = UnsafeSQLHDESC<'conn, AppDesc<'buf>, V>;
2898    type ExplicitAPD = UnsafeSQLHDESC<'conn, AppDesc<'buf>, V>;
2899
2900    // TODO: Don't bind (SQLPOINTER, SQLLEN) fat pointer when using raw_api
2901    #[cfg(not(feature = "odbc_debug"))]
2902    fn bind_col<TT: Ident, B: DeferredBuf<Self::ARD, TT, V>>(&self, _: Option<&'buf B>)
2903    where
2904        B: ?Sized,
2905    {
2906    }
2907    #[cfg(not(feature = "odbc_debug"))]
2908    fn bind_param<TT: Ident, B: DeferredBuf<Self::APD, TT, V>>(&self, _: Option<&'buf B>)
2909    where
2910        B: ?Sized,
2911    {
2912    }
2913    #[cfg(not(feature = "odbc_debug"))]
2914    fn bind_strlen_or_ind(&self, _: Option<&'buf UnsafeCell<StrLenOrInd>>) {}
2915
2916    #[cfg(feature = "odbc_debug")]
2917    fn bind_col<TT: Ident, B: DeferredBuf<Self::ARD, TT, V>>(&self, _: Option<&'buf B>)
2918    where
2919        B: ?Sized,
2920    {
2921        if let Some(explicit_ard) = self.explicit_ard.get() {
2922            // TODO:
2923            //explicit_ard.bind_col(TargetValuePtr);
2924        } else {
2925            // TODO:
2926            //self.ard.bind_col(TargetValuePtr);
2927        }
2928    }
2929    #[cfg(feature = "odbc_debug")]
2930    fn bind_param<TT: Ident, B: DeferredBuf<Self::APD, TT, V>>(
2931        &self,
2932        TargetValuePtr: Option<&'buf B>,
2933    ) where
2934        B: ?Sized,
2935    {
2936        if let Some(explicit_apd) = self.explicit_apd.get() {
2937            // TODO:
2938            //explicit_apd.bind_param(TargetValuePtr);
2939        } else {
2940            // TODO:
2941            //self.apd.bind_param(TargetValuePtr);
2942        }
2943    }
2944    #[cfg(feature = "odbc_debug")]
2945    fn bind_strlen_or_ind(&self, StrLen_or_IndPtr: Option<&'buf UnsafeCell<StrLenOrInd>>) {
2946        unimplemented!();
2947    }
2948}
2949
2950impl<'conn, 'buf, DT: DescType<'buf>, V: OdbcVersion> Descriptor<'buf, DT, V>
2951    for SQLHDESC<'conn, DT, V>
2952{
2953}
2954impl<'conn, 'buf, DT: DescType<'buf>, V: OdbcVersion> Descriptor<'buf, DT, V>
2955    for RefSQLHDESC<'conn, DT, V>
2956{
2957}
2958impl<'conn, 'buf, DT: DescType<'buf>, V: OdbcVersion> Descriptor<'buf, DT, V>
2959    for UnsafeSQLHDESC<'conn, DT, V>
2960{
2961}
2962impl<'conn, 'buf, DT: DescType<'buf>, V: OdbcVersion> Descriptor<'buf, DT, V>
2963    for RefUnsafeSQLHDESC<'conn, DT, V>
2964{
2965}
2966
2967// TODO: If Connection trait is introduced implement for all connections
2968impl Cancel<SQL_OV_ODBC3_80> for SQLHDBC<'_, C4, SQL_OV_ODBC3_80> {}
2969impl Cancel<SQL_OV_ODBC4> for SQLHDBC<'_, C4, SQL_OV_ODBC4> {}
2970
2971impl Async<SQL_OV_ODBC3_80> for SQLHDBC<'_, C4, SQL_OV_ODBC3_80> {}
2972impl Async<SQL_OV_ODBC4> for SQLHDBC<'_, C4, SQL_OV_ODBC4> {}
2973
2974impl<'desc, 'buf, S: Statement<'desc, 'buf, SQL_OV_ODBC3_80>> Cancel<SQL_OV_ODBC3_80> for S {}
2975impl<'desc, 'buf, S: Statement<'desc, 'buf, SQL_OV_ODBC4>> Cancel<SQL_OV_ODBC4> for S {}
2976
2977impl<'desc, 'buf, S: Statement<'desc, 'buf, SQL_OV_ODBC3_80>> Async<SQL_OV_ODBC3_80> for S {}
2978impl<'desc, 'buf, S: Statement<'desc, 'buf, SQL_OV_ODBC4>> Async<SQL_OV_ODBC4> for S {}
2979
2980#[allow(non_snake_case, unused_variables)]
2981fn SQLGetStmtAttrA<
2982    'stmt,
2983    'desc,
2984    'buf,
2985    S: Statement<'desc, 'buf, V>,
2986    A: Ident<Type = SQLINTEGER>,
2987    T: BaseStmtAttr<'desc, 'buf, S, A, V>,
2988    V: OdbcVersion,
2989>(
2990    Handle: &'stmt S,
2991    Attribute: A,
2992    ValuePtr: Option<&mut T>,
2993    StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
2994) -> SQLRETURN
2995where
2996    T: AttrGet<A> + Ansi + Ref<'stmt> + ?Sized,
2997    MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
2998{
2999    if let Some(ValuePtr) = ValuePtr {
3000        if cfg!(feature = "odbc_debug") {
3001            ValuePtr.assert_zeroed();
3002        }
3003
3004        ValuePtr.readA(Handle, StringLengthPtr)
3005    } else {
3006        unsafe {
3007            ffi::SQLGetStmtAttrA(
3008                Handle.as_SQLHANDLE(),
3009                A::IDENTIFIER,
3010                ptr::null_mut(),
3011                0,
3012                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
3013            )
3014        }
3015    }
3016}
3017
3018#[allow(non_snake_case, unused_variables)]
3019fn SQLGetStmtAttrW<
3020    'stmt,
3021    'desc,
3022    'buf,
3023    S: Statement<'desc, 'buf, V>,
3024    A: Ident<Type = SQLINTEGER>,
3025    T: BaseStmtAttr<'desc, 'buf, S, A, V>,
3026    V: OdbcVersion,
3027>(
3028    Handle: &'stmt S,
3029    Attribute: A,
3030    ValuePtr: Option<&mut T>,
3031    StringLengthPtr: Option<&mut MaybeUninit<T::StrLen>>,
3032) -> SQLRETURN
3033where
3034    T: AttrGet<A> + Unicode + Ref<'stmt> + ?Sized,
3035    MaybeUninit<T::StrLen>: StrLen<SQLINTEGER>,
3036{
3037    if let Some(ValuePtr) = ValuePtr {
3038        if cfg!(feature = "odbc_debug") {
3039            ValuePtr.assert_zeroed();
3040        }
3041
3042        ValuePtr.readW(Handle, StringLengthPtr)
3043    } else {
3044        unsafe {
3045            ffi::SQLGetStmtAttrW(
3046                Handle.as_SQLHANDLE(),
3047                A::IDENTIFIER,
3048                ptr::null_mut(),
3049                0,
3050                StringLengthPtr.map_or_else(ptr::null_mut, StrLen::as_mut_ptr),
3051            )
3052        }
3053    }
3054}
3055
3056#[allow(non_snake_case, unused_variables)]
3057fn SQLSetStmtAttrA<
3058    'desc,
3059    'buf,
3060    S: Statement<'desc, 'buf, V>,
3061    A: Ident<Type = SQLINTEGER>,
3062    T: BaseStmtAttr<'desc, 'buf, S, A, V>,
3063    V: OdbcVersion,
3064>(
3065    Handle: &S,
3066    Attribute: A,
3067    ValuePtr: T,
3068) -> SQLRETURN
3069where
3070    T: AttrSet<A> + Ansi,
3071{
3072    let sql_return = unsafe {
3073        ffi::SQLSetStmtAttrA(
3074            Handle.as_SQLHANDLE(),
3075            A::IDENTIFIER,
3076            ValuePtr.into_SQLPOINTER(),
3077            ValuePtr.len(),
3078        )
3079    };
3080
3081    if SQL_SUCCEEDED(sql_return) {
3082        ValuePtr.update_handle(Handle);
3083    }
3084
3085    sql_return
3086}
3087
3088#[allow(non_snake_case, unused_variables)]
3089fn SQLSetStmtAttrW<
3090    'desc,
3091    'buf,
3092    S: Statement<'desc, 'buf, V>,
3093    A: Ident<Type = SQLINTEGER>,
3094    T: BaseStmtAttr<'desc, 'buf, S, A, V>,
3095    V: OdbcVersion,
3096>(
3097    Handle: &S,
3098    Attribute: A,
3099    ValuePtr: T,
3100) -> SQLRETURN
3101where
3102    T: AttrSet<A> + Unicode,
3103{
3104    let sql_return = unsafe {
3105        ffi::SQLSetStmtAttrW(
3106            Handle.as_SQLHANDLE(),
3107            A::IDENTIFIER,
3108            ValuePtr.into_SQLPOINTER(),
3109            ValuePtr.len(),
3110        )
3111    };
3112
3113    if SQL_SUCCEEDED(sql_return) {
3114        ValuePtr.update_handle(Handle);
3115    }
3116
3117    sql_return
3118}
3119
3120#[cfg_attr(test, automock)]
3121pub(crate) mod ffi {
3122    use crate::handle::SQLHWND;
3123    use crate::{
3124        diag::SQLSTATE_SIZE, handle::SQLHANDLE, sqlreturn::SQLRETURN, RETCODE, SQLCHAR, SQLINTEGER,
3125        SQLLEN, SQLPOINTER, SQLSETPOSIROW, SQLSMALLINT, SQLULEN, SQLUSMALLINT, SQLWCHAR,
3126    };
3127
3128    type HENV = SQLHANDLE;
3129    type HDBC = SQLHANDLE;
3130    type HSTMT = SQLHANDLE;
3131    type HDESC = SQLHANDLE;
3132
3133    type ConstSQLPOINTER = *const core::ffi::c_void;
3134    type MutSQLPOINTER = *mut core::ffi::c_void;
3135
3136    // TODO: static linking is not supported for windows
3137    #[cfg_attr(windows, link(name = "odbc32", kind = "dylib"))]
3138    #[cfg_attr(
3139        all(not(windows), feature = "static"),
3140        link(name = "odbc", kind = "static")
3141    )]
3142    #[cfg_attr(
3143        all(not(windows), not(feature = "static")),
3144        link(name = "odbc", kind = "dylib")
3145    )]
3146    extern "system" {
3147        #[allow(non_snake_case)]
3148        pub fn SQLAllocHandle(
3149            HandleType: SQLSMALLINT,
3150            InputHandle: SQLHANDLE,
3151            OutputHandlePtr: *mut SQLHANDLE,
3152        ) -> SQLRETURN;
3153
3154        #[allow(non_snake_case)]
3155        pub fn SQLBindCol(
3156            StatementHandle: HSTMT,
3157            ColumnNumber: SQLUSMALLINT,
3158            TargetType: SQLSMALLINT,
3159            TargetValuePtr: MutSQLPOINTER,
3160            BufferLength: SQLLEN,
3161            StrLen_or_IndPtr: *mut SQLLEN,
3162        ) -> SQLRETURN;
3163
3164        #[allow(non_snake_case)]
3165        pub fn SQLBindParameter(
3166            StatementHandle: HSTMT,
3167            ParameterNumber: SQLUSMALLINT,
3168            InputOutputType: SQLSMALLINT,
3169            ValueType: SQLSMALLINT,
3170            ParameterType: SQLSMALLINT,
3171            ColumnSize: SQLULEN,
3172            DecimalDigits: SQLSMALLINT,
3173            ParameterValuePtr: SQLPOINTER,
3174            BufferLength: SQLLEN,
3175            StrLen_or_IndPtr: *const SQLLEN,
3176        ) -> SQLRETURN;
3177
3178        #[allow(non_snake_case)]
3179        pub fn SQLBrowseConnectA(
3180            ConnectionHandle: HDBC,
3181            InConnectionString: *const SQLCHAR,
3182            StringLength1: SQLSMALLINT,
3183            OutConnectionString: *mut SQLCHAR,
3184            BufferLength: SQLSMALLINT,
3185            StringLength2Ptr: *mut SQLSMALLINT,
3186        ) -> SQLRETURN;
3187
3188        #[allow(non_snake_case)]
3189        pub fn SQLBrowseConnectW(
3190            ConnectionHandle: HDBC,
3191            InConnectionString: *const SQLWCHAR,
3192            StringLength1: SQLSMALLINT,
3193            OutConnectionString: *mut SQLWCHAR,
3194            BufferLength: SQLSMALLINT,
3195            StringLength2Ptr: *mut SQLSMALLINT,
3196        ) -> SQLRETURN;
3197
3198        #[allow(non_snake_case)]
3199        pub fn SQLBulkOperations(StatementHandle: HSTMT, Operation: SQLUSMALLINT) -> SQLRETURN;
3200
3201        #[allow(non_snake_case)]
3202        pub fn SQLCancel(StatementHandle: HSTMT) -> SQLRETURN;
3203
3204        #[allow(non_snake_case)]
3205        pub fn SQLCancelHandle(HandleType: SQLSMALLINT, Handle: SQLHANDLE) -> SQLRETURN;
3206
3207        #[allow(non_snake_case)]
3208        pub fn SQLCloseCursor(StatementHandle: HSTMT) -> SQLRETURN;
3209
3210        #[allow(non_snake_case)]
3211        pub fn SQLColAttributeA(
3212            StatementHandle: HSTMT,
3213            ColumnNumber: SQLUSMALLINT,
3214            FieldIdentifier: SQLUSMALLINT,
3215            CharacterAttributePtr: MutSQLPOINTER,
3216            BufferLength: SQLSMALLINT,
3217            StringLengthPtr: *mut SQLSMALLINT,
3218            NumericAttributePtr: *mut SQLLEN,
3219        ) -> SQLRETURN;
3220
3221        #[allow(non_snake_case)]
3222        pub fn SQLColAttributeW(
3223            StatementHandle: HSTMT,
3224            ColumnNumber: SQLUSMALLINT,
3225            FieldIdentifier: SQLUSMALLINT,
3226            CharacterAttributePtr: MutSQLPOINTER,
3227            BufferLength: SQLSMALLINT,
3228            StringLengthPtr: *mut SQLSMALLINT,
3229            NumericAttributePtr: *mut SQLLEN,
3230        ) -> SQLRETURN;
3231
3232        #[allow(non_snake_case)]
3233        pub fn SQLColumnPrivilegesA(
3234            StatementHandle: HSTMT,
3235            CatalogName: *const SQLCHAR,
3236            NameLength1: SQLSMALLINT,
3237            SchemaName: *const SQLCHAR,
3238            NameLength2: SQLSMALLINT,
3239            TableName: *const SQLCHAR,
3240            NameLength3: SQLSMALLINT,
3241            ColumnName: *const SQLCHAR,
3242            NameLength4: SQLSMALLINT,
3243        ) -> SQLRETURN;
3244
3245        #[allow(non_snake_case)]
3246        pub fn SQLColumnPrivilegesW(
3247            StatementHandle: HSTMT,
3248            CatalogName: *const SQLWCHAR,
3249            NameLength1: SQLSMALLINT,
3250            SchemaName: *const SQLWCHAR,
3251            NameLength2: SQLSMALLINT,
3252            TableName: *const SQLWCHAR,
3253            NameLength3: SQLSMALLINT,
3254            ColumnName: *const SQLWCHAR,
3255            NameLength4: SQLSMALLINT,
3256        ) -> SQLRETURN;
3257
3258        #[allow(non_snake_case)]
3259        pub fn SQLColumnsA(
3260            StatementHandle: HSTMT,
3261            CatalogName: *const SQLCHAR,
3262            NameLength1: SQLSMALLINT,
3263            SchemaName: *const SQLCHAR,
3264            NameLength2: SQLSMALLINT,
3265            TableName: *const SQLCHAR,
3266            NameLength3: SQLSMALLINT,
3267            ColumnName: *const SQLCHAR,
3268            NameLength4: SQLSMALLINT,
3269        ) -> SQLRETURN;
3270
3271        #[allow(non_snake_case)]
3272        pub fn SQLColumnsW(
3273            StatementHandle: HSTMT,
3274            CatalogName: *const SQLWCHAR,
3275            NameLength1: SQLSMALLINT,
3276            SchemaName: *const SQLWCHAR,
3277            NameLength2: SQLSMALLINT,
3278            TableName: *const SQLWCHAR,
3279            NameLength3: SQLSMALLINT,
3280            ColumnName: *const SQLWCHAR,
3281            NameLength4: SQLSMALLINT,
3282        ) -> SQLRETURN;
3283
3284        #[allow(non_snake_case)]
3285        pub fn SQLCompleteAsync(
3286            HandleType: SQLSMALLINT,
3287            Handle: SQLHANDLE,
3288            AsyncRetCodePtr: *mut RETCODE,
3289        ) -> SQLRETURN;
3290
3291        #[allow(non_snake_case)]
3292        pub fn SQLConnectA(
3293            ConnectionHandle: HDBC,
3294            ServerName: *const SQLCHAR,
3295            NameLength1: SQLSMALLINT,
3296            UserName: *const SQLCHAR,
3297            NameLength2: SQLSMALLINT,
3298            Authentication: *const SQLCHAR,
3299            NameLength3: SQLSMALLINT,
3300        ) -> SQLRETURN;
3301
3302        #[allow(non_snake_case)]
3303        pub fn SQLConnectW(
3304            ConnectionHandle: HDBC,
3305            ServerName: *const SQLWCHAR,
3306            NameLength1: SQLSMALLINT,
3307            UserName: *const SQLWCHAR,
3308            NameLength2: SQLSMALLINT,
3309            Authentication: *const SQLWCHAR,
3310            NameLength3: SQLSMALLINT,
3311        ) -> SQLRETURN;
3312
3313        #[allow(non_snake_case)]
3314        pub fn SQLCopyDesc(SourceDescHandle: HDESC, TargetDescHandle: HDESC) -> SQLRETURN;
3315
3316        #[allow(non_snake_case)]
3317        pub fn SQLDataSourcesA(
3318            EnvironmentHandle: HENV,
3319            Direction: SQLUSMALLINT,
3320            ServerName: *mut SQLCHAR,
3321            BufferLength1: SQLSMALLINT,
3322            NameLength1Ptr: *mut SQLSMALLINT,
3323            Description: *mut SQLCHAR,
3324            BufferLength2: SQLSMALLINT,
3325            NameLength2Ptr: *mut SQLSMALLINT,
3326        ) -> SQLRETURN;
3327
3328        #[allow(non_snake_case)]
3329        pub fn SQLDataSourcesW(
3330            EnvironmentHandle: HENV,
3331            Direction: SQLUSMALLINT,
3332            ServerName: *mut SQLWCHAR,
3333            BufferLength1: SQLSMALLINT,
3334            NameLength1Ptr: *mut SQLSMALLINT,
3335            Description: *mut SQLWCHAR,
3336            BufferLength2: SQLSMALLINT,
3337            NameLength2Ptr: *mut SQLSMALLINT,
3338        ) -> SQLRETURN;
3339
3340        #[allow(non_snake_case)]
3341        pub fn SQLDescribeColA(
3342            StatementHandle: HSTMT,
3343            ColumnNumber: SQLUSMALLINT,
3344            ColumnName: *mut SQLCHAR,
3345            BufferLength: SQLSMALLINT,
3346            NameLengthPtr: *mut SQLSMALLINT,
3347            DataTypePtr: *mut SQLSMALLINT,
3348            ColumnSizePtr: *mut SQLULEN,
3349            DecimalDigitsPtr: *mut SQLSMALLINT,
3350            NullablePtr: *mut SQLSMALLINT,
3351        ) -> SQLRETURN;
3352
3353        #[allow(non_snake_case)]
3354        pub fn SQLDescribeColW(
3355            StatementHandle: HSTMT,
3356            ColumnNumber: SQLUSMALLINT,
3357            ColumnName: *mut SQLWCHAR,
3358            BufferLength: SQLSMALLINT,
3359            NameLengthPtr: *mut SQLSMALLINT,
3360            DataTypePtr: *mut SQLSMALLINT,
3361            ColumnSizePtr: *mut SQLULEN,
3362            DecimalDigitsPtr: *mut SQLSMALLINT,
3363            NullablePtr: *mut SQLSMALLINT,
3364        ) -> SQLRETURN;
3365
3366        #[allow(non_snake_case)]
3367        pub fn SQLDescribeParam(
3368            StatementHandle: HSTMT,
3369            ParameterNumber: SQLUSMALLINT,
3370            DataTypePtr: *mut SQLSMALLINT,
3371            ParameterSizePtr: *mut SQLULEN,
3372            DecimalDigitsPtr: *mut SQLSMALLINT,
3373            NullablePtr: *mut SQLSMALLINT,
3374        ) -> SQLRETURN;
3375
3376        #[allow(non_snake_case)]
3377        pub fn SQLDisconnect(ConnectionHandle: HDBC) -> SQLRETURN;
3378
3379        #[allow(non_snake_case)]
3380        pub fn SQLDriverConnectA(
3381            ConnectionHandle: HDBC,
3382            WindowHandle: SQLHWND,
3383            InConnectionString: *const SQLCHAR,
3384            StringLength1: SQLSMALLINT,
3385            OutConnectionString: *mut SQLCHAR,
3386            BufferLength: SQLSMALLINT,
3387            StringLength2Ptr: *mut SQLSMALLINT,
3388            DriverCompletion: SQLUSMALLINT,
3389        ) -> SQLRETURN;
3390
3391        #[allow(non_snake_case)]
3392        pub fn SQLDriverConnectW(
3393            ConnectionHandle: HDBC,
3394            WindowHandle: SQLHWND,
3395            InConnectionString: *const SQLWCHAR,
3396            StringLength1: SQLSMALLINT,
3397            OutConnectionString: *mut SQLWCHAR,
3398            BufferLength: SQLSMALLINT,
3399            StringLength2Ptr: *mut SQLSMALLINT,
3400            DriverCompletion: SQLUSMALLINT,
3401        ) -> SQLRETURN;
3402
3403        #[allow(non_snake_case)]
3404        pub fn SQLDriversA(
3405            EnvironmentHandle: HENV,
3406            Direction: SQLUSMALLINT,
3407            DriverDescription: *mut SQLCHAR,
3408            BufferLength1: SQLSMALLINT,
3409            DescriptionLengthPtr: *mut SQLSMALLINT,
3410            DriverAttributes: *mut SQLCHAR,
3411            BufferLength2: SQLSMALLINT,
3412            AttributesLengthPtr: *mut SQLSMALLINT,
3413        ) -> SQLRETURN;
3414
3415        #[allow(non_snake_case)]
3416        pub fn SQLDriversW(
3417            EnvironmentHandle: HENV,
3418            Direction: SQLUSMALLINT,
3419            DriverDescription: *mut SQLWCHAR,
3420            BufferLength1: SQLSMALLINT,
3421            DescriptionLengthPtr: *mut SQLSMALLINT,
3422            DriverAttributes: *mut SQLWCHAR,
3423            BufferLength2: SQLSMALLINT,
3424            AttributesLengthPtr: *mut SQLSMALLINT,
3425        ) -> SQLRETURN;
3426
3427        #[allow(non_snake_case)]
3428        pub fn SQLEndTran(
3429            HandleType: SQLSMALLINT,
3430            Handle: SQLHANDLE,
3431            CompletionType: SQLSMALLINT,
3432        ) -> SQLRETURN;
3433
3434        #[allow(non_snake_case)]
3435        pub fn SQLExecDirectA(
3436            StatementHandle: HSTMT,
3437            StatementText: *const SQLCHAR,
3438            TextLength: SQLINTEGER,
3439        ) -> SQLRETURN;
3440
3441        #[allow(non_snake_case)]
3442        pub fn SQLExecDirectW(
3443            StatementHandle: HSTMT,
3444            StatementText: *const SQLWCHAR,
3445            TextLength: SQLINTEGER,
3446        ) -> SQLRETURN;
3447
3448        #[allow(non_snake_case)]
3449        pub fn SQLExecute(StatementHandle: HSTMT) -> SQLRETURN;
3450
3451        #[allow(non_snake_case)]
3452        pub fn SQLFetch(StatementHandle: HSTMT) -> SQLRETURN;
3453
3454        #[allow(non_snake_case)]
3455        pub fn SQLFetchScroll(
3456            StatementHandle: HSTMT,
3457            FetchOrientation: SQLSMALLINT,
3458            FetchOffset: SQLLEN,
3459        ) -> SQLRETURN;
3460
3461        #[allow(non_snake_case)]
3462        pub fn SQLForeignKeysA(
3463            StatementHandle: HSTMT,
3464            PKCatalogName: *const SQLCHAR,
3465            NameLength1: SQLSMALLINT,
3466            PKSchemaName: *const SQLCHAR,
3467            NameLength2: SQLSMALLINT,
3468            PKTableName: *const SQLCHAR,
3469            NameLength3: SQLSMALLINT,
3470            FKCatalogName: *const SQLCHAR,
3471            NameLength4: SQLSMALLINT,
3472            FKSchemaName: *const SQLCHAR,
3473            NameLength5: SQLSMALLINT,
3474            FKTableName: *const SQLCHAR,
3475            NameLength6: SQLSMALLINT,
3476        ) -> SQLRETURN;
3477
3478        #[allow(non_snake_case)]
3479        pub fn SQLForeignKeysW(
3480            StatementHandle: HSTMT,
3481            PKCatalogName: *const SQLWCHAR,
3482            NameLength1: SQLSMALLINT,
3483            PKSchemaName: *const SQLWCHAR,
3484            NameLength2: SQLSMALLINT,
3485            PKTableName: *const SQLWCHAR,
3486            NameLength3: SQLSMALLINT,
3487            FKCatalogName: *const SQLWCHAR,
3488            NameLength4: SQLSMALLINT,
3489            FKSchemaName: *const SQLWCHAR,
3490            NameLength5: SQLSMALLINT,
3491            FKTableName: *const SQLWCHAR,
3492            NameLength6: SQLSMALLINT,
3493        ) -> SQLRETURN;
3494
3495        #[allow(non_snake_case)]
3496        pub fn SQLFreeHandle(HandleType: SQLSMALLINT, Handle: SQLHANDLE) -> SQLRETURN;
3497
3498        #[allow(non_snake_case)]
3499        pub fn SQLFreeStmt(StatementHandle: HSTMT, Option: SQLUSMALLINT) -> SQLRETURN;
3500
3501        #[allow(non_snake_case)]
3502        pub fn SQLGetConnectAttrA(
3503            ConnectionHandle: HDBC,
3504            Attribute: SQLINTEGER,
3505            ValuePtr: MutSQLPOINTER,
3506            BufferLength: SQLINTEGER,
3507            StringLengthPtr: *mut SQLINTEGER,
3508        ) -> SQLRETURN;
3509
3510        #[allow(non_snake_case)]
3511        pub fn SQLGetConnectAttrW(
3512            ConnectionHandle: HDBC,
3513            Attribute: SQLINTEGER,
3514            ValuePtr: MutSQLPOINTER,
3515            BufferLength: SQLINTEGER,
3516            StringLengthPtr: *mut SQLINTEGER,
3517        ) -> SQLRETURN;
3518
3519        #[allow(non_snake_case)]
3520        pub fn SQLGetCursorNameA(
3521            StatementHandle: HSTMT,
3522            CursorName: *mut SQLCHAR,
3523            BufferLength: SQLSMALLINT,
3524            NameLengthPtr: *mut SQLSMALLINT,
3525        ) -> SQLRETURN;
3526
3527        #[allow(non_snake_case)]
3528        pub fn SQLGetCursorNameW(
3529            StatementHandle: HSTMT,
3530            CursorName: *mut SQLWCHAR,
3531            BufferLength: SQLSMALLINT,
3532            NameLengthPtr: *mut SQLSMALLINT,
3533        ) -> SQLRETURN;
3534
3535        #[allow(non_snake_case)]
3536        pub fn SQLGetData(
3537            StatementHandle: HSTMT,
3538            Col_or_Param_Num: SQLUSMALLINT,
3539            TargetType: SQLSMALLINT,
3540            TargetValuePtr: MutSQLPOINTER,
3541            BufferLength: SQLLEN,
3542            StrLen_or_IndPtr: *mut SQLLEN,
3543        ) -> SQLRETURN;
3544
3545        #[allow(non_snake_case)]
3546        pub fn SQLGetDescFieldA(
3547            DescriptorHandle: HDESC,
3548            RecNumber: SQLSMALLINT,
3549            FieldIdentifier: SQLSMALLINT,
3550            ValuePtr: MutSQLPOINTER,
3551            BufferLength: SQLINTEGER,
3552            StringLengthPtr: *mut SQLINTEGER,
3553        ) -> SQLRETURN;
3554
3555        #[allow(non_snake_case)]
3556        pub fn SQLGetDescFieldW(
3557            DescriptorHandle: HDESC,
3558            RecNumber: SQLSMALLINT,
3559            FieldIdentifier: SQLSMALLINT,
3560            ValuePtr: MutSQLPOINTER,
3561            BufferLength: SQLINTEGER,
3562            StringLengthPtr: *mut SQLINTEGER,
3563        ) -> SQLRETURN;
3564
3565        #[allow(non_snake_case)]
3566        pub fn SQLGetDescRecA(
3567            DescriptorHandle: HDESC,
3568            RecNumber: SQLSMALLINT,
3569            Name: *mut SQLCHAR,
3570            BufferLength: SQLSMALLINT,
3571            StringLengthPtr: *mut SQLSMALLINT,
3572            TypePtr: *mut SQLSMALLINT,
3573            SubTypePtr: *mut SQLSMALLINT,
3574            LengthPtr: *mut SQLLEN,
3575            PrecisionPtr: *mut SQLSMALLINT,
3576            ScalePtr: *mut SQLSMALLINT,
3577            NullablePtr: *mut SQLSMALLINT,
3578        ) -> SQLRETURN;
3579
3580        #[allow(non_snake_case)]
3581        pub fn SQLGetDescRecW(
3582            DescriptorHandle: HDESC,
3583            RecNumber: SQLSMALLINT,
3584            Name: *mut SQLWCHAR,
3585            BufferLength: SQLSMALLINT,
3586            StringLengthPtr: *mut SQLSMALLINT,
3587            TypePtr: *mut SQLSMALLINT,
3588            SubTypePtr: *mut SQLSMALLINT,
3589            LengthPtr: *mut SQLLEN,
3590            PrecisionPtr: *mut SQLSMALLINT,
3591            ScalePtr: *mut SQLSMALLINT,
3592            NullablePtr: *mut SQLSMALLINT,
3593        ) -> SQLRETURN;
3594
3595        #[allow(non_snake_case)]
3596        pub fn SQLGetDiagFieldA(
3597            HandleType: SQLSMALLINT,
3598            Handle: SQLHANDLE,
3599            RecNumber: SQLSMALLINT,
3600            DiagIdentifier: SQLSMALLINT,
3601            DiagInfoPtr: MutSQLPOINTER,
3602            BufferLength: SQLSMALLINT,
3603            StringLengthPtr: *mut SQLSMALLINT,
3604        ) -> SQLRETURN;
3605
3606        #[allow(non_snake_case)]
3607        pub fn SQLGetDiagFieldW(
3608            HandleType: SQLSMALLINT,
3609            Handle: SQLHANDLE,
3610            RecNumber: SQLSMALLINT,
3611            DiagIdentifier: SQLSMALLINT,
3612            DiagInfoPtr: MutSQLPOINTER,
3613            BufferLength: SQLSMALLINT,
3614            StringLengthPtr: *mut SQLSMALLINT,
3615        ) -> SQLRETURN;
3616
3617        #[allow(non_snake_case)]
3618        pub fn SQLGetDiagRecA(
3619            HandleType: SQLSMALLINT,
3620            Handle: SQLHANDLE,
3621            RecNumber: SQLSMALLINT,
3622            SQLState: *mut [SQLCHAR; SQLSTATE_SIZE + 1],
3623            NativeErrorPtr: *mut SQLINTEGER,
3624            MessageText: *mut SQLCHAR,
3625            BufferLength: SQLSMALLINT,
3626            TextLengthPtr: *mut SQLSMALLINT,
3627        ) -> SQLRETURN;
3628
3629        #[allow(non_snake_case)]
3630        pub fn SQLGetDiagRecW(
3631            HandleType: SQLSMALLINT,
3632            Handle: SQLHANDLE,
3633            RecNumber: SQLSMALLINT,
3634            SQLState: *mut [SQLWCHAR; SQLSTATE_SIZE + 1],
3635            NativeErrorPtr: *mut SQLINTEGER,
3636            MessageText: *mut SQLWCHAR,
3637            BufferLength: SQLSMALLINT,
3638            TextLengthPtr: *mut SQLSMALLINT,
3639        ) -> SQLRETURN;
3640
3641        #[allow(non_snake_case)]
3642        pub fn SQLGetEnvAttr(
3643            EnvironmentHandle: HENV,
3644            Attribute: SQLINTEGER,
3645            ValuePtr: MutSQLPOINTER,
3646            BufferLength: SQLINTEGER,
3647            StringLengthPtr: *mut SQLINTEGER,
3648        ) -> SQLRETURN;
3649
3650        #[allow(non_snake_case)]
3651        pub fn SQLGetFunctions(
3652            ConnectionHandle: HDBC,
3653            FunctionId: SQLUSMALLINT,
3654            SupportedPtr: *mut SQLUSMALLINT,
3655        ) -> SQLRETURN;
3656
3657        #[allow(non_snake_case)]
3658        pub fn SQLGetInfoA(
3659            ConnectionHandle: HDBC,
3660            InfoType: SQLUSMALLINT,
3661            InfoValuePtr: MutSQLPOINTER,
3662            BufferLength: SQLSMALLINT,
3663            StringLengthPtr: *mut SQLSMALLINT,
3664        ) -> SQLRETURN;
3665
3666        #[allow(non_snake_case)]
3667        pub fn SQLGetInfoW(
3668            ConnectionHandle: HDBC,
3669            InfoType: SQLUSMALLINT,
3670            InfoValuePtr: MutSQLPOINTER,
3671            BufferLength: SQLSMALLINT,
3672            StringLengthPtr: *mut SQLSMALLINT,
3673        ) -> SQLRETURN;
3674
3675        #[allow(non_snake_case)]
3676        pub fn SQLGetStmtAttrA(
3677            StatementHandle: HSTMT,
3678            Attribute: SQLINTEGER,
3679            ValuePtr: MutSQLPOINTER,
3680            BufferLength: SQLINTEGER,
3681            StringLengthPtr: *mut SQLINTEGER,
3682        ) -> SQLRETURN;
3683
3684        #[allow(non_snake_case)]
3685        pub fn SQLGetStmtAttrW(
3686            StatementHandle: HSTMT,
3687            Attribute: SQLINTEGER,
3688            ValuePtr: MutSQLPOINTER,
3689            BufferLength: SQLINTEGER,
3690            StringLengthPtr: *mut SQLINTEGER,
3691        ) -> SQLRETURN;
3692
3693        #[allow(non_snake_case)]
3694        pub fn SQLGetTypeInfoA(StatementHandle: HSTMT, DataType: SQLSMALLINT) -> SQLRETURN;
3695
3696        #[allow(non_snake_case)]
3697        pub fn SQLGetTypeInfoW(StatementHandle: HSTMT, DataType: SQLSMALLINT) -> SQLRETURN;
3698
3699        #[allow(non_snake_case)]
3700        pub fn SQLMoreResults(StatementHandle: HSTMT) -> SQLRETURN;
3701
3702        #[allow(non_snake_case)]
3703        pub fn SQLNativeSqlA(
3704            ConnectionHandle: HDBC,
3705            InStatementText: *const SQLCHAR,
3706            TextLength1: SQLINTEGER,
3707            OutStatementText: *mut SQLCHAR,
3708            BufferLength: SQLINTEGER,
3709            TextLength2Ptr: *mut SQLINTEGER,
3710        ) -> SQLRETURN;
3711
3712        #[allow(non_snake_case)]
3713        pub fn SQLNativeSqlW(
3714            ConnectionHandle: HDBC,
3715            InStatementText: *const SQLWCHAR,
3716            TextLength1: SQLINTEGER,
3717            OutStatementText: *mut SQLWCHAR,
3718            BufferLength: SQLINTEGER,
3719            TextLength2Ptr: *mut SQLINTEGER,
3720        ) -> SQLRETURN;
3721
3722        #[allow(non_snake_case)]
3723        pub fn SQLNumParams(
3724            StatementHandle: HSTMT,
3725            ParameterCountPtr: *mut SQLSMALLINT,
3726        ) -> SQLRETURN;
3727
3728        #[allow(non_snake_case)]
3729        pub fn SQLNumResultCols(
3730            StatementHandle: HSTMT,
3731            ColumnCountPtr: *mut SQLSMALLINT,
3732        ) -> SQLRETURN;
3733
3734        #[allow(non_snake_case)]
3735        pub fn SQLParamData(StatementHandle: HSTMT, ValuePtrPtr: *mut MutSQLPOINTER) -> SQLRETURN;
3736
3737        #[allow(non_snake_case)]
3738        pub fn SQLPrepareA(
3739            StatementHandle: HSTMT,
3740            StatementText: *const SQLCHAR,
3741            TextLength: SQLINTEGER,
3742        ) -> SQLRETURN;
3743
3744        #[allow(non_snake_case)]
3745        pub fn SQLPrepareW(
3746            StatementHandle: HSTMT,
3747            StatementText: *const SQLWCHAR,
3748            TextLength: SQLINTEGER,
3749        ) -> SQLRETURN;
3750
3751        #[allow(non_snake_case)]
3752        pub fn SQLPrimaryKeysA(
3753            StatementHandle: HSTMT,
3754            CatalogName: *const SQLCHAR,
3755            NameLength1: SQLSMALLINT,
3756            SchemaName: *const SQLCHAR,
3757            NameLength2: SQLSMALLINT,
3758            TableName: *const SQLCHAR,
3759            NameLength3: SQLSMALLINT,
3760        ) -> SQLRETURN;
3761
3762        #[allow(non_snake_case)]
3763        pub fn SQLPrimaryKeysW(
3764            StatementHandle: HSTMT,
3765            CatalogName: *const SQLWCHAR,
3766            NameLength1: SQLSMALLINT,
3767            SchemaName: *const SQLWCHAR,
3768            NameLength2: SQLSMALLINT,
3769            TableName: *const SQLWCHAR,
3770            NameLength3: SQLSMALLINT,
3771        ) -> SQLRETURN;
3772
3773        #[allow(non_snake_case)]
3774        pub fn SQLProcedureColumnsA(
3775            StatementHandle: HSTMT,
3776            CatalogName: *const SQLCHAR,
3777            NameLength1: SQLSMALLINT,
3778            SchemaName: *const SQLCHAR,
3779            NameLength2: SQLSMALLINT,
3780            ProcName: *const SQLCHAR,
3781            NameLength3: SQLSMALLINT,
3782            ColumnName: *const SQLCHAR,
3783            NameLength4: SQLSMALLINT,
3784        ) -> SQLRETURN;
3785
3786        #[allow(non_snake_case)]
3787        pub fn SQLProcedureColumnsW(
3788            StatementHandle: HSTMT,
3789            CatalogName: *const SQLWCHAR,
3790            NameLength1: SQLSMALLINT,
3791            SchemaName: *const SQLWCHAR,
3792            NameLength2: SQLSMALLINT,
3793            ProcName: *const SQLWCHAR,
3794            NameLength3: SQLSMALLINT,
3795            ColumnName: *const SQLWCHAR,
3796            NameLength4: SQLSMALLINT,
3797        ) -> SQLRETURN;
3798
3799        #[allow(non_snake_case)]
3800        pub fn SQLProceduresA(
3801            StatementHandle: HSTMT,
3802            CatalogName: *const SQLCHAR,
3803            NameLength1: SQLSMALLINT,
3804            SchemaName: *const SQLCHAR,
3805            NameLength2: SQLSMALLINT,
3806            ProcName: *const SQLCHAR,
3807            NameLength3: SQLSMALLINT,
3808        ) -> SQLRETURN;
3809
3810        #[allow(non_snake_case)]
3811        pub fn SQLProceduresW(
3812            StatementHandle: HSTMT,
3813            CatalogName: *const SQLWCHAR,
3814            NameLength1: SQLSMALLINT,
3815            SchemaName: *const SQLWCHAR,
3816            NameLength2: SQLSMALLINT,
3817            ProcName: *const SQLWCHAR,
3818            NameLength3: SQLSMALLINT,
3819        ) -> SQLRETURN;
3820
3821        #[allow(non_snake_case)]
3822        pub fn SQLPutData(
3823            StatementHandle: HSTMT,
3824            DataPtr: ConstSQLPOINTER,
3825            StrLen_or_Ind: SQLLEN,
3826        ) -> SQLRETURN;
3827
3828        #[allow(non_snake_case)]
3829        pub fn SQLRowCount(StatementHandle: HSTMT, RowCountPtr: *mut SQLLEN) -> SQLRETURN;
3830
3831        #[allow(non_snake_case)]
3832        pub fn SQLSetConnectAttrA(
3833            ConnectionHandle: HDBC,
3834            Attribute: SQLINTEGER,
3835            ValuePtr: ConstSQLPOINTER,
3836            StringLength: SQLINTEGER,
3837        ) -> SQLRETURN;
3838
3839        #[allow(non_snake_case)]
3840        pub fn SQLSetConnectAttrW(
3841            ConnectionHandle: HDBC,
3842            Attribute: SQLINTEGER,
3843            ValuePtr: ConstSQLPOINTER,
3844            StringLength: SQLINTEGER,
3845        ) -> SQLRETURN;
3846
3847        #[allow(non_snake_case)]
3848        pub fn SQLSetCursorNameA(
3849            StatementHandle: HSTMT,
3850            CursorName: *const SQLCHAR,
3851            NameLength: SQLSMALLINT,
3852        ) -> SQLRETURN;
3853
3854        #[allow(non_snake_case)]
3855        pub fn SQLSetCursorNameW(
3856            StatementHandle: HSTMT,
3857            CursorName: *const SQLWCHAR,
3858            NameLength: SQLSMALLINT,
3859        ) -> SQLRETURN;
3860
3861        #[allow(non_snake_case)]
3862        pub fn SQLSetDescFieldA(
3863            DescriptorHandle: HDESC,
3864            RecNumber: SQLSMALLINT,
3865            FieldIdentifier: SQLSMALLINT,
3866            ValuePtr: ConstSQLPOINTER,
3867            BufferLength: SQLINTEGER,
3868        ) -> SQLRETURN;
3869
3870        #[allow(non_snake_case)]
3871        pub fn SQLSetDescFieldW(
3872            DescriptorHandle: HDESC,
3873            RecNumber: SQLSMALLINT,
3874            FieldIdentifier: SQLSMALLINT,
3875            ValuePtr: ConstSQLPOINTER,
3876            BufferLength: SQLINTEGER,
3877        ) -> SQLRETURN;
3878
3879        #[allow(non_snake_case)]
3880        pub fn SQLSetDescRec(
3881            DescriptorHandle: HDESC,
3882            RecNumber: SQLSMALLINT,
3883            Type: SQLSMALLINT,
3884            SubType: SQLSMALLINT,
3885            Length: SQLLEN,
3886            Precision: SQLSMALLINT,
3887            Scale: SQLSMALLINT,
3888            DataPtr: MutSQLPOINTER,
3889            StringLengthPtr: *mut SQLLEN,
3890            IndicatorPtr: *mut SQLLEN,
3891        ) -> SQLRETURN;
3892
3893        #[allow(non_snake_case)]
3894        pub fn SQLSetEnvAttr(
3895            EnvironmentHandle: HENV,
3896            Attribute: SQLINTEGER,
3897            ValuePtr: ConstSQLPOINTER,
3898            StringLength: SQLINTEGER,
3899        ) -> SQLRETURN;
3900
3901        #[allow(non_snake_case)]
3902        pub fn SQLSetPos(
3903            StatementHandle: HSTMT,
3904            RowNumber: SQLSETPOSIROW,
3905            Operation: SQLUSMALLINT,
3906            LockType: SQLUSMALLINT,
3907        ) -> SQLRETURN;
3908
3909        #[allow(non_snake_case)]
3910        pub fn SQLSetStmtAttrA(
3911            StatementHandle: HSTMT,
3912            Attribute: SQLINTEGER,
3913            ValuePtr: ConstSQLPOINTER,
3914            StringLength: SQLINTEGER,
3915        ) -> SQLRETURN;
3916
3917        #[allow(non_snake_case)]
3918        pub fn SQLSetStmtAttrW(
3919            StatementHandle: HSTMT,
3920            Attribute: SQLINTEGER,
3921            ValuePtr: ConstSQLPOINTER,
3922            StringLength: SQLINTEGER,
3923        ) -> SQLRETURN;
3924
3925        #[allow(non_snake_case)]
3926        pub fn SQLSpecialColumnsA(
3927            StatementHandle: HSTMT,
3928            IdentifierType: SQLSMALLINT,
3929            CatalogName: *const SQLCHAR,
3930            NameLength1: SQLSMALLINT,
3931            SchemaName: *const SQLCHAR,
3932            NameLength2: SQLSMALLINT,
3933            TableName: *const SQLCHAR,
3934            NameLength3: SQLSMALLINT,
3935            Scope: SQLSMALLINT,
3936            Nullable: SQLSMALLINT,
3937        ) -> SQLRETURN;
3938
3939        #[allow(non_snake_case)]
3940        pub fn SQLSpecialColumnsW(
3941            StatementHandle: HSTMT,
3942            IdentifierType: SQLSMALLINT,
3943            CatalogName: *const SQLWCHAR,
3944            NameLength1: SQLSMALLINT,
3945            SchemaName: *const SQLWCHAR,
3946            NameLength2: SQLSMALLINT,
3947            TableName: *const SQLWCHAR,
3948            NameLength3: SQLSMALLINT,
3949            Scope: SQLSMALLINT,
3950            Nullable: SQLSMALLINT,
3951        ) -> SQLRETURN;
3952
3953        #[allow(non_snake_case)]
3954        pub fn SQLStatisticsA(
3955            StatementHandle: HSTMT,
3956            CatalogName: *const SQLCHAR,
3957            NameLength1: SQLSMALLINT,
3958            SchemaName: *const SQLCHAR,
3959            NameLength2: SQLSMALLINT,
3960            TableName: *const SQLCHAR,
3961            NameLength3: SQLSMALLINT,
3962            Unique: SQLUSMALLINT,
3963            Reserved: SQLUSMALLINT,
3964        ) -> SQLRETURN;
3965
3966        #[allow(non_snake_case)]
3967        pub fn SQLStatisticsW(
3968            StatementHandle: HSTMT,
3969            CatalogName: *const SQLWCHAR,
3970            NameLength1: SQLSMALLINT,
3971            SchemaName: *const SQLWCHAR,
3972            NameLength2: SQLSMALLINT,
3973            TableName: *const SQLWCHAR,
3974            NameLength3: SQLSMALLINT,
3975            Unique: SQLUSMALLINT,
3976            Reserved: SQLUSMALLINT,
3977        ) -> SQLRETURN;
3978
3979        #[allow(non_snake_case)]
3980        pub fn SQLTablePrivilegesA(
3981            StatementHandle: HSTMT,
3982            CatalogName: *const SQLCHAR,
3983            NameLength1: SQLSMALLINT,
3984            SchemaName: *const SQLCHAR,
3985            NameLength2: SQLSMALLINT,
3986            TableName: *const SQLCHAR,
3987            NameLength3: SQLSMALLINT,
3988        ) -> SQLRETURN;
3989
3990        #[allow(non_snake_case)]
3991        pub fn SQLTablePrivilegesW(
3992            StatementHandle: HSTMT,
3993            CatalogName: *const SQLWCHAR,
3994            NameLength1: SQLSMALLINT,
3995            SchemaName: *const SQLWCHAR,
3996            NameLength2: SQLSMALLINT,
3997            TableName: *const SQLWCHAR,
3998            NameLength3: SQLSMALLINT,
3999        ) -> SQLRETURN;
4000
4001        #[allow(non_snake_case)]
4002        pub fn SQLTablesA(
4003            StatementHandle: HSTMT,
4004            CatalogName: *const SQLCHAR,
4005            NameLength1: SQLSMALLINT,
4006            SchemaName: *const SQLCHAR,
4007            NameLength2: SQLSMALLINT,
4008            TableName: *const SQLCHAR,
4009            NameLength3: SQLSMALLINT,
4010            TableType: *const SQLCHAR,
4011            NameLength4: SQLSMALLINT,
4012        ) -> SQLRETURN;
4013
4014        #[allow(non_snake_case)]
4015        pub fn SQLTablesW(
4016            StatementHandle: HSTMT,
4017            CatalogName: *const SQLWCHAR,
4018            NameLength1: SQLSMALLINT,
4019            SchemaName: *const SQLWCHAR,
4020            NameLength2: SQLSMALLINT,
4021            TableName: *const SQLWCHAR,
4022            NameLength3: SQLSMALLINT,
4023            TableType: *const SQLWCHAR,
4024            NameLength4: SQLSMALLINT,
4025        ) -> SQLRETURN;
4026    }
4027}