# # # # overview_query_util.cfv # # # set_overview_totals_in_query_info_header() # get_overview_query_result() - DISABLED # # # # include "templates.statistics.util.get_table_exists"; # include "templates.statistics.util.expression_handling"; # # # # # set_overview_totals_in_query_info_header() # # # # subroutine(set_overview_totals_in_query_info_header( string profile_name, node overview_query_info, string database_last_modification_time, string filter_expression, int number_of_days, node collected_whitelist_objects), ( debug_message("\n\n#### set_overview_totals_in_query_info_header() \n"); debug_message("#### overview_query_info:\n" . node_as_string(overview_query_info) . "\n"); # This sets the overview total values in overview_query_info.header. # overview_query_info.header is accessable in the callee, so it doesn't return # anything. If no cached ssql table exists then a new query is performed. # overview_query_info is already complete so that it can be used in # query_db_for_report(). # # overview_info.header is a header generated from query_fields. # The subnodes must not contain any show_column, show_percent_column or # show_bar_column node because the header is used to generate the # overview_root_table_id. # Each column node name of header should be the report field name! node query_header = overview_query_info{"header"}; # # Check if the overview ssql table exists # string s = 'OVERVIEW_' . node_as_string(overview_query_info) . database_last_modification_time . filter_expression; string overview_root_table_id = 'rep_' . md5_digest(s); debug_message("#### overview_root_table_id: " . overview_root_table_id . "\n"); bool overview_root_table_exists = get_table_exists(profile_name, overview_root_table_id, collected_whitelist_objects); if (!overview_root_table_exists) then ( # Set filters volatile.filters = if (filter_expression ne "") then (filter_expression) else ("nofilters"); delete_node("v.query_result"); v.query_result = ""; debug_message("#### query_db_for_report() START \n"); query_db_for_report(overview_query_info, "v.query_result", overview_root_table_id); debug_message("#### query_db_for_report() DONE \n"); # # Check if we need to handle report field expressions # # KHP 30/Jan/2012 - report field expressions are now evaluated in the C++ # bool is_report_field_expression = @overview_query_info{"is_report_field_expression"}; # # debug_message("#### is_report_field_expression: " .is_report_field_expression . "\n"); # # if (is_report_field_expression) then ( # # # # # Update the ssql table # # # # bool use_overview_for_totals = false; # bool is_table_filter_expression = false; # bool is_handle_progress = false; # # # Get a pseudo progress_substeps info because we don't handle progress in export_report_element # node progress_substep_info = get_report_progress_substep_info(1000); # # int total_rows = expression_handling_update_ssql_table( # profile_name, # query_header, # overview_root_table_id, # use_overview_for_totals, # is_report_field_expression, # is_table_filter_expression, # number_of_days, # is_handle_progress, # progress_substep_info # ); # ); ); # # Set the total values # table root_table = load_table(overview_root_table_id); int total_rows = table_get_num_rows(root_table); debug_message("#### total_rows: " . total_rows . "\n"); node column; int ssql_column_number = 0; foreach column query_header ( # Make sure the table has rows. It is possible that the database contains no data, # in this case it should show 0 and not throw any error. if (total_rows > 0) then ( if (@column{"is_aggregating_field"}) then ( @column{"total_value"} = table_get_cell_value(root_table, 0, ssql_column_number); ) else ( # In case there is a string field @column{"total_value"} = table_get_cell_string_value(root_table, 0, ssql_column_number); ); ) else ( # No data in database table, set value to 0 @column{"total_value"} = 0; ); ssql_column_number++; ); unload_table(root_table); debug_message("#### set_overview_totals_in_query_info_header - overview_query_info final:\n" . node_as_string(overview_query_info) . "\n"); )); # # # # get_overview_query_result() # # # # #subroutine(get_overview_query_result( # string session_id, # string profile_name, # string database_last_modification_time, # string filter_expression), ( # # # Returns a cached or new overview query result # # The query result is used for the Overview Report and to receive the totals in standard table reporting code. # # debug_message("\n\n#### get_overview_query_result() START \n\n"); # # # debug_message("#### get_overview_query_result() - filter_expression: " . filter_expression . "\n"); # # # # # # # Get overview query Id # # # # # # # node extended_profile_dat = get_extended_profile_dat_node_reference(session_id, profile_name); # node cached_overview_query_info = extended_profile_dat{"overview_query_info"}; # string query_header_checksum = @cached_overview_query_info{"header_checksum"}; # # string query_id = "overview_" . md5_digest(database_last_modification_time . filter_expression . query_header_checksum); # # # # # # # Use cached overview query_result, else perform a new query # # # # # # string profiles_cache_path = "profiles_cache." . profile_name; # # string saved_query_result_path = profiles_cache_path . ".queries." . query_id; # # node query_result; # node saved_query_result; # # node item; # string item_name; # string item_type; # # if (!?(saved_query_result_path)) then ( # # # # # # # No cached overview query exists, perform query now # # # # # # volatile.filters = if (filter_expression ne "") then (filter_expression) else ("nofilters"); # # # debug_message("#### get_overview_query_result() - filter expression:\n" . volatile.filters . "\n\n"); # # delete_node("v.query_info"); # v.query_info = ""; # # v.query_info.report_element_type = "overview"; # v.query_info.header = ""; # # delete_node("v.query_result"); # v.query_result = ""; # query_result = "v.query_result"; # # node overview_query_header = cached_overview_query_info{"header"}; # clone_node(overview_query_header, "v.query_info.header"); # # # debug_message("#### query_info of overview report:\n" . node_as_string("v.query_info") . "\n"); # # debug_message("#### get_overview_query_result() - query_db_for_report() START \n"); # # query_db_for_report("v.query_info", query_result, "tbl"); # # debug_message("#### get_overview_query_result() - query_db_for_report() DONE \n"); # # # # # # Handle average denominator field, if any # # # # # We don't do that here because the average denominator is handled by a report field # # which is based on a database field with an expression, and expression evaluation # # is handled in the query header if the overview report is part of a table report. # # For overview reports we handle the average_denominator_field in the raw overview # # code. # # # # # # Save query result to cache, also save the node type so that we can restore the types, # # else we may get wrong results when dividing float by string. # # # # foreach item query_result ( # # item_name = node_name(item); # item_type = node_type(item); # # saved_query_result_path . "." . item_name . ".item_type" = item_type; # saved_query_result_path . "." . item_name . ".item_value" = @item; # ); # # save_node(saved_query_result_path); # # debug_message("#### get_overview_query_result() - NO CHACHED OVERVIEW QUERY RESULT --> EXECUTED query_db_for_report() \n"); # ) # else ( # # # Create a query_result from saved_query_result, with original node types! # # saved_query_result = saved_query_result_path; # query_result = new_node(); # # debug_message("#### get_overview_query_result() - GOT OVERVIEW QUERY RESULT FROM CACHE \n"); # # foreach item saved_query_result ( # # item_name = node_name(item); # item_type = @item{"item_type"}; # # # Create new query_result node # query_result{item_name} = ""; # # # Set node type # set_node_type(query_result{item_name}, item_type); # # # Set actual value # query_result{item_name} = @item{"item_value"}; # ); # ); # # # debug_message("#### query_db_for_report\n" . node_as_string(query_result) . "\n"); # debug_message("\n\n#### get_overview_query_result() END \n\n"); # # query_result; #));