@@ -409,6 +409,62 @@ def _create_parameter_types_list(self, parameter, ParamInfo, parameters_list, i)
409409 paraminfo .decimalDigits = decimal_digits
410410 return paraminfo
411411
412+ def _initialize_description (self ):
413+ """
414+ Initialize the description attribute using SQLDescribeCol.
415+ """
416+ col_metadata = []
417+ ret = ddbc_bindings .DDBCSQLDescribeCol (self .hstmt .value , col_metadata )
418+ check_error (odbc_sql_const .SQL_HANDLE_STMT .value , self .hstmt .value , ret )
419+
420+ self .description = [
421+ (
422+ col ["ColumnName" ],
423+ self ._map_data_type (col ["DataType" ]),
424+ None ,
425+ col ["ColumnSize" ],
426+ col ["ColumnSize" ],
427+ col ["DecimalDigits" ],
428+ col ["Nullable" ] == odbc_sql_const .SQL_NULLABLE .value ,
429+ )
430+ for col in col_metadata
431+ ]
432+
433+ def _map_data_type (self , sql_type ):
434+ """
435+ Map SQL data type to Python data type.
436+
437+ Args:
438+ sql_type: SQL data type.
439+
440+ Returns:
441+ Corresponding Python data type.
442+ """
443+ sql_to_python_type = {
444+ odbc_sql_const .SQL_INTEGER .value : int ,
445+ odbc_sql_const .SQL_VARCHAR .value : str ,
446+ odbc_sql_const .SQL_WVARCHAR .value : str ,
447+ odbc_sql_const .SQL_CHAR .value : str ,
448+ odbc_sql_const .SQL_WCHAR .value : str ,
449+ odbc_sql_const .SQL_FLOAT .value : float ,
450+ odbc_sql_const .SQL_DOUBLE .value : float ,
451+ odbc_sql_const .SQL_DECIMAL .value : decimal .Decimal ,
452+ odbc_sql_const .SQL_NUMERIC .value : decimal .Decimal ,
453+ odbc_sql_const .SQL_DATE .value : datetime .date ,
454+ odbc_sql_const .SQL_TIMESTAMP .value : datetime .datetime ,
455+ odbc_sql_const .SQL_TIME .value : datetime .time ,
456+ odbc_sql_const .SQL_BIT .value : bool ,
457+ odbc_sql_const .SQL_TINYINT .value : int ,
458+ odbc_sql_const .SQL_SMALLINT .value : int ,
459+ odbc_sql_const .SQL_BIGINT .value : int ,
460+ odbc_sql_const .SQL_BINARY .value : bytes ,
461+ odbc_sql_const .SQL_VARBINARY .value : bytes ,
462+ odbc_sql_const .SQL_LONGVARBINARY .value : bytes ,
463+ odbc_sql_const .SQL_GUID .value : uuid .UUID ,
464+ # Add more mappings as needed
465+ }
466+ return sql_to_python_type .get (sql_type , str )
467+
412468 def execute (self , operation : str , * parameters , use_prepare : bool = True , reset_cursor : bool = True ):
413469 """
414470 Prepare and execute a database operation (query or command).
@@ -452,6 +508,12 @@ def execute(self, operation: str, *parameters, use_prepare: bool = True, reset_c
452508 self .is_stmt_prepared , use_prepare )
453509 check_error (odbc_sql_const .SQL_HANDLE_STMT .value , self .hstmt .value , ret )
454510 self .last_executed_stmt = operation
511+
512+ # Update rowcount after execution
513+ self .rowcount = ddbc_bindings .DDBCSQLRowCount (self .hstmt .value )
514+
515+ # Initialize description after execution
516+ self ._initialize_description ()
455517 except Exception as e :
456518 if ENABLE_LOGGING :
457519 logging .error ("An error occurred while executing query: %s" , e )
@@ -475,6 +537,7 @@ def executemany(self, operation: str, seq_of_parameters: list) -> None:
475537 self ._reset_cursor ()
476538
477539 first_execution = True
540+ total_rowcount = 0
478541 for parameters in seq_of_parameters :
479542 # Execute the operation with the current set of parameters without
480543 # Converting the parameters to a list
@@ -491,6 +554,13 @@ def executemany(self, operation: str, seq_of_parameters: list) -> None:
491554 prepare_stmt = False
492555 # Execute statement with one parameter set
493556 self .execute (operation , parameters , use_prepare = prepare_stmt , reset_cursor = False )
557+ if self .rowcount != - 1 :
558+ # Rowcount would get updated inside execute method, add it to the current rowcount
559+ total_rowcount += self .rowcount
560+ else :
561+ total_rowcount = - 1
562+ # Update the rowcount after all executions
563+ self .rowcount = total_rowcount
494564 except Exception as e :
495565 if ENABLE_LOGGING :
496566 logging .error ("An error occurred while executing multiple queries: %s" , e )
0 commit comments