/** * Process all the raw data up to the previous day. * * The primary key on the {project_usage_raw} table will prevent duplicate * records provided we process them once the day is complete. If we pull them * out too soon and the site checks in again they will be counted twice. */ function project_usage_process_daily() { // Timestamp for begining of the previous day. $timestamp = project_usage_daily_timestamp(NULL, 1); $time_0 = time(); watchdog('project_usage', 'Starting to process daily usage data for !date.', array('!date' => format_date($timestamp, 'custom', 'Y-m-d'))); // Assign API version term IDs. $terms = array(); foreach (project_release_get_api_taxonomy() as $term) { $terms[$term->tid] = $term->name; } $num_updates = 0; $query = db_query("SELECT DISTINCT api_version FROM {project_usage_raw} WHERE tid = 0"); while ($row = db_fetch_object($query)) { $tid = array_search($row->api_version, $terms); db_query("UPDATE {project_usage_raw} SET tid = %d WHERE api_version = '%s'", $tid, $row->api_version); $num_updates += db_affected_rows(); } $time_1 = time(); $substitutions = array('!rows' => format_plural($num_updates, '1 row', '@count rows'), '!delta' => format_interval($time_1 - $time_0)); watchdog('project_usage', 'Assigned API version term IDs for !rows (!delta).', $substitutions); // Asign project and release node IDs. $num_updates = 0; $query = db_query("SELECT DISTINCT project_uri, project_version FROM {project_usage_raw} WHERE pid = 0 OR nid = 0"); while ($row = db_fetch_object($query)) { $pid = db_result(db_query("SELECT pp.nid AS pid FROM {project_projects} pp WHERE pp.uri = '%s'", $row->project_uri)); if ($pid) { $nid = db_result(db_query("SELECT prn.nid FROM {project_release_nodes} prn WHERE prn.pid = %d AND prn.version = '%s'", $pid, $row->project_version)); db_query("UPDATE {project_usage_raw} SET pid = %d, nid = %d WHERE project_uri = '%s' AND project_version = '%s'", $pid, $nid, $row->project_uri, $row->project_version); $num_updates += db_affected_rows(); } } $time_2 = time(); $substitutions = array('!rows' => format_plural($num_updates, '1 row', '@count rows'), '!delta' => format_interval($time_2 - $time_1)); watchdog('project_usage', 'Assigned project and release node IDs to !rows (!delta).', $substitutions); // Move usage records with project node IDs into the daily table and remove // the rest. db_query("INSERT INTO {project_usage_day} (timestamp, site_key, pid, nid, tid, ip_addr) SELECT timestamp, site_key, pid, nid, tid, ip_addr FROM {project_usage_raw} WHERE timestamp < %d AND pid <> 0", $timestamp); $num_new_day_rows = db_affected_rows(); db_query("DELETE FROM {project_usage_raw} WHERE timestamp < %d", $timestamp); $num_deleted_raw_rows = db_affected_rows(); $time_3 = time(); $substitutions = array('!day_rows' => format_plural($num_new_day_rows, '1 row', '@count rows'), '!raw_rows' => format_plural($num_deleted_raw_rows, '1 row', '@count rows'), '!delta' => format_interval($time_3 - $time_2)); watchdog('project_usage', 'Moved usage from raw to daily: !day_rows added to {project_usage_day}, !raw_rows deleted from {project_usage_raw} (!delta).', $substitutions); // Remove old daily records. $seconds = variable_get('project_usage_life_daily', 4 * PROJECT_USAGE_WEEK); db_query("DELETE FROM {project_usage_day} WHERE timestamp < %d", time() - $seconds); $time_4 = time(); $substitutions = array('!rows' => format_plural(db_affected_rows(), '1 old daily row', '@count old daily rows'), '!delta' => format_interval($time_4 - $time_3)); watchdog('project_usage', 'Removed !rows (!delta).', $substitutions); watchdog('project_usage', 'Completed daily usage data processing (total time: !delta).', array('!delta' => format_interval($time_4 - $time_0))); }
/** * Process all the raw data up to the previous day. * * The primary key on the {project_usage_raw} table will prevent duplicate * records provided we process them once the day is complete. If we pull them * out too soon and the site checks in again they will be counted twice. */ function project_usage_process_daily() { // Timestamp for beginning of the previous day. $timestamp = project_usage_daily_timestamp(NULL, 1); $time_0 = microtime(TRUE); watchdog('project_usage', 'Starting to process daily usage data for !date.', array('!date' => format_date($timestamp, 'custom', 'Y-m-d'))); // Assign project and release node IDs. $num_updates = 0; $result = db_query("SELECT DISTINCT name, version FROM {project_usage_raw} WHERE project_nid = 0 OR release_nid = 0"); foreach ($result as $row) { $project_nid = db_query("SELECT nid FROM {project} WHERE name = :name", array(':name' => $row->name))->fetchField(); if ($project_nid) { $release_nid = db_query("SELECT nid FROM {project_release} WHERE project_nid = :project_nid AND version = :version", array(':project_nid' => $project_nid, ':version' => $row->version))->fetchField(); if ($release_nid) { $update_result = db_query("UPDATE {project_usage_raw} SET project_nid = :project_nid, release_nid = :release_nid WHERE name = :name AND version = :version", array(':project_nid' => $project_nid, ':release_nid' => $release_nid, ':name' => $row->name, ':version' => $row->version)); $num_updates += $update_result->rowCount(); } } } $time_1 = time(); $substitutions = array('!rows' => format_plural($num_updates, '1 row', '@count rows'), '!delta' => format_interval($time_1 - $time_0)); watchdog('project_usage', 'Assigned project and release node IDs to !rows (!delta).', $substitutions); // Move usage records with project node IDs into the daily table and remove // the rest. $result = db_query("INSERT INTO {project_usage_day} (timestamp, site_key, project_nid, release_nid, version_api, hostname) SELECT timestamp, site_key, project_nid, release_nid, version_api, hostname FROM {project_usage_raw} WHERE timestamp < :timestamp AND project_nid <> 0", array(':timestamp' => $timestamp)); $num_new_day_rows = $result->rowCount(); $result = db_query("DELETE FROM {project_usage_raw} WHERE timestamp < :timestamp", array(':timestamp' => $timestamp)); $num_deleted_raw_rows = $result->rowCount(); $time_2 = microtime(TRUE); $substitutions = array('!day_rows' => format_plural($num_new_day_rows, '1 row', '@count rows'), '!raw_rows' => format_plural($num_deleted_raw_rows, '1 row', '@count rows'), '!delta' => format_interval($time_2 - $time_1)); watchdog('project_usage', 'Moved usage from raw to daily: !day_rows added to {project_usage_day}, !raw_rows deleted from {project_usage_raw} (!delta).', $substitutions); // Remove old daily records. $seconds = config_get('project_usage.settings', 'life_daily'); $result = db_query("DELETE FROM {project_usage_day} WHERE timestamp < :timestamp", array(':timestamp' => REQUEST_TIME - $seconds)); $time_3 = microtime(TRUE); $substitutions = array('!rows' => format_plural($result->rowCount(), '1 old daily row', '@count old daily rows'), '!delta' => format_interval($time_3 - $time_2)); watchdog('project_usage', 'Removed !rows (!delta).', $substitutions); watchdog('project_usage', 'Completed daily usage data processing (total time: !delta).', array('!delta' => format_interval($time_2 - $time_0))); }
/** * Compute the weekly summaries for the week starting at the given timestamp. * * @param $week_start_timestamp * Timestamp indicating the start of the week for which stats should be * calculated. */ function project_usage_process_weekly($week_start_timestamp) { // Ensure the timestamp is a starting timestamp. $start = project_usage_weekly_timestamp($week_start_timestamp); $end = project_usage_weekly_timestamp($week_start_timestamp, 1); // Safety check to prevent processing of the current week's numbers, as the // week has not yet finished. if ($end > REQUEST_TIME) { return; } $start_date = format_date($start, 'custom', 'Y-m-d'); $end_date = format_date(project_usage_daily_timestamp($end, -1), 'custom', 'Y-m-d'); // Try to compute the usage tallies per project and per release. If there // is a problem--perhaps some rows existed from a previous, incomplete // run that are preventing inserts, throw a watchdog error. try { $sql = "INSERT INTO {project_usage_week_project} (nid, timestamp, version_api, count) SELECT project_nid as nid, :start, version_api, COUNT(DISTINCT site_key) FROM {project_usage_day} WHERE timestamp >= :start AND timestamp < :end AND project_nid <> 0 GROUP BY project_nid, version_api"; $query_args = array(':start' => $start, ':end' => $end); $result = db_query($sql, $query_args); $project_count = $result->rowCount(); } catch (PDOException $e) { $project_count = 0; $substitutions = array('@start' => $start_date, '@end' => $end_date); watchdog('project_usage', 'Weekly project tallies for the week of @start through @end already calculated. No data updated.', $substitutions); } try { $sql = "INSERT INTO {project_usage_week_release} (nid, timestamp, count) SELECT release_nid as nid, :start, COUNT(DISTINCT site_key) FROM {project_usage_day} WHERE timestamp >= :start AND timestamp < :end AND release_nid <> 0 GROUP BY release_nid"; $query_args = array(':start' => $start, ':end' => $end); $result = db_query($sql, $query_args); $release_count = $result->rowCount(); } catch (PDOException $e) { $release_count = 0; $substitutions = array('@start' => $start_date, '@end' => $end_date); watchdog('project_usage', 'Weekly release tallies for the week of @start through @end already calculated. No data updated.', $substitutions); } $substitutions = array('@projects' => format_plural($project_count, '1 project', '@count projects'), '@releases' => format_plural($release_count, '1 release', '@count releases'), '@start' => $start_date, '@end' => $end_date); watchdog('project_usage', 'Completed weekly usage data processing on @projects and @releases for the week of @start through @end.', $substitutions); }