Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 8110d0deae
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

executable file 122 lines (101 sloc) 3.513 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#!/usr/bin/env php
<?php
require_once 'MDB2.php';
$dsn = 'mysql://root:@localhost/pear';

try {
    $proposal_id = (int) $argv[1];
    if ($proposal_id < 1) {
        throw InvalidArgumentException("Please supply a number: ./rollback.php NUM");
    }

    $mdb2 = MDB2::connect($dsn);
    if (MDB2::isError($mdb2)) {
        throw new RuntimeException("Could not connect to database: {$e->getDebugInfo()}");
    }
    $pearweb = new Pearweb_Rollback($proposal_id, $mdb2);
    $pearweb->rollback();

} catch (Exception $e) {
    echo $e->getMessage();
    exit(1);
}

echo "All is well.\n";
exit;

class Pearweb_Rollback
{
    protected $mdb2;
    protected $proposal;

    public function __construct($proposal, MDB2_Driver_Common $mdb2)
    {
        if (!is_int($proposal)) {
            throw new InvalidArgumentException('$proposal must be an int');
        }
        $this->proposal = $proposal;
        $this->mdb2 = $mdb2;
    }

    public function rollback()
    {
        $this->moveVotes();
        echo "Moved votes to comments...\n";

        $this->resetDate();
        echo "Reset vote date...\n";

        $this->resetStatus();
        echo "Reset status...\n";
    }

    protected function moveVotes()
    {
        $sql = "SELECT * FROM package_proposal_votes WHERE pkg_prop_id = {$this->proposal}";
        $res = $this->mdb2->query($sql);
        if (MDB2::isError($res)) {
            throw new RuntimeException("DB error occurred: {$res->getDebugInfo()}");
        }
        if ($res->numRows() == 0) {
            return; // nothing to do
        }

        $insert = "INSERT INTO package_proposal_comments (";
        $insert .= "user_handle, pkg_prop_id, timestamp, comment";
        $insert .= ") VALUES(%s, {$this->proposal}, %d, %s)";

        $delete = "DELETE FROM package_proposal_votes WHERE";
        $delete .= " pkg_prop_id = {$this->proposal}";
        $delete .= " AND user_handle = %s";

        while ($row = $res->fetchRow(MDB2_FETCHMODE_OBJECT)) {

            $comment = "Original vote: {$row->value}\n";
            $comment .= "Conditional vote: " . ($row->is_conditional != 0)?'yes':'no' . "\n";
            $comment .= "Comment on vote: " . $row->comment . "\n\n";
            $comment .= "Reviewed: " . implode(", ", unserialize($row->reviews));

            $sql = sprintf(
                $insert,
                $this->mdb2->quote($row->user_handle),
                $row->timestamp,
                $this->mdb2->quote($comment)
            );
            $this->queryChange($sql);

            $sql = sprintf(
                $delete,
                $this->mdb2->quote($row->user_handle)
            );
            $this->queryChange($sql);
        }

        $res->free();
        return true;
    }

    protected function queryChange($sql)
    {
        $affected = $this->mdb2->exec($sql);
        if (MDB2::isError($affected)) {
            throw new RuntimeException("DB error occurred: " . $affected->getDebugInfo());
        }
        if ($affected < 1) {
            throw new UnexpectedValueException("No rows affected. Invalid proposal ID?");
        }
        return true;
    }

    protected function resetDate()
    {
        $sql = "UPDATE package_proposals SET vote_date = null WHERE id = {$this->proposal}";
        return $this->queryChange($sql);
    }

    protected function resetStatus()
    {
        $sql = "UPDATE proposal SET status='proposal' WHERE id = {$this->proposal}";
        return $this->queryChange($sql);
    }
}
Something went wrong with that request. Please try again.