Skip to content

Commit 55fa7e4

Browse files
jahnvi480Sumit Sarabhai
authored andcommitted
Merged PR 5344: Refining code
#### AI description (iteration 1) #### PR Classification Code cleanup #### PR Summary This pull request refines and cleans up the codebase, improving readability and maintainability. - `/mssql_python/exceptions.py`: Refactored exception mapping and added docstrings. - `/mssql_python/testing_ddbc_bindings.py`: Added docstrings and improved error handling. - `/mssql_python/cursor.py`: Refactored methods for better readability and added docstrings. - `/tests/test_004_cursor.py`: Added new tests for datetime, date, time, and numeric parsing. - `/mssql_python/helpers.py`, `/mssql_python/connection.py`, `/mssql_python/logging_config.py`, `/mssql_python/constants.py`: Added docstrings and improved error handling. <!-- GitOpsUserAgent=GitOps.Apps.Server.pullrequestcopilot --> Related work items: #33971
1 parent 7056dca commit 55fa7e4

File tree

14 files changed

+1668
-699
lines changed

14 files changed

+1668
-699
lines changed

mssql_python/__init__.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
1-
from .constants import (
2-
ConstantsODBC
3-
)
4-
5-
# GLOBALS
6-
# Read-Only
7-
apilevel = '2.0'
8-
paramstyle = 'qmark'
9-
threadsafety = 1
1+
"""
2+
Copyright (c) Microsoft Corporation.
3+
Licensed under the MIT license.
4+
This module initializes the mssql_python package.
5+
"""
106

117
# Exceptions
128
# https://www.python.org/dev/peps/pep-0249/#exceptions
139
from .exceptions import (
14-
Warning, Error, InterfaceError, DatabaseError, DataError, OperationalError,
15-
IntegrityError, InternalError, ProgrammingError, NotSupportedError
10+
Warning,
11+
Error,
12+
InterfaceError,
13+
DatabaseError,
14+
DataError,
15+
OperationalError,
16+
IntegrityError,
17+
InternalError,
18+
ProgrammingError,
19+
NotSupportedError,
1620
)
1721

1822
# Type Objects
1923
from .type import (
20-
Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks, Binary,
21-
STRING, BINARY, NUMBER, DATETIME, ROWID
24+
Date,
25+
Time,
26+
Timestamp,
27+
DateFromTicks,
28+
TimeFromTicks,
29+
TimestampFromTicks,
30+
Binary,
31+
STRING,
32+
BINARY,
33+
NUMBER,
34+
DATETIME,
35+
ROWID,
2236
)
2337

2438
# Connection Objects
@@ -28,4 +42,14 @@
2842
# Cursor Objects
2943
from .cursor import Cursor
3044

45+
# Logging Configuration
3146
from .logging_config import setup_logging, get_logger
47+
48+
# Constants
49+
from .constants import ConstantsDDBC
50+
51+
# GLOBALS
52+
# Read-Only
53+
apilevel = "2.0"
54+
paramstyle = "qmark"
55+
threadsafety = 1

mssql_python/connection.py

Lines changed: 75 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
"""
2+
Copyright (c) Microsoft Corporation.
3+
Licensed under the MIT license.
4+
This module defines the Connection class, which is used to manage a connection to a database.
5+
The class provides methods to establish a connection, create cursors, commit transactions,
6+
roll back transactions, and close the connection.
7+
"""
18
import ctypes
29
from mssql_python.cursor import Cursor
310
from mssql_python.logging_config import get_logger, ENABLE_LOGGING
4-
from mssql_python.constants import ConstantsODBC as odbc_sql_const
11+
from mssql_python.constants import ConstantsDDBC as ddbc_sql_const
512
from mssql_python.helpers import add_driver_to_connection_str, check_error
6-
import os
713
from mssql_python import ddbc_bindings
814

915
logger = get_logger()
1016

17+
1118
class Connection:
1219
"""
1320
A class to manage a connection to a database, compliant with DB-API 2.0 specifications.
@@ -16,7 +23,7 @@ class Connection:
1623
commit transactions, roll back transactions, and close the connection. It is designed
1724
to be used in a context where database operations are required, such as executing queries
1825
and fetching results.
19-
26+
2027
Methods:
2128
__init__(database: str) -> None:
2229
connect_to_db() -> None:
@@ -25,7 +32,7 @@ class Connection:
2532
rollback() -> None:
2633
close() -> None:
2734
"""
28-
35+
2936
def __init__(self, connection_str: str, autocommit: bool = False, **kwargs) -> None:
3037
"""
3138
Initialize the connection object with the specified connection string and parameters.
@@ -35,26 +42,30 @@ def __init__(self, connection_str: str, autocommit: bool = False, **kwargs) -> N
3542
- autocommit (bool): If True, causes a commit to be performed after each SQL statement.
3643
**kwargs: Additional key/value pairs for the connection string.
3744
Not including below properties since we are driver doesn't support this:
38-
45+
3946
Returns:
4047
None
4148
4249
Raises:
4350
ValueError: If the connection string is invalid or connection fails.
4451
45-
This method sets up the initial state for the connection object,
46-
preparing it for further operations such as connecting to the database, executing queries, etc.
52+
This method sets up the initial state for the connection object,
53+
preparing it for further operations such as connecting to the
54+
database, executing queries, etc.
4755
"""
4856
self.henv = ctypes.c_void_p()
4957
self.hdbc = ctypes.c_void_p()
50-
self.connection_str = self._construct_connection_string(connection_str, **kwargs)
58+
self.connection_str = self._construct_connection_string(
59+
connection_str, **kwargs
60+
)
5161
self._initializer()
5262
self._autocommit = autocommit
5363
self.setautocommit(autocommit)
5464

