Skip to content

Commit 6d2f65b

Browse files
committed
Merged PR 5173: Feat: Cursor class Implementation Basics with Tests
#### AI description (iteration 1) #### PR Classification New feature #### PR Summary This pull request implements the basic functionality of the `Cursor` class along with associated tests. - `mssql_python/cursor.py`: Implemented various data retrieval functions, execute methods, and cursor initialization. - `mssql_python/connection.py`: Removed the `_get_data` method. - Added `build-pyd-pipeline.yml` to automate the build and push of the `ddbc_bindings.pyd` file. Related work items: #32921
1 parent 2fcbcc6 commit 6d2f65b

12 files changed

Lines changed: 1320 additions & 120 deletions

build-pyd-pipeline.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
trigger:
2+
branches:
3+
include:
4+
- pybind11_win_test
5+
paths:
6+
include:
7+
- mssql_python/pybind/ddbc_bindings.cpp
8+
- mssql_python/pybind/CMakeLists.txt
9+
10+
jobs:
11+
- job: BuildOnWindows
12+
pool:
13+
vmImage: 'windows-2019'
14+
steps:
15+
- task: UsePythonVersion@0
16+
inputs:
17+
versionSpec: '3.x'
18+
addToPath: true
19+
- script: |
20+
pip install pybind11
21+
displayName: 'Install pybind11'
22+
- script: |
23+
cd mssql_python\pybind
24+
mkdir build
25+
cd build
26+
cmake -DPython3_EXECUTABLE="python3" -DCMAKE_BUILD_TYPE=Debug ..
27+
cmake --build . --config Debug
28+
move /Y Debug\ddbc_bindings.pyd ..\..\ddbc_bindings.pyd
29+
displayName: 'Build and move .pyd file'
30+
- script: |
31+
git config --global user.name "$(Build.RequestedFor)"
32+
git config --global user.email "$(Build.RequestedForEmail)"
33+
git config --global credential.helper store
34+
echo "https://$(System.AccessToken):@dev.azure.com" > ~/.git-credentials
35+
git checkout pybind11_win_test
36+
git add mssql_python/ddbc_bindings.pyd
37+
git commit -m "Add generated ddbc_bindings.pyd"
38+
git push https://$(System.AccessToken)@dev.azure.com/sqlclientdrivers/mssql-python/_git/mssql-python HEAD:pybind11_win_test
39+
displayName: 'Commit and push .pyd file'
40+
env:
41+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

main.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,18 @@
44
conn_str = os.getenv("DB_CONNECTION_STRING")
55
conn = connect(conn_str)
66

7+
cursor = conn.cursor()
8+
cursor.execute("SELECT database_id, name from sys.databases;")
9+
row = cursor.fetchmany(1)
10+
print(row)
11+
12+
cursor.execute("SELECT database_id, name from sys.databases;")
13+
row = cursor.fetchone()
14+
print(row)
15+
16+
cursor.execute("SELECT database_id, name from sys.databases;")
17+
row = cursor.fetchall()
18+
print(row)
19+
20+
cursor.close()
721
conn.close()

