Skip to content

Commit bd5b323

Browse files
authored
FEAT: Adding getInfo (#201)
1 parent c14cc42 commit bd5b323

File tree

9 files changed

+1011
-34
lines changed

9 files changed

+1011
-34
lines changed

mssql_python/connection.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def _validate_encoding(encoding: str) -> bool:
6666
ProgrammingError,
6767
NotSupportedError,
6868
)
69+
from mssql_python.constants import GetInfoConstants
6970

7071

7172
class Connection:
@@ -544,6 +545,30 @@ def getdecoding(self, sqltype):
544545

545546
return self._decoding_settings[sqltype].copy()
546547

548+
@property
549+
def searchescape(self):
550+
"""
551+
The ODBC search pattern escape character, as returned by
552+
SQLGetInfo(SQL_SEARCH_PATTERN_ESCAPE), used to escape special characters
553+
such as '%' and '_' in LIKE clauses. These are driver specific.
554+
555+
Returns:
556+
str: The search pattern escape character (usually '\' or another character)
557+
"""
558+
if not hasattr(self, '_searchescape'):
559+
try:
560+
escape_char = self.getinfo(GetInfoConstants.SQL_SEARCH_PATTERN_ESCAPE.value)
561+
# Some drivers might return this as an integer memory address
562+
# or other non-string format, so ensure we have a string
563+
if not isinstance(escape_char, str):
564+
escape_char = '\\' # Default to backslash if not a string
565+
self._searchescape = escape_char
566+
except Exception as e:
567+
# Log the exception for debugging, but do not expose sensitive info
568+
log('warning', f"Failed to retrieve search escape character, using default '\\'. Exception: {type(e).__name__}")
569+
self._searchescape = '\\'
570+
return self._searchescape
571+
547572
def cursor(self) -> Cursor:
548573
"""
549574
Return a new Cursor object using the connection.
@@ -824,6 +849,30 @@ def batch_execute(self, statements, params=None, reuse_cursor=None, auto_close=F
824849
log('debug', "Automatically closed cursor after batch execution")
825850

826851
return results, cursor
852+
853+
def getinfo(self, info_type):
854+
"""
855+
Return general information about the driver and data source.
856+
857+
Args:
858+
info_type (int): The type of information to return. See the ODBC
859+
SQLGetInfo documentation for the supported values.
860+
861+
Returns:
862+
The requested information. The type of the returned value depends
863+
on the information requested. It will be a string, integer, or boolean.
864+
865+
Raises:
866+
DatabaseError: If there is an error retrieving the information.
867+
InterfaceError: If the connection is closed.
868+
"""
869+
if self._closed:
870+
raise InterfaceError(
871+
driver_error="Cannot get info on closed connection",
872+
ddbc_error="Cannot get info on closed connection",
873+
)
874+
875+
return self._conn.get_info(info_type)
827876

828877
def commit(self) -> None:
829878
"""

mssql_python/constants.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,144 @@ class ConstantsDDBC(Enum):
134134
SQL_QUICK = 0
135135
SQL_ENSURE = 1
136136