5565
def _construct_connection_string(self, connection_str: str, **kwargs) -> str:
5666
"""
57-
Construct the connection string by concatenating the connection string with key/value pairs from kwargs.
67+
Construct the connection string by concatenating the connection string
68+
with key/value pairs from kwargs.
5869
5970
Args:
6071
connection_str (str): The base connection string.
@@ -97,40 +108,44 @@ def _initializer(self) -> None:
97108
self._allocate_connection_handle()
98109
self._set_connection_attributes()
99110
self._connect_to_db()
100-
111+
101112
def _allocate_environment_handle(self):
102113
"""
103114
Allocate the environment handle.
104115
"""
105116
ret = ddbc_bindings.DDBCSQLAllocHandle(
106-
odbc_sql_const.SQL_HANDLE_ENV.value, #SQL environment handle type
107-
0, # SQL input handle
108-
ctypes.cast(ctypes.pointer(self.henv), ctypes.c_void_p).value # SQL output handle pointer
117+
ddbc_sql_const.SQL_HANDLE_ENV.value, # SQL environment handle type
118+
0, # SQL input handle
119+
ctypes.cast(
120+
ctypes.pointer(self.henv), ctypes.c_void_p
121+
).value, # SQL output handle pointer
109122
)
110-
check_error(odbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
123+
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
111124

112125
def _set_environment_attributes(self):
113126
"""
114127
Set the environment attributes.
115128
"""
116129
ret = ddbc_bindings.DDBCSQLSetEnvAttr(
117130
self.henv.value, # Environment handle
118-
odbc_sql_const.SQL_ATTR_ODBC_VERSION.value, # Attribute
119-
odbc_sql_const.SQL_OV_ODBC3_80.value, # String Length
120-
0 # Null-terminated string
131+
ddbc_sql_const.SQL_ATTR_DDBC_VERSION.value, # Attribute
132+
ddbc_sql_const.SQL_OV_DDBC3_80.value, # String Length
133+
0, # Null-terminated string
121134
)
122-
check_error(odbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
135+
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
123136

124137
def _allocate_connection_handle(self):
125138
"""
126139
Allocate the connection handle.
127140
"""
128141
ret = ddbc_bindings.DDBCSQLAllocHandle(
129-
odbc_sql_const.SQL_HANDLE_DBC.value, # SQL connection handle type
130-
self.henv.value, # SQL environment handle
131-
ctypes.cast(ctypes.pointer(self.hdbc), ctypes.c_void_p).value # SQL output handle pointer
142+
ddbc_sql_const.SQL_HANDLE_DBC.value, # SQL connection handle type
143+
self.henv.value, # SQL environment handle
144+
ctypes.cast(
145+
ctypes.pointer(self.hdbc), ctypes.c_void_p
146+
).value, # SQL output handle pointer
132147
)
133-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
148+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
134149

135150
def _set_connection_attributes(self):
136151
"""
@@ -139,11 +154,11 @@ def _set_connection_attributes(self):
139154
if self.autocommit:
140155
ret = ddbc_bindings.DDBCSQLSetConnectAttr(
141156
self.hdbc.value,
142-
odbc_sql_const.SQL_ATTR_AUTOCOMMIT.value,
143-
odbc_sql_const.SQL_AUTOCOMMIT_ON.value,
144-
0
157+
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value,
158+
ddbc_sql_const.SQL_AUTOCOMMIT_ON.value,
159+
0,
145160
)
146-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
161+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
147162

148163
def _connect_to_db(self) -> None:
149164
"""
@@ -161,11 +176,11 @@ def _connect_to_db(self) -> None:
161176
if ENABLE_LOGGING:
162177
logger.info("Connecting to the database")
163178
ret = ddbc_bindings.DDBCSQLDriverConnect(
164-
self.hdbc.value, # Connection handle
165-
0, # Window handle
166-
self.connection_str # Connection string
179+
self.hdbc.value, # Connection handle
180+
0, # Window handle
181+
self.connection_str, # Connection string
167182
)
168-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
183+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
169184
if ENABLE_LOGGING:
170185
logger.info("Connection established successfully.")
171186

@@ -178,10 +193,12 @@ def autocommit(self) -> bool:
178193
"""
179194
autocommit_mode = ddbc_bindings.DDBCSQLGetConnectionAttr(
180195
self.hdbc.value, # Connection handle
181-
odbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
196+
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
197+
)
198+
check_error(
199+
ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, autocommit_mode
182200
)
183-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, autocommit_mode)
184-
return autocommit_mode == odbc_sql_const.SQL_AUTOCOMMIT_ON.value
201+
return autocommit_mode == ddbc_sql_const.SQL_AUTOCOMMIT_ON.value
185202

