1
0
Fork 0
- changes and fixes for parsing statements
- QA

SQl-Browser / SQL-Box:
-  added semicolon to table select box
Dieser Commit ist enthalten in:
DSB 2011-06-20 13:39:03 +00:00
Ursprung 2a46539fe5
Commit e95ab08945
13 geänderte Dateien mit 98 neuen und 56 gelöschten Zeilen

Datei anzeigen

@ -394,12 +394,11 @@ class SqlController extends Zend_Controller_Action
if ($sqlObject->hasErrors()) { if ($sqlObject->hasErrors()) {
$this->view->errorMessage = implode('<br />', $sqlObject->getErrors()); $this->view->errorMessage = implode('<br />', $sqlObject->getErrors());
} }
//echo $parser->getDebugOutput();
$statements = $parser->getParsedStatements(); $statements = $parser->getParsedStatements();
foreach ($statements as $statement) { foreach ($statements as $statement) {
echo "<br>- ".$statement; //echo "<br>Extracted statement: ".$statement;
try { try {
$res = array(); //$this->_db->query($statement, Msd_Db::ARRAY_ASSOC); $res = $this->_db->query($statement, Msd_Db::ARRAY_ASSOC);
$this->view->resultset = $res; $this->view->resultset = $res;
} catch (Exception $e) { } catch (Exception $e) {
$this->view->errorMessage = $e->getMessage(); $this->view->errorMessage = $e->getMessage();

Datei anzeigen

@ -43,7 +43,7 @@ if (isset($this->errorMessage)) {
function setShowTableQuery() function setShowTableQuery()
{ {
query = $('#selectTable').attr('value'); query = $('#selectTable').attr('value');
query = 'SELECT * FROM `' + query + '`'; query = 'SELECT * FROM `' + query + '`;';
$('#sqltextarea').val(query); $('#sqltextarea').val(query);
$('#myForm').submit(); $('#myForm').submit();
} }

Datei anzeigen

@ -45,11 +45,10 @@ class Msd_Html
* filter select boxes (e.g. sqlserver/show.variables). * filter select boxes (e.g. sqlserver/show.variables).
* *
* @param array $array Array to scan for prefixes * @param array $array Array to scan for prefixes
* @param boolean $addNoneOption Whether to add a first entry '---'
* *
* @return $prefix_array array The array conatining the unique prefixes * @return array The array conatining the unique prefixes
*/ */
public static function getPrefixArray($array, $addNoneOption = true) public static function getPrefixArray($array)
{ {
$prefixes = array(); $prefixes = array();
$keys = array_keys($array); $keys = array_keys($array);

Datei anzeigen

@ -115,33 +115,48 @@ class Msd_Sql_Object
{ {
$pointer = $this->getPointer(); $pointer = $this->getPointer();
$dataSize = strlen($this->_data); $dataSize = strlen($this->_data);
$skip = array(';', ' ', "\n", "\r"); $skip = array(' ', "\n", "\r", "\t");
if ($this->_state !== 'Comment') {
$skip[] = "\n";
}
if (in_array($this->_data[$pointer], $skip)) { if (in_array($this->_data[$pointer], $skip)) {
while ($pointer < $dataSize && in_array($this->_data[$pointer], $skip)) { while ($pointer < $dataSize && in_array($this->_data[$pointer], $skip)) {
$pointer++; $pointer++;
} }
} }
$this->setPointer($pointer); $this->setPointer($pointer);
if ($pointer == $this->getLength()) { if ($pointer >= $this->getLength()) {
$pointer = false; $pointer = false;
} }
return $pointer; return $pointer;
} }
/**
* Move pointer forward by $positions positions.
*
* @param integer $positions Move pointer forward by $positions
*
* @return void
*/
public function movePointerForward($positions)
{
$this->setPointer($this->getPointer() + $positions);
}
/** /**
* Get some characters of data. * Get data from actual pointer to given position.
* *
* @param int $nrOfCharacters Number of characters to get * @param int $endPosition End position of pointer
* @param bool $movePointer Move pointer behind fetched data
* *
* @return string Sql data from the pointer position to end or to the nr of chars to fetch * @return string Sql data from the pointer position to end or to the nr of chars to fetch
*/ */
public function getData($nrOfCharacters = null) public function getData($endPosition, $movePointer = true)
{ {
if ($nrOfCharacters > 0) { $data = substr($this->_data, $this->_pointer, ($endPosition - $this->_pointer));
return substr($this->_data, $this->_pointer, $nrOfCharacters); if ($movePointer === true) {
} else { $this->setPointer($endPosition +1);
return substr($this->_data, $this->_pointer);
} }
return $data;
} }
/** /**
@ -195,11 +210,19 @@ class Msd_Sql_Object
$pointer = $this->getPointer(); $pointer = $this->getPointer();
$offset = $pointer; $offset = $pointer;
$notFound = true; $notFound = true;
$nextHit = 0; $nextHit = false;
$length = $this->getLength() - 1; $length = $this->getLength() - 1; // zero-based
while ($notFound && $offset < $length) { while ($notFound && $offset < $length) {
$nextHit = strpos($this->_data, $match, $offset); $nextHit = strpos($this->_data, $match, $offset);
//echo "<br>getPosition: Search for '".$match."' P: ".$offset."-> Hit at :".$nextHit;
if ($nextHit === false) { if ($nextHit === false) {
// check special case for comments
if ($this->getState() == 'Comment' && strpos($this->_data, "\n", $pointer) === false) {
// there is no next line - return statement "as is"
$this->setPointer($this->getLength());
return $this->getLength();
}
// we haven't found the correct end of the query - inform user
$lang = Msd_Language::getInstance()->getTranslator(); $lang = Msd_Language::getInstance()->getTranslator();
$msg = sprintf( $msg = sprintf(
$lang->_('L_SQL_INCOMPLETE_STATEMENT_DETECTED'), $lang->_('L_SQL_INCOMPLETE_STATEMENT_DETECTED'),
@ -211,25 +234,51 @@ class Msd_Sql_Object
$this->setPointer($this->getLength()); $this->setPointer($this->getLength());
return false; return false;
} }
// now check if we found an escaped occurance
$string = substr($this->_data, $pointer, $nextHit); $data = $this->getData($nextHit, false);
$string = str_replace('\\\\', '', trim($string)); if (!$this->isEscaped($data)) {
$quotes = substr_count($string, '\'');
$escapedQuotes = substr_count($string, '\\\'');
if (($quotes - $escapedQuotes) % 2 == 0) {
// hit was not escaped - we found the match // hit was not escaped - we found the match
$notFound = false; $notFound = false;
if ($includeMatch) { if ($includeMatch) {
$nextHit += strlen($match); $nextHit += strlen($match)-1;
} }
} else { } else {
// keep on looking, this was escaped // keep on looking, this one was escaped
$offset = $pointer + $nextHit; $offset = $nextHit+1;
} }
} }
return $nextHit; return $nextHit;
} }
/**
* Get data upto the next new line
*
* @return string
*/
public function getDataUntilNewLine()
{
}
/**
* Check if hit is escaped.
*
* @param string $string String to analyse
*
* @return bool
*/
private function isEscaped($string)
{
$string = str_replace('\\\\', '', $string);
$quotes = substr_count($string, '\'');
$escapedQuotes = substr_count($string, '\\\'');
if (($quotes - $escapedQuotes) % 2 == 0) {
return false;
} else {
return true;
}
}
/** /**
* Set an error message * Set an error message
* *

Datei anzeigen

@ -82,30 +82,31 @@ class Msd_Sql_Parser implements Iterator
{ {
$statementCounter = 0; $statementCounter = 0;
while ($this->_sql->hasMoreToProcess() && $this->_sql->movePointerToNextCommand()!==false) { while ($this->_sql->hasMoreToProcess() && $this->_sql->movePointerToNextCommand()!==false) {
$startPosition = $this->_sql->getPointer(); // check for comments or conditional comments
$commentCheck = $this->_sql->getData($this->_sql->getPointer() + 3, false);
if (substr($commentCheck,0 , 2) == '--' || substr($commentCheck, 0, 2) == '/*') {
$statement = 'Comment';
} else {
//$this->_sql->movePointerToNextCommand();
// get first "word" of query to extract the kind we have to process // get first "word" of query to extract the kind we have to process
$endOfFirstWord = $this->_sql->getPosition(' ', false); $endOfFirstWord = $this->_sql->getPosition(' ', false);
// get substring from actual position to found position $sqlQuery = $this->_sql->getData($endOfFirstWord, false);
$sqlQuery = $this->_sql->getData($endOfFirstWord - $startPosition);
$statement = strtolower($sqlQuery); $statement = strtolower($sqlQuery);
// check for comments or conditional comments
$commentCheck = substr($sqlQuery, 0, 2);
if (isset($this->_sqlComments[$commentCheck]) || substr($statement, 0, 3) == '/*!') {
$statement = 'Comment';
} }
try { try {
$foundStatement = $this->_parseStatement($this->_sql, ucfirst($statement)); $foundStatement = $this->_parseStatement($this->_sql, ucfirst($statement));
} catch (Msd_Sql_Parser_Exception $e) { } catch (Msd_Sql_Parser_Exception $e) {
// stop parsing by setting pointer to the end // stop parsing by setting pointer to the end
$this->_sql->setPointer($this->_sql->getLength()-1); $this->_sql->setPointer($this->_sql->getLength());
echo "<br>Error: ".$e->getMessage();
} }
if ($this->_debug) { if ($this->_debug) {
$this->_debugOutput .= '<br />Extracted statement: '.$foundStatement; $this->_debugOutput .= '<br />Extracted statement: '.$foundStatement;
} }
if ($foundStatement > '') {
$this->_parsedStatements[] = $foundStatement; $this->_parsedStatements[] = $foundStatement;
$statementCounter++; $statementCounter++;
}
// increment query type counter // increment query type counter
if (!isset($this->_parsingSummary[$statement])) { if (!isset($this->_parsingSummary[$statement])) {
$this->_parsingSummary[$statement] = 0; $this->_parsingSummary[$statement] = 0;

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Alter implements Msd_Sql_Parser_Interface
$sql->setState('Alter'); $sql->setState('Alter');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -21,18 +21,20 @@ class Msd_Sql_Parser_Statement_Comment implements Msd_Sql_Parser_Interface
/** /**
* Parse the statement. * Parse the statement.
* *
* @param Msd_Sql_Object $statement MySQL comment. * @param Msd_Sql_Object $sql MySQL comment.
* *
* @return void * @return string
*/ */
public function parse(Msd_Sql_Object $sql) public function parse(Msd_Sql_Object $sql)
{ {
$sql->setState('Comment'); $sql->setState('Comment');
$firstChars = $sql->getData(3); $firstChars = $sql->getData($sql->getPointer() + 3, false);
$includeMatch = true;
$returnStatement = false; $returnStatement = false;
if (substr($firstChars, 0, 2) == '--' || substr($firstChars, 0, 1) == '#') { if (substr($firstChars, 0, 2) == '--' || substr($firstChars, 0, 1) == '#') {
// one line comment -> match new line // one line comment -> match new line
$match = "\n"; $match = "\n";
$includeMatch = false;
} else { } else {
if ($firstChars == '/*!') { if ($firstChars == '/*!') {
// conditionial statement // conditionial statement
@ -43,13 +45,12 @@ class Msd_Sql_Parser_Statement_Comment implements Msd_Sql_Parser_Interface
$match = '*/'; $match = '*/';
} }
} }
$endOfStatement = $sql->getPosition($match); $endOfStatement = $sql->getPosition($match, $includeMatch);
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
if ($returnStatement === true) { if ($returnStatement === true) {
return $statement; return $statement;
} else { } else {
return false; return '';
} }
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Create implements Msd_Sql_Parser_Interface
$sql->setState('Create'); $sql->setState('Create');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Drop implements Msd_Sql_Parser_Interface
$sql->setState('Drop'); $sql->setState('Drop');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Insert implements Msd_Sql_Parser_Interface
$sql->setState('Insert'); $sql->setState('Insert');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Lock implements Msd_Sql_Parser_Interface
$sql->setState('Lock'); $sql->setState('Lock');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Select implements Msd_Sql_Parser_Interface
$sql->setState('Select'); $sql->setState('Select');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }

Datei anzeigen

@ -30,7 +30,6 @@ class Msd_Sql_Parser_Statement_Unlock implements Msd_Sql_Parser_Interface
$sql->setState('Unlock'); $sql->setState('Unlock');
$endOfStatement = $sql->getPosition(';'); $endOfStatement = $sql->getPosition(';');
$statement = $sql->getData($endOfStatement); $statement = $sql->getData($endOfStatement);
$sql->setPointer($endOfStatement);
return $statement; return $statement;
} }
} }