mssql_python/connection.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import ctypes
22
from mssql_python.cursor import Cursor
3-
from mssql_python.logging_config import setup_logging
3+
from mssql_python.logging_config import setup_logging, ENABLE_LOGGING
44
from mssql_python.constants import ConstantsODBC as odbc_sql_const
55
from mssql_python.helpers import add_driver_to_connection_str, check_error
66
import logging
@@ -115,17 +115,20 @@ def _connect_to_db(self) -> None:
115115
DatabaseError: If there is an error while trying to connect to the database.
116116
InterfaceError: If there is an error related to the database interface.
117117
"""
118-
logging.info("Connecting to the database")
118+
if ENABLE_LOGGING:
119+
logging.info("Connecting to the database")
119120
try:
120121
ret = ddbc_bindings.DDBCSQLDriverConnect(
121122
self.hdbc.value, # Connection handle
122123
0, # Window handle
123124
self.connection_str # Connection string
124125
)
125126
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
126-
logging.info("Connection established successfully.")
127+
if ENABLE_LOGGING:
128+
logging.info("Connection established successfully.")
127129
except Exception as e:
128-
logging.error("An error occurred while connecting to the database: %s", e)
130+
if ENABLE_LOGGING:
131+
logging.error("An error occurred while connecting to the database: %s", e)
129132
raise
130133

131134
@property
@@ -165,9 +168,11 @@ def setautocommit(self, value: bool) -> None:
165168
)
166169
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
167170
self._autocommit = value
168-
logging.info("Autocommit mode set to %s.", value)
171+
if ENABLE_LOGGING:
172+
logging.info("Autocommit mode set to %s.", value)
169173
except Exception as e:
170-
logging.error("An error occurred while setting autocommit mode: %s", e)
174+
if ENABLE_LOGGING:
175+
logging.error("An error occurred while setting autocommit mode: %s", e)
171176
raise Exception("DatabaseError: Failed to set autocommit mode") from e
172177

173178

@@ -212,9 +217,11 @@ def commit(self) -> None:
212217
odbc_sql_const.SQL_COMMIT.value # Commit the transaction
213218
)
214219
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
215-
logging.info("Transaction committed successfully.")
220+
if ENABLE_LOGGING:
221+
logging.info("Transaction committed successfully.")
216222
except Exception as e:
217-
logging.error("An error occurred while committing the transaction: %s", e)
223+
if ENABLE_LOGGING:
224+
logging.error("An error occurred while committing the transaction: %s", e)
218225
raise Exception("DatabaseError: Failed to commit the transaction") from e
219226

220227
def rollback(self) -> None:
@@ -236,9 +243,11 @@ def rollback(self) -> None:
236243
odbc_sql_const.SQL_ROLLBACK.value # Roll back the transaction
237244
)
238245
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
239-
logging.info("Transaction rolled back successfully.")
246+
if ENABLE_LOGGING:
247+
logging.info("Transaction rolled back successfully.")
240248
except Exception as e:
241-
logging.error("An error occurred while rolling back the transaction: %s", e)
249+
if ENABLE_LOGGING:
250+
logging.error("An error occurred while rolling back the transaction: %s", e)
242251
raise Exception("DatabaseError: Failed to roll back the transaction") from e
243252

244253
def close(self) -> None:
@@ -263,8 +272,9 @@ def close(self) -> None:
263272
ret = ddbc_bindings.DDBCSQLFreeHandle(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value)
264273
check_error(odbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
265274

266-
267-
logging.info("Connection closed successfully.")
275+
if ENABLE_LOGGING:
276+
logging.info("Connection closed successfully.")
268277
except Exception as e:
269-
logging.error("An error occurred while closing the connection: %s", e)
278+
if ENABLE_LOGGING:
279+
logging.error("An error occurred while closing the connection: %s", e)
270280
raise Exception("DatabaseError: Failed to close the connection") from e

mssql_python/constants.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,90 @@ class ConstantsODBC(Enum):
1717
SQL_ATTR_ODBC_VERSION = 200
1818
SQL_ATTR_ASYNC_ENABLE = 4
1919
SQL_ATTR_ASYNC_STMT_EVENT = 29
20+
SQL_ATTR_AUTOCOMMIT = 102
2021
SQL_ERROR = -1
2122
SQL_INVALID_HANDLE = -2
2223
SQL_NULL_HANDLE = 0
2324
SQL_OV_ODBC3 = 3
2425
SQL_COMMIT = 0
2526
SQL_ROLLBACK = 1
26-
SQL_ATTR_AUTOCOMMIT = 102
27+
SQL_SMALLINT = 5
28+
SQL_CHAR = 1
29+
SQL_WCHAR = -8
30+
SQL_WVARCHAR = -9
31+
SQL_BIT = -7
32+
SQL_TINYINT = -6
33+
SQL_BIGINT = -5
34+
SQL_BINARY = -2
35+
SQL_VARBINARY = -3
36+
SQL_LONGVARBINARY = -4
37+
SQL_LONGVARCHAR = -1
38+
SQL_UNKNOWN_TYPE = 0
39+
SQL_NUMERIC = 2
40+
SQL_DECIMAL = 3
41+
SQL_INTEGER = 4
42+
SQL_FLOAT = 6
43+
SQL_REAL = 7
44+
SQL_DOUBLE = 8
45+
SQL_DATETIME = 9
46+
SQL_INTERVAL = 10
47+
SQL_TIMESTAMP = 11
48+
SQL_DATE = 9
49+
SQL_TIME = 10
50+
SQL_VARCHAR = 12
51+
SQL_TYPE_DATE = 91
52+
SQL_TYPE_TIME = 92
53+
SQL_TYPE_TIMESTAMP = 93
54+
SQL_TYPE_TIMESTAMP_WITH_TIMEZONE = 95
55+
SQL_GUID = -11
56+
SQL_XML = 241
57+
SQL_SMALLDATETIME = 58
58+
SQL_TIMESTAMPOFFSET = 43
59+
SQL_DATETIME2 = 42
60+
SQL_SMALLMONEY = 122
61+
SQL_MONEY = 60
62+
SQL_WLONGVARCHAR = -10
63+
SQL_C_BIT = -7
64+
SQL_C_TINYINT = -6
65+
SQL_C_SBIGINT = -25
66+
SQL_C_BINARY = -2
2767
SQL_AUTOCOMMIT_ON = 1
2868
SQL_AUTOCOMMIT_OFF = 0
69+
SQL_C_VARBINARY = -3
70+
SQL_C_LONGVARBINARY = -4
71+
SQL_C_LONGVARCHAR = -1
72+
SQL_C_CHAR = -8
73+
SQL_C_NUMERIC = 2
74+
SQL_C_DECIMAL = 3
75+
SQL_C_LONG = 4
76+
SQL_C_SHORT = 5
77+
SQL_C_FLOAT = 7
78+
SQL_C_DOUBLE = 8
79+
SQL_C_TYPE_DATE = 91
80+
SQL_C_TYPE_TIME = 92
81+
SQL_C_TYPE_TIMESTAMP = 93
82+
SQL_C_TYPE_TIMESTAMP_WITH_TIMEZONE = 95
83+
SQL_C_GUID = -11
84+
SQL_DESC_TYPE = 2
85+
SQL_DESC_LENGTH = 3
86+
SQL_DESC_NAME = 4
87+
SQL_ATTR_ROW_ARRAY_SIZE = 27
88+
SQL_ATTR_ROWS_FETCHED_PTR = 26
89+
SQL_ATTR_ROW_STATUS_PTR = 25
90+
SQL_FETCH_NEXT = 1
91+
SQL_ROW_SUCCESS = 0
92+
SQL_ROW_SUCCESS_WITH_INFO = 1
93+
SQL_ROW_NOROW = 100
94+
SQL_ATTR_CURSOR_TYPE = 6
95+
SQL_CURSOR_FORWARD_ONLY = 0
96+
SQL_CURSOR_STATIC = 3
97+
SQL_CURSOR_KEYSET_DRIVEN = 2
98+
SQL_CURSOR_DYNAMIC = 3
99+
SQL_NULL_DATA = -1
100+
SQL_C_DEFAULT = 99
101+
SQL_ATTR_ROW_BIND_TYPE = 5
102+
SQL_BIND_BY_COLUMN = 0
103+
SQL_PARAM_INPUT = 1
104+
SQL_PARAM_OUTPUT = 2
105+
SQL_PARAM_INPUT_OUTPUT = 3
106+
SQL_C_WCHAR = -8

0 commit comments

Comments
 (0)