00001 <?php
00013 require_once( 'commandLine.inc' );
00014
00015 if ( count( $args ) < 3 ) {
00016 echo "Usage: php fixTimestamps.php <offset in hours> <start time> <end time>\n";
00017 exit(1);
00018 }
00019
00020 $offset = $args[0] * 3600;
00021 $start = $args[1];
00022 $end = $args[2];
00023 $fname = 'fixTimestamps.php';
00024 $grace = 60;
00025
00026 # Find bounding revision IDs
00027 $dbw = wfGetDB( DB_MASTER );
00028 $revisionTable = $dbw->tableName( 'revision' );
00029 $res = $dbw->query( "SELECT MIN(rev_id) as minrev, MAX(rev_id) as maxrev FROM $revisionTable " .
00030 "WHERE rev_timestamp BETWEEN '{$start}' AND '{$end}'", $fname );
00031 $row = $dbw->fetchObject( $res );
00032
00033 if ( is_null( $row->minrev ) ) {
00034 echo "No revisions in search period.\n";
00035 exit(0);
00036 }
00037
00038 $minRev = $row->minrev;
00039 $maxRev = $row->maxrev;
00040
00041 # Select all timestamps and IDs
00042 $sql = "SELECT rev_id, rev_timestamp FROM $revisionTable " .
00043 "WHERE rev_id BETWEEN $minRev AND $maxRev";
00044 if ( $offset > 0 ) {
00045 $sql .= " ORDER BY rev_id DESC";
00046 $expectedSign = -1;
00047 } else {
00048 $expectedSign = 1;
00049 }
00050
00051 $res = $dbw->query( $sql, $fname );
00052
00053 $lastNormal = 0;
00054 $badRevs = array();
00055 $numGoodRevs = 0;
00056
00057 while ( $row = $dbw->fetchObject( $res ) ) {
00058 $timestamp = wfTimestamp( TS_UNIX, $row->rev_timestamp );
00059 $delta = $timestamp - $lastNormal;
00060 $sign = $delta == 0 ? 0 : $delta / abs( $delta );
00061 if ( $sign == 0 || $sign == $expectedSign ) {
00062
00063 $lastNormal = $timestamp;
00064 ++ $numGoodRevs;
00065 continue;
00066 } elseif ( abs( $delta ) <= $grace ) {
00067
00068 ++ $numGoodRevs;
00069 continue;
00070 } else {
00071
00072 $badRevs[] = $row->rev_id;
00073 }
00074 }
00075 $dbw->freeResult( $res );
00076
00077 $numBadRevs = count( $badRevs );
00078 if ( $numBadRevs > $numGoodRevs ) {
00079 echo
00080 "The majority of revisions in the search interval are marked as bad.
00081
00082 Are you sure the offset ($offset) has the right sign? Positive means the clock
00083 was incorrectly set forward, negative means the clock was incorrectly set back.
00084
00085 If the offset is right, then increase the search interval until there are enough
00086 good revisions to provide a majority reference.
00087 ";
00088
00089 exit(1);
00090 } elseif ( $numBadRevs == 0 ) {
00091 echo "No bad revisions found.\n";
00092 exit(0);
00093 }
00094
00095 printf( "Fixing %d revisions (%.2f%% of revisions in search interval)\n",
00096 $numBadRevs, $numBadRevs / ($numGoodRevs + $numBadRevs) * 100 );
00097
00098 $fixup = -$offset;
00099 $sql = "UPDATE $revisionTable " .
00100 "SET rev_timestamp=DATE_FORMAT(DATE_ADD(rev_timestamp, INTERVAL $fixup SECOND), '%Y%m%d%H%i%s') " .
00101 "WHERE rev_id IN (" . $dbw->makeList( $badRevs ) . ')';
00102
00103 $dbw->query( $sql, $fname );
00104 echo "Done\n";
00105
00106