Example #1
0
 /**
  * Reverts a series of SQL patches by looking up their down_sql code and executing it.
  */
 public function rollback()
 {
     $this->logger->log('Database rollback: ' . implode(', ', $this->sql_revert_patches), LOG_DEBUG);
     if (!count($this->sql_revert_patches)) {
         return;
     }
     foreach ($this->sql_revert_patches as $patch_name) {
         // get the code to revert the patch
         $result = $this->driver->query("\n                SELECT id, down_sql\n                FROM db_patches\n                WHERE patch_name = '" . $this->driver->escape($patch_name) . "'\n                ORDER BY applied_at DESC, id DESC;\n            ");
         if (!($patch_info = $this->driver->fetchAssoc($result))) {
             return;
         }
         if ($patch_info['down_sql'] != '') {
             // mark the patch as being reverted
             $this->driver->query("\n                    UPDATE db_patches\n                    SET reverted_at = '" . $this->driver->escape($this->timestamp) . "'\n                    WHERE patch_timestamp = '" . $this->driver->escape($patch_name) . "';\n                ");
             // revert the patch
             $this->driver->startTransaction();
             $this->driver->multiQuery($patch_info['down_sql']);
             if (false === $result) {
                 throw new DatabaseException('Error reverting patch ' . $patch_name . ': ' . $this->driver->getLastError(), 1);
             }
             $this->driver->doCommit();
         }
         // remove the patch from the db_patches table
         $this->driver->query("\n                DELETE FROM db_patches\n                WHERE id = " . $this->driver->escape($patch_info['id']) . ";\n            ");
         $this->logger->log("Patch '{$patch_name}' reverted.");
     }
 }