Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions mssql_python/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def _validate_encoding(encoding: str) -> bool:
ProgrammingError,
NotSupportedError,
)
from mssql_python.constants import GetInfoConstants


class Connection:
Expand Down Expand Up @@ -544,6 +545,30 @@ def getdecoding(self, sqltype):

return self._decoding_settings[sqltype].copy()

@property
def searchescape(self):
"""
The ODBC search pattern escape character, as returned by
SQLGetInfo(SQL_SEARCH_PATTERN_ESCAPE), used to escape special characters
such as '%' and '_' in LIKE clauses. These are driver specific.

Returns:
str: The search pattern escape character (usually '\' or another character)
"""
if not hasattr(self, '_searchescape'):
try:
escape_char = self.getinfo(GetInfoConstants.SQL_SEARCH_PATTERN_ESCAPE.value)
# Some drivers might return this as an integer memory address
# or other non-string format, so ensure we have a string
if not isinstance(escape_char, str):
escape_char = '\\' # Default to backslash if not a string
self._searchescape = escape_char
except Exception as e:
# Log the exception for debugging, but do not expose sensitive info
log('warning', f"Failed to retrieve search escape character, using default '\\'. Exception: {type(e).__name__}")
self._searchescape = '\\'
return self._searchescape

def cursor(self) -> Cursor:
"""
Return a new Cursor object using the connection.
Expand Down Expand Up @@ -824,6 +849,30 @@ def batch_execute(self, statements, params=None, reuse_cursor=None, auto_close=F
log('debug', "Automatically closed cursor after batch execution")

return results, cursor

def getinfo(self, info_type):
"""
Return general information about the driver and data source.

Args:
info_type (int): The type of information to return. See the ODBC
SQLGetInfo documentation for the supported values.

Returns:
The requested information. The type of the returned value depends
on the information requested. It will be a string, integer, or boolean.

Raises:
DatabaseError: If there is an error retrieving the information.
InterfaceError: If the connection is closed.
"""
if self._closed:
raise InterfaceError(
driver_error="Cannot get info on closed connection",
ddbc_error="Cannot get info on closed connection",
)

return self._conn.get_info(info_type)

def commit(self) -> None:
"""
Expand Down
138 changes: 138 additions & 0 deletions mssql_python/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,144 @@ class ConstantsDDBC(Enum):
SQL_QUICK = 0
SQL_ENSURE = 1

class GetInfoConstants(Enum):
"""
These constants are used with various methods like getinfo().
"""

# Driver and database information
SQL_DRIVER_NAME = 6
SQL_DRIVER_VER = 7
SQL_DRIVER_ODBC_VER = 77
SQL_DRIVER_HLIB = 76
SQL_DRIVER_HENV = 75
SQL_DRIVER_HDBC = 74
SQL_DATA_SOURCE_NAME = 2
SQL_DATABASE_NAME = 16
SQL_SERVER_NAME = 13
SQL_USER_NAME = 47

# SQL conformance and support
SQL_SQL_CONFORMANCE = 118
SQL_KEYWORDS = 89
SQL_IDENTIFIER_CASE = 28
SQL_IDENTIFIER_QUOTE_CHAR = 29
SQL_SPECIAL_CHARACTERS = 94
SQL_SQL92_ENTRY_SQL = 127
SQL_SQL92_INTERMEDIATE_SQL = 128
SQL_SQL92_FULL_SQL = 129
SQL_SUBQUERIES = 95
SQL_EXPRESSIONS_IN_ORDERBY = 27
SQL_CORRELATION_NAME = 74
SQL_SEARCH_PATTERN_ESCAPE = 14

# Catalog and schema support
SQL_CATALOG_TERM = 42
SQL_CATALOG_NAME_SEPARATOR = 41
SQL_SCHEMA_TERM = 39
SQL_TABLE_TERM = 45
SQL_PROCEDURES = 21
SQL_ACCESSIBLE_TABLES = 19
SQL_ACCESSIBLE_PROCEDURES = 20
SQL_CATALOG_NAME = 10002
SQL_CATALOG_USAGE = 92
SQL_SCHEMA_USAGE = 91
SQL_COLUMN_ALIAS = 87
SQL_DESCRIBE_PARAMETER = 10003

