Skip to content

Commit fc8f1f1

Browse files
committed
restored other files
1 parent 2791481 commit fc8f1f1

6 files changed

Lines changed: 92 additions & 96 deletions

File tree

eng/pipelines/test-pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@ jobs:
6565
- task: PublishCodeCoverageResults@1
6666
inputs:
6767
codeCoverageTool: 'Cobertura'
68-
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
68+
summaryFileLocation: 'coverage.xml'
6969
displayName: 'Publish code coverage results'

main.py

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,10 @@
1212

1313
cursor = conn.cursor()
1414
cursor.execute("SELECT database_id, name from sys.databases;")
15-
row = cursor.fetchmany(1)
16-
print(row)
15+
rows = cursor.fetchall()
1716

18-
cursor.execute("DROP TABLE IF EXISTS main_single_column")
19-
20-
# cursor.execute("CREATE TABLE main_single_column (float_column FLOAT)")
21-
# cursor.executemany("INSERT INTO main_single_column (float_column) VALUES (?)", [[12.34], [1.234], [0.125], [0.0125], [0.00125], [23243243232.432432432], [0.247985732852735032750973209750]])
22-
# cursor.execute("SELECT * FROM main_single_column")
23-
# row = cursor.fetchall()
24-
# print(row)
25-
# print(len(row))
26-
27-
import time
28-
cursor.execute("CREATE TABLE main_single_column (decimal_column NUMERIC(10, 4))")
29-
# time.sleep(45)
30-
31-
cursor.execute("INSERT INTO main_single_column (decimal_column) VALUES (?)", [decimal.Decimal(123.45).quantize(decimal.Decimal('0.00'))])
32-
cursor.execute("SELECT * FROM main_single_column")
33-
row = cursor.fetchone()[0]
34-
35-
print(row)
36-
print(row.val)
37-
print(row.precision)
38-
print(row.scale)
39-
print(row.sign)
17+
for row in rows:
18+
print(f"Database ID: {row[0]}, Name: {row[1]}")
4019

4120
cursor.close()
4221
conn.close()

mssql_python/connection.py

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ def __init__(self, connection_str: str, autocommit: bool = False, **kwargs) -> N
5353
preparing it for further operations such as connecting to the
5454
database, executing queries, etc.
5555
"""
56-
self.henv = ctypes.c_void_p()
57-
self.hdbc = ctypes.c_void_p()
56+
self.henv = None
57+
self.hdbc = None
5858
self.connection_str = self._construct_connection_string(
5959
connection_str, **kwargs
6060
)
@@ -95,6 +95,15 @@ def _construct_connection_string(self, connection_str: str, **kwargs) -> str:
9595
conn_str += f"{key}={value};"
9696
return conn_str
9797

98+
def _is_closed(self) -> bool:
99+
"""
100+
Check if the connection is closed.
101+
102+
Returns:
103+
bool: True if the connection is closed, False otherwise.
104+
"""
105+
return self.hdbc is None
106+
98107
def _initializer(self) -> None:
99108
"""
100109
Initialize the environment and connection handles.
@@ -113,52 +122,48 @@ def _allocate_environment_handle(self):
113122
"""
114123
Allocate the environment handle.
115124
"""
116-
ret = ddbc_bindings.DDBCSQLAllocHandle(
125+
ret, handle = ddbc_bindings.DDBCSQLAllocHandle(
117126
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
127+
None
122128
)
123-
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
129+
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, handle, ret)
130+
self.henv = handle
124131

125132
def _set_environment_attributes(self):
126133
"""
127134
Set the environment attributes.
128135
"""
129136
ret = ddbc_bindings.DDBCSQLSetEnvAttr(
130-
self.henv.value, # Environment handle
137+
self.henv, # Use the wrapper class
131138
ddbc_sql_const.SQL_ATTR_DDBC_VERSION.value, # Attribute
132139
ddbc_sql_const.SQL_OV_DDBC3_80.value, # String Length
133140
0, # Null-terminated string
134141
)
135-
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, self.henv.value, ret)
142+
check_error(ddbc_sql_const.SQL_HANDLE_ENV.value, self.henv, ret)
136143

137144
def _allocate_connection_handle(self):
138145
"""
139146
Allocate the connection handle.
140147
"""
141-
ret = ddbc_bindings.DDBCSQLAllocHandle(
148+
ret, handle = ddbc_bindings.DDBCSQLAllocHandle(
142149
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
150+
self.henv
147151
)
148-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
152+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, handle, ret)
153+
self.hdbc = handle
149154

150155
def _set_connection_attributes(self):
151156
"""
152157
Set the connection attributes before connecting.
153158
"""
154159
if self.autocommit:
155160
ret = ddbc_bindings.DDBCSQLSetConnectAttr(
156-
self.hdbc.value,
161+
self.hdbc, # Using the wrapper class
157162
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value,
158163
ddbc_sql_const.SQL_AUTOCOMMIT_ON.value,
159-
0,
164+
0
160165
)
161-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
166+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
162167

