1
0
Fork 0
MySQLDumper/library/Msd/Sql/Parser.php

222 Zeilen
5.6 KiB
PHP

<?php
/**
* This file is part of MySQLDumper released under the GNU/GPL 2 license
* http://www.mysqldumper.net
*
* @package MySQLDumper
* @subpackage SQL-Parser
* @version SVN: $Rev$
* @author $Author$
*/
/**
* Class to parse MySQL queries.
* This enables you to analyze and modify MySQL queries, which the user has entered.
*
* @package MySQLDumper
* @subpackage SQL-Browser
*/
class Msd_Sql_Parser implements Iterator
{
/**
* Saves the raw MySQL Query.
*
* @var string
*/
private $_rawQuery = null;
/**
* Parsed MySQL statements.
*
* @var array
*/
private $_parsedStatements = array();
/**
* Holds the summary of the parsing process.
* The summary contains the count of each statement in the query.
*
* @var array
*/
private $_parsingSummary = array();
/**
* MySQL comment types.
*
* @var array
*/
protected $_sqlComments = array(
'--' => "\n", '/*' => '*/', '/*!' => '*/'
);
/**
* Whether to save debug output
*
* @var bool
*/
private $_debug = false;
/**
* Debug output buffer
*
* @var string
*/
private $_debugOutput = '';
/**
* Class constructor.
* Creates a new instance of the MySQL parser and optionally assign the raw MySQL query.
*
* @param Msd_Sql_Object $sqlObject SQL-Object holding the data to be parsed
* @param bool $debug If turned on, detection of queries is logged
*/
public function __construct(Msd_Sql_Object $sqlObject, $debug = false)
{
$this->_sql = $sqlObject;
$this->_debug = $debug;
}
/**
* Parses a raw MySQL query.
* This could include more than one MySQL statement.
*
* @throws Msd_Sql_Parser_Exception
*
* @return void
*/
public function parse()
{
// get first characters to extract the kind of query we have to process
$statementCounter = 0;
while ($this->_sql->hasMoreToProcess()) {
$this->_sql->movePointerToNextCommand();
$endOfCommand = $this->_sql->getPosition(' ');
$sqlQuery = $this->_sql->getData($endOfCommand);
//echo "<br>Query beginn: ".$sqlQuery;
$parts = explode(' ', $sqlQuery);
$statement = strtolower($parts[0]);
// check for comments or conditional comments
$commentCheck = substr($sqlQuery, 0, 2);
if (isset($this->_sqlComments[$commentCheck]) || substr($statement, 0, 3) == '/*!') {
$statement = 'Comment';
}
$foundStatement = $this->_parseStatement($this->_sql, ucwords($statement));
if ($this->_debug) {
$this->_debugOutput .= '<br />Extracted statement: '.$foundStatement;
}
$this->_parsedStatements[] = $foundStatement;
$statementCounter++;
// increment query type counter
if (!isset($this->_parsingSummary[$statement])) {
$this->_parsingSummary[$statement] = 0;
}
$this->_parsingSummary[$statement]++;
}
}
/**
* Creates an instance of a statement parser class and invokes statement parsing.
*
* @throws Msd_Sql_Parser_Exception
*
* @param Msd_Sql_Object $sqlObject MySQL statement to parse
* @param string $statement Parser class to use
*
* @return array
*/
private function _parseStatement(Msd_Sql_Object $sqlObject, $statement)
{
$statementPath = '/Msd/Sql/Parser/Statement/' . $statement;
if ($statement !== 'Select') die("Not implemented yet: ".$statement);
if (!file_exists(LIBRARY_PATH . $statementPath . '.php')) {
throw new Msd_Sql_Parser_Exception("Can't find statement class for statement: " . $statement);
}
$statementClass = 'Msd_Sql_Parser_Statement_' . $statement;
$parserObject = new $statementClass;
return $parserObject->parse($sqlObject);
}
/**
* Returns the array with the parsed statements.
*
* @return array
*/
public function getParsedStatements()
{
return $this->_parsedStatements;
}
/**
* Returns the parsing summary.
*
* @return array
*/
public function getSummary()
{
return $this->_parsingSummary;
}
/**
* Rewind (reset) the internal pointer position af the parsed statements array.
*
* @return mixed
*/
public function rewind()
{
return reset($this->_parsedStatements);
}
/**
* Return the current value af the parsed statements array.
*
* @return mixed
*/
public function current()
{
return current($this->_parsedStatements);
}
/**
* Return the current key af the parsed statements array.
*
* @return mixed
*/
public function key()
{
return key($this->_parsedStatements);
}
/**
* Move the internal pointer af the parsed statements array to the next position.
*
* @return mixed
*/
public function next()
{
return next($this->_parsedStatements);
}
/**
* Validates the internal pointer position af the parsed statements array.
*
* @return bool
*/
public function valid()
{
return key($this->_parsedStatements) !== null;
}
/**
* Get debug output buffer
*
* @return array
*/
public function getDebugOutput()
{
return $this->_debugOutput;
}
}