/**
 * Handles request for ROLLBACK.
 *
 * @param string $sql_query SQL query(s)
 *
 * @return void
 */
function PMA_handleRollbackRequest($sql_query)
{
    $sql_delimiter = $_REQUEST['sql_delimiter'];
    $queries = explode($sql_delimiter, $sql_query);
    $error = false;
    $error_msg = __('Only INSERT, UPDATE, DELETE and REPLACE ' . 'SQL queries containing transactional engine tables can be rolled back.');
    foreach ($queries as $sql_query) {
        if (empty($sql_query)) {
            continue;
        }
        // Check each query for ROLLBACK support.
        if (!PMA_checkIfRollbackPossible($sql_query)) {
            $global_error = $GLOBALS['dbi']->getError();
            if ($global_error) {
                $error = $global_error;
            } else {
                $error = $error_msg;
            }
            break;
        }
    }
    if ($error) {
        unset($_REQUEST['rollback_query']);
        $response = PMA_Response::getInstance();
        $message = PMA_Message::rawError($error);
        $response->addJSON('message', $message);
        exit;
    } else {
        // If everything fine, START a transaction.
        $GLOBALS['dbi']->query('START TRANSACTION');
    }
}
Example #2
0
 /**
  * Test for PMA_checkIfRollbackPossible
  *
  * @return void
  */
 function testPMACheckIfRollbackPossible()
 {
     $GLOBALS['db'] = 'PMA';
     //mock DBI
     $dbi = $this->getMockBuilder('PMA\\libraries\\DatabaseInterface')->disableOriginalConstructor()->getMock();
     // List of Transactional Engines.
     $transactional_engines = array('INNODB', 'FALCON', 'NDB', 'INFINIDB', 'TOKUDB', 'XTRADB', 'SEQUENCE', 'BDB');
     $check_query = 'SELECT `ENGINE` FROM `information_schema`.`tables` ' . 'WHERE `table_name` = "%s" ' . 'AND `table_schema` = "%s" ' . 'AND UPPER(`engine`) IN ("' . implode('", "', $transactional_engines) . '")';
     $check_table_query = 'SELECT * FROM `%s`.`%s` ' . 'LIMIT 1';
     $dbi->expects($this->at(0))->method('tryQuery')->with(sprintf($check_table_query, 'PMA', 'table_1'))->will($this->returnValue(array('table')));
     $dbi->expects($this->at(1))->method('tryQuery')->with(sprintf($check_query, 'table_1', 'PMA'))->will($this->returnValue(true));
     $dbi->expects($this->at(2))->method('numRows')->will($this->returnValue(1));
     $dbi->expects($this->at(3))->method('tryQuery')->with(sprintf($check_table_query, 'PMA', 'table_2'))->will($this->returnValue(array('table')));
     $dbi->expects($this->at(4))->method('tryQuery')->with(sprintf($check_query, 'table_2', 'PMA'))->will($this->returnValue(true));
     $dbi->expects($this->at(5))->method('numRows')->will($this->returnValue(1));
     $GLOBALS['dbi'] = $dbi;
     $sql_query = 'UPDATE `table_1` AS t1, `table_2` t2 ' . 'SET `table_1`.`id` = `table_2`.`id` ' . 'WHERE 1';
     $this->assertEquals(true, PMA_checkIfRollbackPossible($sql_query));
 }