# Transaction support
SQL_TXN_CAPABLE = 46
SQL_TXN_ISOLATION_OPTION = 72
SQL_DEFAULT_TXN_ISOLATION = 26
SQL_MULTIPLE_ACTIVE_TXN = 37
SQL_TXN_ISOLATION_LEVEL = 108

# Data type support
SQL_NUMERIC_FUNCTIONS = 49
SQL_STRING_FUNCTIONS = 50
SQL_DATETIME_FUNCTIONS = 51
SQL_SYSTEM_FUNCTIONS = 58
SQL_CONVERT_FUNCTIONS = 48
SQL_LIKE_ESCAPE_CLAUSE = 113

# Numeric limits
SQL_MAX_COLUMN_NAME_LEN = 30
SQL_MAX_TABLE_NAME_LEN = 35
SQL_MAX_SCHEMA_NAME_LEN = 32
SQL_MAX_CATALOG_NAME_LEN = 34
SQL_MAX_IDENTIFIER_LEN = 10005
SQL_MAX_STATEMENT_LEN = 105
SQL_MAX_CHAR_LITERAL_LEN = 108
SQL_MAX_BINARY_LITERAL_LEN = 112
SQL_MAX_COLUMNS_IN_TABLE = 101
SQL_MAX_COLUMNS_IN_SELECT = 100
SQL_MAX_COLUMNS_IN_GROUP_BY = 97
SQL_MAX_COLUMNS_IN_ORDER_BY = 99
SQL_MAX_COLUMNS_IN_INDEX = 98
SQL_MAX_TABLES_IN_SELECT = 106
SQL_MAX_CONCURRENT_ACTIVITIES = 1
SQL_MAX_DRIVER_CONNECTIONS = 0
SQL_MAX_ROW_SIZE = 104
SQL_MAX_USER_NAME_LEN = 107

# Connection attributes
SQL_ACTIVE_CONNECTIONS = 0
SQL_ACTIVE_STATEMENTS = 1
SQL_DATA_SOURCE_READ_ONLY = 25
SQL_NEED_LONG_DATA_LEN = 111
SQL_GETDATA_EXTENSIONS = 81

# Result set and cursor attributes
SQL_CURSOR_COMMIT_BEHAVIOR = 23
SQL_CURSOR_ROLLBACK_BEHAVIOR = 24
SQL_CURSOR_SENSITIVITY = 10001
SQL_BOOKMARK_PERSISTENCE = 82
SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144
SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147
SQL_STATIC_CURSOR_ATTRIBUTES1 = 150
SQL_STATIC_CURSOR_ATTRIBUTES2 = 151
SQL_KEYSET_CURSOR_ATTRIBUTES1 = 148
SQL_KEYSET_CURSOR_ATTRIBUTES2 = 149
SQL_SCROLL_OPTIONS = 44
SQL_SCROLL_CONCURRENCY = 43
SQL_FETCH_DIRECTION = 8
SQL_ROWSET_SIZE = 9
SQL_CONCURRENCY = 7
SQL_ROW_NUMBER = 14
SQL_STATIC_SENSITIVITY = 83
SQL_BATCH_SUPPORT = 121
SQL_BATCH_ROW_COUNT = 120
SQL_PARAM_ARRAY_ROW_COUNTS = 153
SQL_PARAM_ARRAY_SELECTS = 154

# Positioned statement support
SQL_POSITIONED_STATEMENTS = 80

# Other constants
SQL_GROUP_BY = 88
SQL_OJ_CAPABILITIES = 65
SQL_ORDER_BY_COLUMNS_IN_SELECT = 90
SQL_OUTER_JOINS = 38
SQL_QUOTED_IDENTIFIER_CASE = 93
SQL_CONCAT_NULL_BEHAVIOR = 22
SQL_NULL_COLLATION = 85
SQL_ALTER_TABLE = 86
SQL_UNION = 96
SQL_DDL_INDEX = 170
SQL_MULT_RESULT_SETS = 36
SQL_OWNER_USAGE = 91
SQL_QUALIFIER_USAGE = 92
SQL_TIMEDATE_ADD_INTERVALS = 109
SQL_TIMEDATE_DIFF_INTERVALS = 110

# Return values for some getinfo functions
SQL_IC_UPPER = 1
SQL_IC_LOWER = 2
SQL_IC_SENSITIVE = 3
SQL_IC_MIXED = 4

class AuthType(Enum):
"""Constants for authentication types"""
INTERACTIVE = "activedirectoryinteractive"
Expand Down
Loading
Loading