163168
def _connect_to_db(self) -> None:
164169
"""
@@ -176,11 +181,11 @@ def _connect_to_db(self) -> None:
176181
if ENABLE_LOGGING:
177182
logger.info("Connecting to the database")
178183
ret = ddbc_bindings.DDBCSQLDriverConnect(
179-
self.hdbc.value, # Connection handle
184+
self.hdbc, # Connection handle (wrapper)
180185
0, # Window handle
181186
self.connection_str, # Connection string
182187
)
183-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
188+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
184189
if ENABLE_LOGGING:
185190
logger.info("Connection established successfully.")
186191

@@ -192,11 +197,11 @@ def autocommit(self) -> bool:
192197
bool: True if autocommit is enabled, False otherwise.
193198
"""
194199
autocommit_mode = ddbc_bindings.DDBCSQLGetConnectionAttr(
195-
self.hdbc.value, # Connection handle
200+
self.hdbc, # Connection handle (wrapper)
196201
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
197202
)
198203
check_error(
199-
ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, autocommit_mode
204+
ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, autocommit_mode
200205
)
201206
return autocommit_mode == ddbc_sql_const.SQL_AUTOCOMMIT_ON.value
202207

@@ -212,7 +217,7 @@ def autocommit(self, value: bool) -> None:
212217
DatabaseError: If there is an error while setting the autocommit mode.
213218
"""
214219
ret = ddbc_bindings.DDBCSQLSetConnectAttr(
215-
self.hdbc.value, # Connection handle
220+
self.hdbc, # Connection handle
216221
ddbc_sql_const.SQL_ATTR_AUTOCOMMIT.value, # Attribute
217222
(
218223
ddbc_sql_const.SQL_AUTOCOMMIT_ON.value
@@ -221,7 +226,7 @@ def autocommit(self, value: bool) -> None:
221226
), # Value
222227
0, # String length
223228
)
224-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
229+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
225230
self._autocommit = value
226231
if ENABLE_LOGGING:
227232
logger.info("Autocommit mode set to %s.", value)
@@ -253,6 +258,9 @@ def cursor(self) -> Cursor:
253258
DatabaseError: If there is an error while creating the cursor.
254259
InterfaceError: If there is an error related to the database interface.
255260
"""
261+
if self._is_closed():
262+
# Cannot create a cursor if the connection is closed
263+
raise Exception("Connection is closed. Cannot create cursor.")
256264
return Cursor(self)
257265

258266
def commit(self) -> None:
@@ -267,13 +275,17 @@ def commit(self) -> None:
267275
Raises:
268276
DatabaseError: If there is an error while committing the transaction.
269277
"""
278+
if self._is_closed():
279+
# Cannot commit if the connection is closed
280+
raise Exception("Connection is closed. Cannot commit.")
281+
270282
# Commit the current transaction
271283
ret = ddbc_bindings.DDBCSQLEndTran(
272284
ddbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
273-
self.hdbc.value, # Connection handle
285+
self.hdbc, # Connection handle (wrapper)
274286
ddbc_sql_const.SQL_COMMIT.value, # Commit the transaction
275287
)
276-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
288+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
277289
if ENABLE_LOGGING:
278290
logger.info("Transaction committed successfully.")
279291

@@ -288,13 +300,17 @@ def rollback(self) -> None:
288300
Raises:
289301
DatabaseError: If there is an error while rolling back the transaction.
290302
"""
303+
if self._is_closed():
304+
# Cannot roll back if the connection is closed
305+
raise Exception("Connection is closed. Cannot roll back.")
306+
291307
# Roll back the current transaction
292308
ret = ddbc_bindings.DDBCSQLEndTran(
293309
ddbc_sql_const.SQL_HANDLE_DBC.value, # Handle type
294-
self.hdbc.value, # Connection handle
310+
self.hdbc, # Connection handle (wrapper)
295311
ddbc_sql_const.SQL_ROLLBACK.value, # Roll back the transaction
296312
)
297-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
313+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
298314
if ENABLE_LOGGING:
299315
logger.info("Transaction rolled back successfully.")
300316

@@ -311,15 +327,16 @@ def close(self) -> None:
311327
Raises:
312328
DatabaseError: If there is an error while closing the connection.
313329
"""
330+
if self._is_closed():
331+
# Connection is already closed
332+
return
314333
# Disconnect from the database
315-
ret = ddbc_bindings.DDBCSQLDisconnect(self.hdbc.value)
316-
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc.value, ret)
334+
ret = ddbc_bindings.DDBCSQLDisconnect(self.hdbc)
335+
check_error(ddbc_sql_const.SQL_HANDLE_DBC.value, self.hdbc, ret)
317336

318-
# Free the connection handle
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)
337+
# Set the reference to None to trigger destructor
338+
self.hdbc.free()
339+
self.hdbc = None
323340

324341
if ENABLE_LOGGING:
325342
logger.info("Connection closed successfully.")

0 commit comments

Comments
 (0)