convert_version_81_profile = { version = "1.0.3" # 2012-02-21 - GMF - 1.0.1 - Fixed issue where ssession_entrances and ssession_exits were not removed from report elements # 2012-03-26 - GMF - 1.0.2 - Removed ssession-field xref tables. Fixed issue where MSSQL databases got a SQL error (CREATE/SELECT) # 2012-05-14 - GMF - 1.0.3 - Added cleanup of unique fields without source database field. label = "Convert 8.0/8.1 Profile To 8.5" description = "This converts a profile from 8.0/8.1 format to 8.5 format" shortcut = "cv8p" requires_profile = true parameters = { } expression = ` include "lib.snapon"; # Back up the profile. #echo("command_line.profile: " . command_line.profile); #echo("command_line.profile: " . command_line.profile); node profile = "profiles"{command_line.profile}; # Back up the profile node backup_profile = clone_node(profile); #echo("backup_profile=" . backup_profile); string backup_profile_pathname = LOGANALYSISINFO_DIRECTORY . "TemporaryFiles" . internal.directory_divider . command_line.profile . ".cfg.v81.bak"; #echo("backup_profile_pathname=" . backup_profile_pathname); write_file(backup_profile_pathname, node_as_string(backup_profile)); #echo("profile: " . profile); # Add the version, so we know this has been converted @profile{"version"}{"created_in_version"} = "unknown (pre-8.5)"; @profile{"version"}{"converted_80"} = true; bool have_sessions = profile{"database"}{"fields"}?{"ssession_id"}; #echo("have_sessions=" . have_sessions); # Create the snapons node @profile{"snapons"} = ""; node snapons = profile{"snapons"}; # Create the database filters node @profile{"database"}{"filters"} = ""; node database_filters = profile{"database"}{"filters"}; # Determine if the database exists (is build) #echo("command_line.profile: " . command_line.profile); node dbinfo = get_database_info(command_line.profile, false); #echo("dbinfo: " . node_as_string(dbinfo)); bool db_built = dbinfo{"database_info"}?{"initial_build_done"} and @dbinfo{"database_info"}{"initial_build_done"}; #echo("db_built: " . db_built); ## ## CONVERT LOG SOURCE ## # If this is a regular expression, extract the file mask from the pathname and put it in file_mask. node log_source; foreach log_source (profile{"log"}{"source"}) ( # echo("log_source: " . node_as_string(log_source)); if (@log_source{"pattern_is_regular_expression"}) then ( # echo("Converting regular expression to file mask"); if (matches_regular_expression(@log_source{"pathname"}, "^(.*)\\\\\\\\([^\\\\]+)$")) then ( @log_source{"pathname"} = $1; @log_source{"file_mask"} = $2; ); else if (matches_regular_expression(@log_source{"pathname"}, "^(.*)/([^/]+)$")) then ( @log_source{"pathname"} = $1; @log_source{"file_mask"} = $2; ); # echo("Converted: " . node_as_string(log_source)); ); # if pattern_is_regular_expression ); # foreach log_source ## ## CONVERT SESSIONS TO SNAPON ## #echo("have_sessions: " . have_sessions); if (have_sessions) then ( # Delete session log fields node log_fields = profile{"log"}{"fields"}; delete_node(log_fields{"ssession_id"}); delete_node(log_fields{"ssessions"}); delete_node(log_fields{"ssession_events"}); delete_node(log_fields{"ssession_user"}); delete_node(log_fields{"ssession_users"}); delete_node(log_fields{"ssession_date_time"}); delete_node(log_fields{"ssession_begin"}); delete_node(log_fields{"ssession_end"}); delete_node(log_fields{"ssession_duration"}); delete_node(log_fields{"ssession_page"}); delete_node(log_fields{"ssession_entrances"}); delete_node(log_fields{"ssession_exits"}); # Delete session database fields node database_fields = profile{"database"}{"fields"}; delete_node(database_fields{"ssession_id"}); delete_node(database_fields{"ssessions"}); delete_node(database_fields{"ssession_events"}); delete_node(database_fields{"ssession_user"}); delete_node(database_fields{"ssession_users"}); delete_node(database_fields{"ssession_date_time"}); delete_node(database_fields{"ssession_begin"}); delete_node(database_fields{"ssession_end"}); delete_node(database_fields{"ssession_duration"}); delete_node(database_fields{"ssession_page"}); delete_node(database_fields{"ssession_entrances"}); delete_node(database_fields{"ssession_exits"}); #echo("Deleted ssession fields from database fields: " . node_as_string(database_fields)); rewrite_database_config(profile); save_node(profile); # Delete session report fields node report_fields = profile{"statistics"}{"report_fields"}; delete_node(report_fields{"ssession_id"}); delete_node(report_fields{"ssessions"}); delete_node(report_fields{"ssession_events"}); delete_node(report_fields{"ssession_user"}); delete_node(report_fields{"ssession_users"}); delete_node(report_fields{"ssession_date_time"}); delete_node(report_fields{"ssession_begin"}); delete_node(report_fields{"ssession_end"}); delete_node(report_fields{"ssession_duration"}); delete_node(report_fields{"ssession_page"}); delete_node(report_fields{"ssession_entrances"}); delete_node(report_fields{"ssession_exits"}); # Remove session fields from xref groups node cross_reference_groups = profile{"database"}{"cross_reference_groups"}; node cross_reference_group; foreach cross_reference_group cross_reference_groups ( node fields = cross_reference_group{"fields"}; delete_node(fields{"ssessions"}); delete_node(fields{"ssession_events"}); delete_node(fields{"ssession_users"}); delete_node(fields{"ssession_begin"}); delete_node(fields{"ssession_end"}); delete_node(fields{"ssession_duration"}); delete_node(fields{"ssession_entrances"}); delete_node(fields{"ssession_exits"}); ); # foreach cross_reference_groups # If there are xrefs for the ssession_user, ssession_page, or ssession_id fields, delete those xrefs if (cross_reference_groups?{"ssession_user"}) then delete_node(cross_reference_groups{"ssession_user"}); if (cross_reference_groups?{"ssession_page"}) then delete_node(cross_reference_groups{"ssession_page"}); if (cross_reference_groups?{"ssession_id"}) then delete_node(cross_reference_groups{"ssession_id"}); # echo("rewrite 2"); rewrite_database_config(profile); # Remove session reports, and columns from reports node reports = profile{"statistics"}{"reports"}; int report_number = 0; while (report_number < num_subnodes(reports)) ( node report = reports[report_number]; node report_elements = report{"report_elements"}; int report_element_number = 0; while (report_element_number < num_subnodes(report_elements)) ( node report_element = report_elements[report_element_number]; # If this is a sessions report element, delete it if ( (@report_element{"type"} eq "sessions_overview") or (@report_element{"type"} eq "session_paths") or (@report_element{"type"} eq "session_page_paths") or (@report_element{"type"} eq "entry_pages") or (@report_element{"type"} eq "exit_pages") or (@report_element{"type"} eq "session_pages") or (@report_element{"type"} eq "session_users") or (@report_element{"type"} eq "individual_sessions") or false) then ( delete_node(report_element); ); # If this isn't a sessions report element, delete any session columns it has else ( if (report_element?{"columns"}) then ( node columns = report_element{"columns"}; int colnum = 0; while (colnum < num_subnodes(columns)) ( node column = columns[colnum]; if ((@column{"report_field"} eq "ssessions") or (@column{"report_field"} eq "ssession_events") or (@column{"report_field"} eq "ssession_users") or (@column{"report_field"} eq "ssession_duration") or (@column{"report_field"} eq "ssession_begin") or (@column{"report_field"} eq "ssession_entrances") or (@column{"report_field"} eq "ssession_exits") or (@column{"report_field"} eq "ssession_end") or false) then delete_node(column); else colnum++; ); # while columns ); # if columns # Go to the next report element report_element_number++; ); # if not sessions report ); # foreach report_element # If this report now has no elements, delete it if (num_subnodes(report_elements) == 0) then delete_node(report); # If the report still has elements, leave it, and go to the next report else report_number++; ); # while (report_number < num_subnodes(reports)) # Remove session reports from the reports menu node reports_menu = profile{"statistics"}{"reports_menu"}; if (reports_menu?{"sessions_group"}) then delete_node(reports_menu{"sessions_group"}); # If there is no sessions_group, maybe it's a numerically-named group (could happen if they edited it). # Search for a group containing only session reports, and delete if if we find it. else ( node reports_menu_group; bool found_sessions_group = false; node sessions_group; foreach reports_menu_group reports_menu ( #echo("reports_menu_group: " . reports_menu_group); bool found_non_session_report = false; if (reports_menu_group?{"items"}) then ( node report_menu_report; foreach report_menu_report (reports_menu_group{"items"}) ( #echo(" report: " . report_menu_report); if ((@report_menu_report{"report"} eq "sessions_overview") or (@report_menu_report{"report"} eq "session_paths") or (@report_menu_report{"report"} eq "session_page_paths") or (@report_menu_report{"report"} eq "entry_pages") or (@report_menu_report{"report"} eq "exit_pages") or (@report_menu_report{"report"} eq "session_pages") or (@report_menu_report{"report"} eq "session_users") or (@report_menu_report{"report"} eq "individual_sessions")) then ( #echo(" session report: " . report_menu_report); ); else ( #echo(" non-session report: " . report_menu_report); found_non_session_report = true; ); ); if (!found_non_session_report) then ( sessions_group = reports_menu_group; found_sessions_group = true; ); ); # if has "items" ); # foreach reports_menu_group if (found_sessions_group) then ( #echo("### Found sessions group: " . sessions_group); delete_node(sessions_group); ); # if found sessions group ); # if no "sessions_group" # Get the session field names string sessions_visitor_id_field = @profile{"log"}{"field_options"}{"sessions_visitor_id_field"}; string sessions_event_field = @profile{"log"}{"field_options"}{"sessions_event_field"}; string sessions_page_field = @profile{"log"}{"field_options"}{"sessions_page_field"}; string sessions_id_field = @profile{"log"}{"field_options"}{"sessions_id_field"}; delete_node(profile{"log"}{"field_options"}); # If there is no report field for the sessions visitor ID field, create one if (!report_fields?{sessions_visitor_id_field}) then ( @report_fields{sessions_visitor_id_field}{"label"} = sessions_visitor_id_field; @report_fields{sessions_visitor_id_field}{"column_label"} = ""; @report_fields{sessions_visitor_id_field}{"column_info"} = ""; @report_fields{sessions_visitor_id_field}{"database_field"} = sessions_visitor_id_field; @report_fields{sessions_visitor_id_field}{"display_format_type"} = "integer"; ); # Use session_id as the field name for the snapon if there's no field by that name; otherwise, use ssession_id. string snapon_session_id_field_name; if (profile{"database"}{"fields"}?{"session_id"}) then snapon_session_id_field_name = "ssession_id"; else snapon_session_id_field_name = "ssession_id"; # Use session_duration as the field name for the snapon if there's no field by that name; otherwise, use ssession_duration. string snapon_session_duration_field_name; if (profile{"database"}{"fields"}?{"session_duration"}) then snapon_session_duration_field_name = "ssession_duration"; else snapon_session_duration_field_name = "ssession_duration"; # Copy the session fields from the plug-in, to the snapon parameters; set up other snapon parameters node sessions = "snapons.sessions"; @sessions{'parameters'}{'session_user_field'}{'parameter_value'} = sessions_visitor_id_field; @sessions{'parameters'}{'session_page_field'}{'parameter_value'} = sessions_page_field; @sessions{'parameters'}{'session_events_field'}{'parameter_value'} = sessions_event_field; @sessions{'parameters'}{'session_date_time_field'}{'parameter_value'} = 'date_time'; @sessions{'parameters'}{'session_id_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_id))=}'; @sessions{'parameters'}{'session_id_name'}{'final_node_name'} = snapon_session_id_field_name; @sessions{'parameters'}{'sessions_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.sessions))=}'; @sessions{'parameters'}{'sessions_name'}{'final_node_name'} = 'sessions'; @sessions{'parameters'}{'session_sequence_number_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_sequence_number))=}'; @sessions{'parameters'}{'session_sequence_number_name'}{'final_node_name'} = 'session_sequence_number'; @sessions{'parameters'}{'session_entrances_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_entrances))=}'; @sessions{'parameters'}{'session_entrances_name'}{'final_node_name'} = 'session_entrances'; @sessions{'parameters'}{'session_exits_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_exits))=}'; @sessions{'parameters'}{'session_exits_name'}{'final_node_name'} = 'session_exits'; @sessions{'parameters'}{'session_begin_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_begin))=}'; @sessions{'parameters'}{'session_begin_name'}{'final_node_name'} = 'session_begin'; @sessions{'parameters'}{'session_end_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_end))=}'; @sessions{'parameters'}{'session_end_name'}{'final_node_name'} = 'session_end'; @sessions{'parameters'}{'session_duration_name'}{'parameter_value'} = '{=capitalize(expand(lang_stats.field_labels.session_duration))=}'; @sessions{'parameters'}{'session_duration_name'}{'final_node_name'} = snapon_session_duration_field_name; @sessions{'parameters'}{'sessions_overview'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.sessions_overview)=}'; @sessions{'parameters'}{'sessions_overview'}{'final_node_name'} = 'sessions_overview'; @sessions{'parameters'}{'session_paths'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.session_paths)=}'; @sessions{'parameters'}{'session_paths'}{'final_node_name'} = 'session_paths'; @sessions{'parameters'}{'session_page_paths'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.session_page_paths)=}'; @sessions{'parameters'}{'session_page_paths'}{'final_node_name'} = 'session_page_paths'; @sessions{'parameters'}{'entry_pages'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.entry_pages)=}'; @sessions{'parameters'}{'entry_pages'}{'final_node_name'} = 'entry_pages'; @sessions{'parameters'}{'exit_pages'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.exit_pages)=}'; @sessions{'parameters'}{'exit_pages'}{'final_node_name'} = 'exit_pages'; @sessions{'parameters'}{'individual_sessions'}{'parameter_value'} = '{=expand(lang_stats.menu.reports.individual_sessions)=}'; @sessions{'parameters'}{'individual_sessions'}{'final_node_name'} = 'individual_sessions'; @sessions{'parameters'}{'report_group_name'}{'parameter_value'} = '{=expand(lang_stats.menu.groups.sessions_group)=}'; @sessions{'parameters'}{'report_group_name'}{'final_node_name'} = 'sessions'; ); # if have sessions #echo("db_built: " . db_built); # If the database is built, convert it to 8.5 format if (db_built) then ( # Add the db_filters_computed field to the main table node dbfield; string new_fields = "loadorder, db_filters_computed"; string old_fields = "loadorder, 0"; foreach dbfield (profile{"database"}{"fields"}) ( # Unique fields no longer appear in main_table; only copy the other ones if (@dbfield{"type"} ne "unique") then ( if (new_fields ne "") then new_fields .= ", "; new_fields .= node_name(dbfield); if (node_name(dbfield) eq "date_time") then new_fields .= ", bottomleveldate"; if (old_fields ne "") then old_fields .= ", "; old_fields .= node_name(dbfield); if (node_name(dbfield) eq "date_time") then old_fields .= ", bottomleveldate"; ); # if not unique ); # foreach dbfield #echo("Adding db_filters_computed"); # Add db_filters_computed to the main_table, at the end string db_filters_computed_query = "alter table main_table add db_filters_computed int"; database_sql_query(db_filters_computed_query, false, false); #DEBUG: get rid of visitors column # Move db_filters_computed to the proper position (second in the table). # 2012-03-26 - GMF - MSSQL doesn't support INSERT/SELECT; use SELECT/INTO instead bool mssql = (@profile{"database"}{"options"}{"server"}{"type"}) eq "odbc_mssql"; if (mssql) then database_sql_query("select " . new_fields . " into main_table_plus_dfc from main_table", false, false); else database_sql_query("create table main_table_plus_dfc select " . new_fields . " from main_table", false, false); database_sql_query("drop table main_table", false, false); if (mssql) then database_sql_query("select " . new_fields . " into main_table from main_table_plus_dfc", false, false); else database_sql_query("create table main_table select " . new_fields . " from main_table_plus_dfc", false, false); database_sql_query("drop table main_table_plus_dfc", false, false); string database_directory = get_database_directory(profile); # echo("database_directory: " . database_directory); string config_pathname = database_directory . "config"; #delete_file(config_pathname); rewrite_database_config(profile); save_node(profile); ); # if database built # If we have sessions, attached the sessions snapon if (have_sessions) then ( # Attach the sessions snapon attach_snapon(profile, "snapons.sessions", "sessions"); #echo("sleeping");sleep_milliseconds(100000); save_node(profile); ); # if have_sessions # Create the internal_optimize snapon description @snapons{"internal_optimize"} = ""; @snapons{"internal_optimize"}{"snapon_name"} = "internal_optimize"; # Create the internal_optimize database filter @database_filters{"internal_optimize"} = ""; @database_filters{"internal_optimize"}{"expression"} = "internal_optimize_current_database_filter_row();"; if (db_built) then ( # Force rebuild of all indices string database_directory = get_database_directory(profile); string tables_directory = database_directory . "Tables"; v.tablesdir = ""; get_directory_contents(tables_directory, "v.tablesdir"); node tabledir; foreach tabledir 'v.tablesdir' ( string indicesdir = @tabledir{"pathname"} . internal.directory_divider . 'indices'; delete_directory(indicesdir); string infopathname = @tabledir{"pathname"} . internal.directory_divider . 'info.cfg'; if (file_exists(infopathname)) then ( node info = string_to_node(read_file(infopathname)); if (info?{"indices"}) then delete_node(info{"indices"}); write_file(infopathname, node_as_string(info)); ); ); # foreach tabledir save_node(profile); # Rebuild database filters volatile.options.1 = "background"; volatile.options.2 = "-p"; volatile.options.3 = node_name(profile); volatile.options.4 = "-a"; volatile.options.5 = "udf"; volatile.options.6 = "-fr"; volatile.options.7 = true; string pid = exec("", "volatile.options", true); ); # if db_built ## ## CONVERT OVERVIEW TO REPORT-FIELD VERSION ## #echo(1); node report; node database_fields = profile{"database"}{"fields"}; foreach report (profile{"statistics"}{"reports"}) ( node report_element; foreach report_element (report{"report_elements"}) ( if (@report_element{"type"} eq "overview") then ( # echo("Found Overview"); node columns = report_element{"columns"}; node report_field; int nodenum = 0; foreach report_field (profile{"statistics"}{"report_fields"}) ( # echo("Considering adding report field " . report_field . " to columns"); if (report_field?{"database_field"} and (@report_field{"database_field"} ne "")) then ( # echo("Is database field"); node database_field = database_fields{@report_field{"database_field"}}; # echo("database_field: " . database_field); if ((database_field?{"aggregation_method"}) and (@database_field{"aggregation_method"} ne "none")) then ( # echo("Found aggregating database field: " . database_field); columns{nodenum}{"report_field"} = node_name(report_field); columns{nodenum}{"show_column"} = true; nodenum++; # echo("Added report column to overview"); ); # if aggregating field ); # if this report field is based on a database field ); # foreach report_fields ); # if overview ); # foreach report_element ); # foreach report #echo(2); # If there is a "unique" field with log_field set to a field that doesn't exist as a database field, create that database field. # 8.1 is blase about this, and automatically creates it; but 8.5 doesn't allow it. node database_field; foreach database_field database_fields ( if (@database_field{"type"} eq "unique") then ( string source_field_name = @database_field{"log_field"}; if (!database_fields?{source_field_name}) then ( node source_field = database_fields{source_field_name}; @source_field{"type"} = "string"; @source_field{"suppress_top"} = 99; @source_field{"suppress_bottom"} = 99; @source_field{"aggregation_operator"} = "none"; @source_field{"log_field"} = source_field_name; @source_field{"label"} = source_field; ); # if no source field ); # if unique ); # foreach database field save_node(profile); ` } # convert_version_81_profile