186203
@autocommit.setter
187204
def autocommit(self, value: bool) -> None:
@@ -196,11 +213,15 @@ def autocommit(self, value: bool) -> None:
196213
"""
197214
ret = ddbc_bindings.DDBCSQLSetConnectAttr(
198215
self.hdbc.value, # Connection handle
199-
odbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
200-
odbc_sql_const.SQL_AUTOCOMMIT_ON.value if value else odbc_sql_const.SQL_AUTOCOMMIT_OFF.value, # Value
201-
0 # String length
216+
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
217+
(
218+
ddbc_sql_const.SQL_AUTOCOMMIT_ON.value
219+
if value
220+
else ddbc_sql_const.SQL_AUTOCOMMIT_OFF.value
221+
), # Value
222+
0, # String length
202223
)
203-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
224+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
204225
self._autocommit = value
205226
if ENABLE_LOGGING:
206227
logger.info("Autocommit mode set to %s.", value)
@@ -230,14 +251,14 @@ def cursor(self) -> Cursor:
230251
231252
Raises:
232253
DatabaseError: If there is an error while creating the cursor.
233-
InterfaceError: If there is an error related to the database interface.
254+
InterfaceError: If there is an error related to the database interface.
234255
"""
235256
return Cursor(self)
236257

237258
def commit(self) -> None:
238259
"""
239260
Commit the current transaction.
240-
261+
241262
This method commits the current transaction to the database, making all
242263
changes made during the transaction permanent. It should be called after
243264
executing a series of SQL statements that modify the database to ensure
@@ -248,11 +269,11 @@ def commit(self) -> None:
248269
"""
249270
# Commit the current transaction
250271
ret = ddbc_bindings.DDBCSQLEndTran(
251-
odbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
252-
self.hdbc.value, # Connection handle
253-
odbc_sql_const.SQL_COMMIT.value # Commit the transaction
272+
ddbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
273+
self.hdbc.value, # Connection handle
274+
ddbc_sql_const.SQL_COMMIT.value, # Commit the transaction
254275
)
255-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
276+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
256277
if ENABLE_LOGGING:
257278
logger.info("Transaction committed successfully.")
258279

@@ -269,11 +290,11 @@ def rollback(self) -> None:
269290
"""
270291
# Roll back the current transaction
271292
ret = ddbc_bindings.DDBCSQLEndTran(
272-
odbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
273-
self.hdbc.value, # Connection handle
274-
odbc_sql_const.SQL_ROLLBACK.value # Roll back the transaction
293+
ddbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
294+
self.hdbc.value, # Connection handle
295+
ddbc_sql_const.SQL_ROLLBACK.value, # Roll back the transaction
275296
)
276-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
297+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
277298
if ENABLE_LOGGING:
278299
logger.info("Transaction rolled back successfully.")
279300

@@ -292,11 +313,13 @@ def close(self) -> None:
292313
"""
293314
# Disconnect from the database
294315
ret = ddbc_bindings.DDBCSQLDisconnect(self.hdbc.value)
295-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
296-
316+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
317+
297318
# Free the connection handle
298-
ret = ddbc_bindings.DDBCSQLFreeHandle(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value)
299-
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
300-
319+
ret = ddbc_bindings.DDBCSQLFreeHandle(
320+
ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value
321+
)
322+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
323+
301324
if ENABLE_LOGGING:
302325
logger.info("Connection closed successfully.")

mssql_python/constants.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
"""
2+
Copyright (c) Microsoft Corporation.
3+
Licensed under the MIT license.
4+
This module contains the constants used in the DDBC module.
5+
"""
6+
17
from enum import Enum
28

3-
class ConstantsODBC(Enum):
9+
10+
class ConstantsDDBC(Enum):
11+
"""
12+
Constants used in the DDBC module.
13+
"""
414
SQL_HANDLE_ENV = 1
515
SQL_HANDLE_DBC = 2
616
SQL_HANDLE_STMT = 3
@@ -13,14 +23,14 @@ class ConstantsODBC(Enum):
1323
SQL_ATTR_ASYNC_DBC_EVENT = 119
1424
SQL_IS_INTEGER = -6
1525
SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE = 117
16-
SQL_OV_ODBC3_80 = 380
17-
SQL_ATTR_ODBC_VERSION = 200
26+
SQL_OV_DDBC3_80 = 380
27+
SQL_ATTR_DDBC_VERSION = 200
1828
SQL_ATTR_ASYNC_ENABLE = 4
1929
SQL_ATTR_ASYNC_STMT_EVENT = 29
2030
SQL_ERROR = -1
2131
SQL_INVALID_HANDLE = -2
2232
SQL_NULL_HANDLE = 0
23-
SQL_OV_ODBC3 = 3
33+
SQL_OV_DDBC3 = 3
2434
SQL_COMMIT = 0
2535
SQL_ROLLBACK = 1
2636
SQL_ATTR_AUTOCOMMIT = 102

0 commit comments

Comments
 (0)