diff --git a/src/DatabaseLibrary/query.py b/src/DatabaseLibrary/query.py index 88ea88b..15befeb 100644 --- a/src/DatabaseLibrary/query.py +++ b/src/DatabaseLibrary/query.py @@ -83,10 +83,11 @@ def query( try: cur = db_connection.client.cursor() logger.info(f"Executing : Query | {selectStatement} ") - self.__execute_sql(cur, selectStatement, parameters=parameters) + self._execute_sql(cur, selectStatement, parameters=parameters) all_rows = cur.fetchall() + col_names = [c[0] for c in cur.description] + self._log_query_result(col_names, all_rows) if returnAsDict: - col_names = [c[0] for c in cur.description] return [dict(zip(col_names, row)) for row in all_rows] return all_rows finally: @@ -123,13 +124,15 @@ def row_count( try: cur = db_connection.client.cursor() logger.info(f"Executing : Row Count | {selectStatement}") - self.__execute_sql(cur, selectStatement, parameters=parameters) + self._execute_sql(cur, selectStatement, parameters=parameters) data = cur.fetchall() + col_names = [c[0] for c in cur.description] if db_connection.module_name in ["sqlite3", "ibm_db", "ibm_db_dbi", "pyodbc"]: current_row_count = len(data) else: current_row_count = cur.rowcount logger.info(f"Retrieved {current_row_count} rows") + self._log_query_result(col_names, data) return current_row_count finally: if cur and not sansTran: @@ -175,7 +178,7 @@ def description( try: cur = db_connection.client.cursor() logger.info("Executing : Description | {selectStatement}") - self.__execute_sql(cur, selectStatement, parameters=parameters) + self._execute_sql(cur, selectStatement, parameters=parameters) description = list(cur.description) if sys.version_info[0] < 3: for row in range(0, len(description)): @@ -205,7 +208,7 @@ def delete_all_rows_from_table(self, tableName: str, sansTran: bool = False, ali try: cur = db_connection.client.cursor() logger.info(f"Executing : Delete All Rows From Table | {query}") - result = self.__execute_sql(cur, query) + result = self._execute_sql(cur, query) if result is not None: if not sansTran: db_connection.client.commit() @@ -289,7 +292,7 @@ def execute_sql_script( logger.info(f"Executing : Execute SQL Script | {sqlScriptFileName}") if not split: logger.info("Statements splitting disabled - pass entire script content to the database module") - self.__execute_sql(cur, sql_file.read()) + self._execute_sql(cur, sql_file.read()) else: logger.info("Splitting script file into statements...") statements_to_execute = [] @@ -355,7 +358,7 @@ def execute_sql_script( logger.info(f"Executing statement from script file: {statement}") line_ends_with_proc_end = re.compile(r"(\s|;)" + proc_end_pattern.pattern + "$") omit_semicolon = not line_ends_with_proc_end.search(statement.lower()) - self.__execute_sql(cur, statement, omit_semicolon) + self._execute_sql(cur, statement, omit_semicolon) if not sansTran: db_connection.client.commit() finally: @@ -400,7 +403,7 @@ def execute_sql_string( try: cur = db_connection.client.cursor() logger.info(f"Executing : Execute SQL String | {sqlString}") - self.__execute_sql(cur, sqlString, omit_trailing_semicolon=omitTrailingSemicolon, parameters=parameters) + self._execute_sql(cur, sqlString, omit_trailing_semicolon=omitTrailingSemicolon, parameters=parameters) if not sansTran: db_connection.client.commit() finally: @@ -549,7 +552,7 @@ def call_stored_procedure( if cur and not sansTran: db_connection.client.rollback() - def __execute_sql( + def _execute_sql( self, cur, sql_statement: str, @@ -573,3 +576,41 @@ def __execute_sql( else: logger.debug(f"Executing sql '{sql_statement}' with parameters: {parameters}") return cur.execute(sql_statement, parameters) + + def _log_query_result(self, col_names, result_rows, log_head=50): + """ + Logs the `result_rows` of a query in RF log as a HTML table. + The `col_names` are needed for the table header. + Max. `log_head` rows are logged (`0` disables the limit). + """ + cell_border_and_align = "border: 1px solid rgb(160 160 160);padding: 8px 10px;text-align: center;" + table_border = "2px solid rgb(140 140 140)" + row_index_color = "#d6ecd4" + msg = f'
' + msg += f'' + msg += f'' + msg += "" + msg += f'' + for col in col_names: + msg += f'' + msg += "" + table_truncated = False + for i, row in enumerate(result_rows): + if log_head and i >= log_head: + table_truncated = True + break + row_style = "" + if i % 2 == 0: + row_style = ' style="background-color: #eee;"' + msg += f"" + msg += f'' + for cell in row: + msg += f'' + msg += "" + msg += "
Query returned {len(result_rows)} rows
Row{col}
{i}{cell}
" + if table_truncated: + msg += ( + f'

Log limit of {log_head} rows was reached, the table was truncated

' + ) + msg += "
" + logger.info(msg, html=True) diff --git a/test/tests/common_tests/assertion_retry.robot b/test/tests/common_tests/assertion_retry.robot index 3fefc3f..47921da 100644 --- a/test/tests/common_tests/assertion_retry.robot +++ b/test/tests/common_tests/assertion_retry.robot @@ -13,8 +13,6 @@ ${Tolerance} ${0.5} ${Request} SELECT first_name FROM person *** Test Cases *** - - Check Query Results With Timeout - Fast If DB Ready Check Query Result ${Request} contains Allan retry_timeout=${Timeout} seconds ${End time}= Get Current Date