odbc_safe/
sql_str.rs

1use sys::*;
2use std::ffi::CStr;
3use std::ptr::null;
4
5/// A type implementing this trait can be passed as a string argument in API calls
6pub unsafe trait SqlStr {
7    /// Returns a pointer to the start of the string
8    fn as_text_ptr(&self) -> *const SQLCHAR;
9    /// Returns buffer length or SQL_NTS
10    fn text_length(&self) -> SQLSMALLINT;
11    /// Returns buffer length or SQL_NTSL
12    fn text_length_int(&self) -> SQLINTEGER;
13}
14
15unsafe impl SqlStr for CStr {
16    fn as_text_ptr(&self) -> *const SQLCHAR {
17        self.as_ptr() as *const SQLCHAR
18    }
19
20    fn text_length(&self) -> SQLSMALLINT {
21        SQL_NTS
22    }
23
24    fn text_length_int(&self) -> SQLINTEGER {
25        SQL_NTSL
26    }
27}
28
29/// For passing a buffer without terminating NULL
30unsafe impl SqlStr for [u8] {
31    fn as_text_ptr(&self) -> *const SQLCHAR {
32        if self.is_empty() {
33            null()
34        } else {
35            self.as_ptr()
36        }
37    }
38
39    fn text_length(&self) -> SQLSMALLINT {
40        if self.len() > SQLSMALLINT::max_value() as usize {
41            panic!(
42                "Buffer length of {} is greater than SQLSMALLINT::MAX: {}",
43                self.len(),
44                SQLSMALLINT::max_value()
45            );
46        }
47        self.len() as SQLSMALLINT
48    }
49
50    fn text_length_int(&self) -> SQLINTEGER {
51        if self.len() > SQLINTEGER::max_value() as usize {
52            panic!(
53                "Buffer length of {} is greater than SQLINTEGER::MAX: {}",
54                self.len(),
55                SQLINTEGER::max_value()
56            );
57        }
58        self.len() as SQLINTEGER
59    }
60}
61
62/// For passing a buffer without terminating NULL
63unsafe impl SqlStr for str {
64    fn as_text_ptr(&self) -> *const SQLCHAR {
65        if self.is_empty() {
66            null()
67        } else {
68            self.as_ptr()
69        }
70    }
71
72    fn text_length(&self) -> SQLSMALLINT {
73        if self.len() > SQLSMALLINT::max_value() as usize {
74            panic!(
75                "Buffer length of {} is greater than SQLSMALLINT::MAX: {}",
76                self.len(),
77                SQLSMALLINT::max_value()
78            );
79        }
80        // str::len is in bytes, so this should work
81        self.len() as SQLSMALLINT
82    }
83
84    fn text_length_int(&self) -> SQLINTEGER {
85        if self.len() > SQLINTEGER::max_value() as usize {
86            panic!(
87                "Buffer length of {} is greater than SQLINTEGER::MAX: {}",
88                self.len(),
89                SQLINTEGER::max_value()
90            );
91        }
92
93        self.len() as SQLINTEGER
94    }
95}