gecko-dev/webtools/remora/services/bin/maintenance.php

243 строки
7.2 KiB
PHP

<?php
/**
* Maintenance script for addons.mozilla.org.
*
* The purpose of this document is to perform periodic tasks that should not be
* done everytime a download occurs in install.php. This should reduce
* unnecessary DELETE and UPDATE queries and lighten the load on the database
* backend.
*
* This script should not ever be accessed over HTTP, and instead run via cron.
* Only sysadmins should be responsible for operating this script.
*
* @package amo
* @subpackage bin
*/
// Before doing anything, test to see if we are calling this from the command
// line. If this is being called from the web, HTTP environment variables will
// be automatically set by Apache. If these are found, exit immediately.
if (isset($_SERVER['HTTP_HOST'])) {
exit;
}
// If we get here, we're on the command line, which means we can continue.
require_once('../config.php');
// For the addon object and db stuff
require_once('../../public/inc/includes.php');
/**
* * Get time as a float.
* * @return float
* */
function getmicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
// Start our timer.
$start = getmicrotime();
// Connect to our database.
$connection = mysql_connect(DB_HOST, DB_USER, DB_PASS);
if (!is_resource($connection)) {
die('Could not connect: ' . mysql_error());
} else {
mysql_select_db(DB_NAME, $connection);
}
// Get our action.
$action = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
// Perform specified task. If a task is not properly defined, exit.
switch ($action) {
/**
* Update weekly addon counts.
*/
case 'weekly':
// Get 7 day counts from the download table.
$seven_day_count_sql = "
SELECT
downloads.ID as ID,
COUNT(downloads.ID) as seven_day_count
FROM
`downloads`
WHERE
`date` >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY
downloads.ID
ORDER BY
downloads.ID
";
echo 'Retrieving seven-day counts from `downloads` ...'."\n";
$seven_day_count_result = mysql_query($seven_day_count_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
$affected_rows = mysql_num_rows($seven_day_count_result);
if ($affected_rows > 0 ) {
$seven_day_counts = array();
while ($row = mysql_fetch_array($seven_day_count_result)) {
$seven_day_counts[$row['ID']] = ($row['seven_day_count']>0) ? $row['seven_day_count'] : 0;
}
echo 'Updating seven day counts in `main` ...'."\n";
foreach ($seven_day_counts as $id=>$seven_day_count) {
$seven_day_count_update_sql = "
UPDATE `main` SET `downloadcount`='{$seven_day_count}' WHERE `id`='{$id}'
";
$seven_day_count_update_result = mysql_query($seven_day_count_update_sql, $connection)
or trigger_error('mysql error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
}
}
break;
/**
* Update all total download counts.
*/
case 'total':
// Get the max dID from downloads so we don't miscount hits
// that occur while the update query is running.
$max_sql = "
SELECT
MAX(dID) as max_id
FROM
downloads
";
$max_result = mysql_query($max_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
$max_row = mysql_fetch_array($max_result,MYSQL_ASSOC);
$max_id = $max_row['max_id'];
// Get uncounted hits from the download table.
// We only select counts for dID < max_id for accuracy.
$uncounted_hits_sql = "
SELECT
downloads.ID as ID,
COUNT(downloads.ID) as count
FROM
downloads
WHERE
`counted`=0 AND
dID <= {$max_id}
GROUP BY
downloads.ID
ORDER BY
downloads.ID
";
echo 'Retrieving uncounted downloads ...'."\n";
$uncounted_hits_result = mysql_query($uncounted_hits_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
$affected_rows = mysql_num_rows($uncounted_hits_result);
if ($affected_rows > 0) {
$uncounted_hits = array();
while ($row = mysql_fetch_array($uncounted_hits_result)) {
$uncounted_hits[$row['ID']] = ($row['count'] > 0) ? $row['count'] : 0;
}
echo 'Updating download totals ...'."\n";
foreach ($uncounted_hits as $id=>$hits) {
$uncounted_update_sql = "
UPDATE `main` SET `TotalDownloads`=`TotalDownloads`+{$hits} WHERE `ID`={$id}
";
$uncounted_update_result = mysql_query($uncounted_update_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
}
// If we get here, we've counted everything and we can mark stuff for
// deletion.
//
// Mark the downloads we just counted as counted if it has a key lower
// than max_id, because all keys lower than max_id have been counted above
$counted_update_sql = "
UPDATE
`downloads`
SET
`counted`=1
WHERE
dID <= {$max_id}
";
$counted_update_result = mysql_query($counted_update_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
} else {
$affected_rows = 0;
}
break;
/**
* Garbage collection for all records that are older than 8 days.
*/
case 'gc':
echo 'Starting garbage collection ...'."\n";
$gc_sql = "
DELETE FROM
`downloads`
WHERE
`date` < DATE_SUB(NOW(), INTERVAL 8 DAY)
";
$gc_result = mysql_query($gc_sql, $connection)
or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
E_USER_NOTICE);
// This is unreliable, but it's not a big deal.
$affected_rows = mysql_affected_rows();
echo 'Cleaning session tables...'."\n";
$_auth->gcSession();
break;
/**
* Unknown command.
*/
default:
echo 'Command not found. Exiting ...'."\n";
exit;
break;
}
// End switch.
// How long did it take to run?
$exectime = getmicrotime() - $start;
// Display script output.
echo 'Affected rows: '.$affected_rows.' ';
echo 'Time: '.$exectime."\n";
echo 'Exiting ...'."\n";
exit;
?>