@@ -53,14 +53,12 @@ def __init__(self, connection_str: str = "", autocommit: bool = False, attrs_bef
5353 preparing it for further operations such as connecting to the
5454 database, executing queries, etc.
5555 """
56- self .henv = None
57- self .hdbc = None
5856 self .connection_str = self ._construct_connection_string (
5957 connection_str , ** kwargs
6058 )
61- self ._attrs_before = attrs_before
62- self ._autocommit = autocommit # Initialize _autocommit before calling _initializer
63- self ._initializer ( )
59+ self ._attrs_before = attrs_before or {}
60+ self ._conn = ddbc_bindings . Connection ( self . connection_str , autocommit )
61+ self ._conn . connect ( self . _attrs_before )
6462 self .setautocommit (autocommit )
6563
6664 def _construct_connection_string (self , connection_str : str = "" , ** kwargs ) -> str :
@@ -100,193 +98,15 @@ def _construct_connection_string(self, connection_str: str = "", **kwargs) -> st
10098 logger .info ("Final connection string: %s" , conn_str )
10199
102100 return conn_str
103-
104- def _is_closed (self ) -> bool :
105- """
106- Check if the connection is closed.
107-
108- Returns:
109- bool: True if the connection is closed, False otherwise.
110- """
111- return self .hdbc is None
112101
113- def _initializer (self ) -> None :
114- """
115- Initialize the environment and connection handles.
116-
117- This method is responsible for setting up the environment and connection
118- handles, allocating memory for them, and setting the necessary attributes.
119- It should be called before establishing a connection to the database.
120- """
121- self ._allocate_environment_handle ()
122- self ._set_environment_attributes ()
123- self ._allocate_connection_handle ()
124- if self ._attrs_before != {}:
125- self ._apply_attrs_before () # Apply pre-connection attributes
126- if self ._autocommit :
127- self ._set_connection_attributes (
128- ddbc_sql_const .SQL_ATTR_AUTOCOMMIT .value ,
129- ddbc_sql_const .SQL_AUTOCOMMIT_ON .value ,
130- )
131- self ._connect_to_db ()
132-
133- def _apply_attrs_before (self ):
134- """
135- Apply specific pre-connection attributes.
136- Currently, this method only processes an attribute with key 1256 (e.g., SQL_COPT_SS_ACCESS_TOKEN)
137- if present in `self._attrs_before`. Other attributes are ignored.
138-
139- Returns:
140- bool: True.
141- """
142-
143- if ENABLE_LOGGING :
144- logger .info ("Attempting to apply pre-connection attributes (attrs_before): %s" , self ._attrs_before )
145-
146- if not isinstance (self ._attrs_before , dict ):
147- if self ._attrs_before is not None and ENABLE_LOGGING :
148- logger .warning (
149- f"_attrs_before is of type { type (self ._attrs_before ).__name__ } , "
150- f"expected dict. Skipping attribute application."
151- )
152- elif self ._attrs_before is None and ENABLE_LOGGING :
153- logger .debug ("_attrs_before is None. No pre-connection attributes to apply." )
154- return True # Exit if _attrs_before is not a dictionary or is None
155-
156- for key , value in self ._attrs_before .items ():
157- ikey = None
158- if isinstance (key , int ):
159- ikey = key
160- elif isinstance (key , str ) and key .isdigit ():
161- try :
162- ikey = int (key )
163- except ValueError :
164- if ENABLE_LOGGING :
165- logger .debug (
166- f"Skipping attribute with key '{ key } ' in attrs_before: "
167- f"could not convert string to int."
168- )
169- continue # Skip if string key is not a valid integer
170- else :
171- if ENABLE_LOGGING :
172- logger .debug (
173- f"Skipping attribute with key '{ key } ' in attrs_before due to "
174- f"unsupported key type: { type (key ).__name__ } . Expected int or string representation of an int."
175- )
176- continue # Skip keys that are not int or string representation of an int
177-
178- if ikey == ddbc_sql_const .SQL_COPT_SS_ACCESS_TOKEN .value :
179- if ENABLE_LOGGING :
180- logger .info (
181- f"Found attribute { ddbc_sql_const .SQL_COPT_SS_ACCESS_TOKEN .value } . Attempting to set it."
182- )
183- self ._set_connection_attributes (ikey , value )
184- if ENABLE_LOGGING :
185- logger .info (
186- f"Call to set attribute { ddbc_sql_const .SQL_COPT_SS_ACCESS_TOKEN .value } with value '{ value } ' completed."
187- )
188- # If you expect only one such key, you could add 'break' here.
189- else :
190- if ENABLE_LOGGING :
191- logger .debug (
192- f"Ignoring attribute with key '{ key } ' (resolved to { ikey } ) in attrs_before "
193- f"as it is not the target attribute ({ ddbc_sql_const .SQL_COPT_SS_ACCESS_TOKEN .value } )."
194- )
195- return True
196-
197- def _allocate_environment_handle (self ):
198- """
199- Allocate the environment handle.
200- """
201- ret , handle = ddbc_bindings .DDBCSQLAllocHandle (
202- ddbc_sql_const .SQL_HANDLE_ENV .value , # SQL environment handle type
203- None
204- )
205- check_error (ddbc_sql_const .SQL_HANDLE_ENV .value , handle , ret )
206- self .henv = handle
207-
208- def _set_environment_attributes (self ):
209- """
210- Set the environment attributes.
211- """
212- ret = ddbc_bindings .DDBCSQLSetEnvAttr (
213- self .henv , # Use the wrapper class
214- ddbc_sql_const .SQL_ATTR_DDBC_VERSION .value , # Attribute
215- ddbc_sql_const .SQL_OV_DDBC3_80 .value , # String Length
216- 0 , # Null-terminated string
217- )
218- check_error (ddbc_sql_const .SQL_HANDLE_ENV .value , self .henv , ret )
219-
220- def _allocate_connection_handle (self ):
221- """
222- Allocate the connection handle.
223- """
224- ret , handle = ddbc_bindings .DDBCSQLAllocHandle (
225- ddbc_sql_const .SQL_HANDLE_DBC .value , # SQL connection handle type
226- self .henv
227- )
228- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , handle , ret )
229- self .hdbc = handle
230-
231- def _set_connection_attributes (self , ikey : int , ivalue : any ) -> None :
232- """
233- Set the connection attributes before connecting.
234-
235- Args:
236- ikey (int): The attribute key to set.
237- ivalue (Any): The value to set for the attribute. Can be bytes, bytearray, int, or unicode.
238- vallen (int): The length of the value.
239-
240- Raises:
241- DatabaseError: If there is an error while setting the connection attribute.
242- """
243-
244- ret = ddbc_bindings .DDBCSQLSetConnectAttr (
245- self .hdbc , # Connection handle
246- ikey , # Attribute
247- ivalue , # Value
248- )
249- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
250-
251- def _connect_to_db (self ) -> None :
252- """
253- Establish a connection to the database.
254-
255- This method is responsible for creating a connection to the specified database.
256- It does not take any arguments and does not return any value. The connection
257- details such as database name, user credentials, host, and port should be
258- configured within the class or passed during the class instantiation.
259-
260- Raises:
261- DatabaseError: If there is an error while trying to connect to the database.
262- InterfaceError: If there is an error related to the database interface.
263- """
264- if ENABLE_LOGGING :
265- logger .info ("Connecting to the database" )
266- ret = ddbc_bindings .DDBCSQLDriverConnect (
267- self .hdbc , # Connection handle (wrapper)
268- 0 , # Window handle
269- self .connection_str , # Connection string
270- )
271- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
272- if ENABLE_LOGGING :
273- logger .info ("Connection established successfully." )
274-
275102 @property
276103 def autocommit (self ) -> bool :
277104 """
278105 Return the current autocommit mode of the connection.
279106 Returns:
280107 bool: True if autocommit is enabled, False otherwise.
281108 """
282- autocommit_mode = ddbc_bindings .DDBCSQLGetConnectionAttr (
283- self .hdbc , # Connection handle (wrapper)
284- ddbc_sql_const .SQL_ATTR_AUTOCOMMIT .value , # Attribute
285- )
286- check_error (
287- ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , autocommit_mode
288- )
289- return autocommit_mode == ddbc_sql_const .SQL_AUTOCOMMIT_ON .value
109+ return self ._conn .get_autocommit ()
290110
291111 @autocommit .setter
292112 def autocommit (self , value : bool ) -> None :
@@ -296,20 +116,8 @@ def autocommit(self, value: bool) -> None:
296116 value (bool): True to enable autocommit, False to disable it.
297117 Returns:
298118 None
299- Raises:
300- DatabaseError: If there is an error while setting the autocommit mode.
301119 """
302- ret = ddbc_bindings .DDBCSQLSetConnectAttr (
303- self .hdbc , # Connection handle
304- ddbc_sql_const .SQL_ATTR_AUTOCOMMIT .value , # Attribute
305- (
306- ddbc_sql_const .SQL_AUTOCOMMIT_ON .value
307- if value
308- else ddbc_sql_const .SQL_AUTOCOMMIT_OFF .value
309- ), # Value
310- )
311- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
312- self ._autocommit = value
120+ self .setautocommit (value )
313121 if ENABLE_LOGGING :
314122 logger .info ("Autocommit mode set to %s." , value )
315123
@@ -323,7 +131,7 @@ def setautocommit(self, value: bool = True) -> None:
323131 Raises:
324132 DatabaseError: If there is an error while setting the autocommit mode.
325133 """
326- self .autocommit = value
134+ self ._conn . set_autocommit ( value )
327135
328136 def cursor (self ) -> Cursor :
329137 """
@@ -340,9 +148,6 @@ def cursor(self) -> Cursor:
340148 DatabaseError: If there is an error while creating the cursor.
341149 InterfaceError: If there is an error related to the database interface.
342150 """
343- if self ._is_closed ():
344- # Cannot create a cursor if the connection is closed
345- raise Exception ("Connection is closed. Cannot create cursor." )
346151 return Cursor (self )
347152
348153 def commit (self ) -> None :
@@ -357,17 +162,8 @@ def commit(self) -> None:
357162 Raises:
358163 DatabaseError: If there is an error while committing the transaction.
359164 """
360- if self ._is_closed ():
361- # Cannot commit if the connection is closed
362- raise Exception ("Connection is closed. Cannot commit." )
363-
364165 # Commit the current transaction
365- ret = ddbc_bindings .DDBCSQLEndTran (
366- ddbc_sql_const .SQL_HANDLE_DBC .value , # Handle type
367- self .hdbc , # Connection handle (wrapper)
368- ddbc_sql_const .SQL_COMMIT .value , # Commit the transaction
369- )
370- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
166+ self ._conn .commit ()
371167 if ENABLE_LOGGING :
372168 logger .info ("Transaction committed successfully." )
373169
@@ -382,17 +178,8 @@ def rollback(self) -> None:
382178 Raises:
383179 DatabaseError: If there is an error while rolling back the transaction.
384180 """
385- if self ._is_closed ():
386- # Cannot roll back if the connection is closed
387- raise Exception ("Connection is closed. Cannot roll back." )
388-
389181 # Roll back the current transaction
390- ret = ddbc_bindings .DDBCSQLEndTran (
391- ddbc_sql_const .SQL_HANDLE_DBC .value , # Handle type
392- self .hdbc , # Connection handle (wrapper)
393- ddbc_sql_const .SQL_ROLLBACK .value , # Roll back the transaction
394- )
395- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
182+ self ._conn .rollback ()
396183 if ENABLE_LOGGING :
397184 logger .info ("Transaction rolled back successfully." )
398185
@@ -409,16 +196,7 @@ def close(self) -> None:
409196 Raises:
410197 DatabaseError: If there is an error while closing the connection.
411198 """
412- if self ._is_closed ():
413- # Connection is already closed
414- return
415- # Disconnect from the database
416- ret = ddbc_bindings .DDBCSQLDisconnect (self .hdbc )
417- check_error (ddbc_sql_const .SQL_HANDLE_DBC .value , self .hdbc , ret )
418-
419- # Set the reference to None to trigger destructor
420- self .hdbc .free ()
421- self .hdbc = None
422-
199+ # Close the connection
200+ self ._conn .close ()
423201 if ENABLE_LOGGING :
424202 logger .info ("Connection closed successfully." )
0 commit comments