137+
class GetInfoConstants(Enum):
138+
"""
139+
These constants are used with various methods like getinfo().
140+
"""
141+
142+
# Driver and database information
143+
SQL_DRIVER_NAME = 6
144+
SQL_DRIVER_VER = 7
145+
SQL_DRIVER_ODBC_VER = 77
146+
SQL_DRIVER_HLIB = 76
147+
SQL_DRIVER_HENV = 75
148+
SQL_DRIVER_HDBC = 74
149+
SQL_DATA_SOURCE_NAME = 2
150+
SQL_DATABASE_NAME = 16
151+
SQL_SERVER_NAME = 13
152+
SQL_USER_NAME = 47
153+
154+
# SQL conformance and support
155+
SQL_SQL_CONFORMANCE = 118
156+
SQL_KEYWORDS = 89
157+
SQL_IDENTIFIER_CASE = 28
158+
SQL_IDENTIFIER_QUOTE_CHAR = 29
159+
SQL_SPECIAL_CHARACTERS = 94
160+
SQL_SQL92_ENTRY_SQL = 127
161+
SQL_SQL92_INTERMEDIATE_SQL = 128
162+
SQL_SQL92_FULL_SQL = 129
163+
SQL_SUBQUERIES = 95
164+
SQL_EXPRESSIONS_IN_ORDERBY = 27
165+
SQL_CORRELATION_NAME = 74
166+
SQL_SEARCH_PATTERN_ESCAPE = 14
167+
168+
# Catalog and schema support
169+
SQL_CATALOG_TERM = 42
170+
SQL_CATALOG_NAME_SEPARATOR = 41
171+
SQL_SCHEMA_TERM = 39
172+
SQL_TABLE_TERM = 45
173+
SQL_PROCEDURES = 21
174+
SQL_ACCESSIBLE_TABLES = 19
175+
SQL_ACCESSIBLE_PROCEDURES = 20
176+
SQL_CATALOG_NAME = 10002
177+
SQL_CATALOG_USAGE = 92
178+
SQL_SCHEMA_USAGE = 91
179+
SQL_COLUMN_ALIAS = 87
180+
SQL_DESCRIBE_PARAMETER = 10003
181+
182+
# Transaction support
183+
SQL_TXN_CAPABLE = 46
184+
SQL_TXN_ISOLATION_OPTION = 72
185+
SQL_DEFAULT_TXN_ISOLATION = 26
186+
SQL_MULTIPLE_ACTIVE_TXN = 37
187+
SQL_TXN_ISOLATION_LEVEL = 108
188+
189+
# Data type support
190+
SQL_NUMERIC_FUNCTIONS = 49
191+
SQL_STRING_FUNCTIONS = 50
192+
SQL_DATETIME_FUNCTIONS = 51
193+
SQL_SYSTEM_FUNCTIONS = 58
194+
SQL_CONVERT_FUNCTIONS = 48
195+
SQL_LIKE_ESCAPE_CLAUSE = 113
196+
197+
# Numeric limits
198+
SQL_MAX_COLUMN_NAME_LEN = 30
199+
SQL_MAX_TABLE_NAME_LEN = 35
200+
SQL_MAX_SCHEMA_NAME_LEN = 32
201+
SQL_MAX_CATALOG_NAME_LEN = 34
202+
SQL_MAX_IDENTIFIER_LEN = 10005
203+
SQL_MAX_STATEMENT_LEN = 105
204+
SQL_MAX_CHAR_LITERAL_LEN = 108
205+
SQL_MAX_BINARY_LITERAL_LEN = 112
206+
SQL_MAX_COLUMNS_IN_TABLE = 101
207+
SQL_MAX_COLUMNS_IN_SELECT = 100
208+
SQL_MAX_COLUMNS_IN_GROUP_BY = 97
209+
SQL_MAX_COLUMNS_IN_ORDER_BY = 99
210+
SQL_MAX_COLUMNS_IN_INDEX = 98
211+
SQL_MAX_TABLES_IN_SELECT = 106
212+
SQL_MAX_CONCURRENT_ACTIVITIES = 1
213+
SQL_MAX_DRIVER_CONNECTIONS = 0
214+
SQL_MAX_ROW_SIZE = 104
215+
SQL_MAX_USER_NAME_LEN = 107
216+
217+
# Connection attributes
218+
SQL_ACTIVE_CONNECTIONS = 0
219+
SQL_ACTIVE_STATEMENTS = 1
220+
SQL_DATA_SOURCE_READ_ONLY = 25
221+
SQL_NEED_LONG_DATA_LEN = 111
222+
SQL_GETDATA_EXTENSIONS = 81
223+
224+
# Result set and cursor attributes
225+
SQL_CURSOR_COMMIT_BEHAVIOR = 23
226+
SQL_CURSOR_ROLLBACK_BEHAVIOR = 24
227+
SQL_CURSOR_SENSITIVITY = 10001
228+
SQL_BOOKMARK_PERSISTENCE = 82
229+
SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144
230+
SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145
231+
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146
232+
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147
233+
SQL_STATIC_CURSOR_ATTRIBUTES1 = 150
234+
SQL_STATIC_CURSOR_ATTRIBUTES2 = 151
235+
SQL_KEYSET_CURSOR_ATTRIBUTES1 = 148
236+
SQL_KEYSET_CURSOR_ATTRIBUTES2 = 149
237+
SQL_SCROLL_OPTIONS = 44
238+
SQL_SCROLL_CONCURRENCY = 43
239+
SQL_FETCH_DIRECTION = 8
240+
SQL_ROWSET_SIZE = 9
241+
SQL_CONCURRENCY = 7
242+
SQL_ROW_NUMBER = 14
243+
SQL_STATIC_SENSITIVITY = 83
244+
SQL_BATCH_SUPPORT = 121
245+
SQL_BATCH_ROW_COUNT = 120
246+
SQL_PARAM_ARRAY_ROW_COUNTS = 153
247+
SQL_PARAM_ARRAY_SELECTS = 154
248+
249+
# Positioned statement support
250+
SQL_POSITIONED_STATEMENTS = 80
251+
252+
# Other constants
253+
SQL_GROUP_BY = 88
254+
SQL_OJ_CAPABILITIES = 65
255+
SQL_ORDER_BY_COLUMNS_IN_SELECT = 90
256+
SQL_OUTER_JOINS = 38
257+
SQL_QUOTED_IDENTIFIER_CASE = 93
258+
SQL_CONCAT_NULL_BEHAVIOR = 22
259+
SQL_NULL_COLLATION = 85
260+
SQL_ALTER_TABLE = 86
261+
SQL_UNION = 96
262+
SQL_DDL_INDEX = 170
263+
SQL_MULT_RESULT_SETS = 36
264+
SQL_OWNER_USAGE = 91
265+
SQL_QUALIFIER_USAGE = 92
266+
SQL_TIMEDATE_ADD_INTERVALS = 109
267+
SQL_TIMEDATE_DIFF_INTERVALS = 110
268+
269+
# Return values for some getinfo functions
270+
SQL_IC_UPPER = 1
271+
SQL_IC_LOWER = 2
272+
SQL_IC_SENSITIVE = 3
273+
SQL_IC_MIXED = 4
274+
137275
class AuthType(Enum):
138276
"""Constants for authentication types"""
139277
INTERACTIVE = "activedirectoryinteractive"

0 commit comments

Comments
 (0)