Skip to content

Commit

Permalink
reapply #141, as I seem to have reintroduced mb_ereg again from somew…
Browse files Browse the repository at this point in the history
…here
  • Loading branch information
Paul M. Jones committed Jan 23, 2017
2 parents f054d65 + 16c0715 commit 419904e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 30 deletions.
13 changes: 10 additions & 3 deletions src/Parser/AbstractParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private function storeQuery(State $state, &$queries)
*/
private function isStatementEmpty($statement)
{
return mb_ereg_match('^\\s*$', $statement);
return trim($statement) === '';
}

/**
Expand Down Expand Up @@ -244,8 +244,15 @@ protected function handleNumberedParameter(State $state)
*/
protected function handleSemiColon(State $state)
{
$uselessCharacters = $state->capture(';\\s*');
$state->passString($uselessCharacters);
while (! $state->done())
{
$character = $state->getCurrentCharacter();
if (! in_array($character, array(';', "\r", "\n", "\t", " "), true))
{
break;
}
$state->passString($character);
}
$state->setNewStatementCharacterFound(true);
}

Expand Down
28 changes: 25 additions & 3 deletions src/Parser/PgsqlParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,22 @@ protected function handlePossibleCStyleString(State $state)
}
if (! $inCString) {
// Checking if we have blank characters until next quote. In which case it is the same string
$blanks = $state->capture("\\s*'");
$offset = 1;
$blanks = true;
while (! $state->done()) {
$characterAtOffset = $state->getCharacterFromCurrent($offset);
if ($characterAtOffset === "'") {
break;
}
if (! in_array($characterAtOffset, array(" ", "\n", "\r", "\t"), true)) {
$blanks = false;
break;
}
$offset ++;
}
if ($blanks) {
$state->copyUntilCharacter("'");
$state->copyCurrentCharacter();
$state->copyUntilCharacter("'");
$inCString = true;
}
}
Expand All @@ -111,7 +123,17 @@ protected function handlePossibleCStyleString(State $state)
*/
protected function handleDollar(State $state)
{
$identifier = $state->capture('\\$([a-zA-Z_]\\w*)*\\$');
$identifier = '$';
$offset = 1;
while (! $state->done()) {
$character = $state->getCharacterFromCurrent($offset);
$identifier .= $character;
if ($character === '$') {
break;
}
$offset ++;
}

if ($identifier) {
// Copy until the end of the starting tag
$state->copyUntilCharacter($identifier);
Expand Down
53 changes: 30 additions & 23 deletions src/Parser/State.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class State
*/
protected $new_statement_character_found = false;

protected $valid_placeholder_characters = [];

/**
*
* Constructor
Expand All @@ -90,6 +92,12 @@ public function __construct($statement, $values = array(), $charset = 'UTF-8')
if (array_key_exists(0, $this->values)) {
array_unshift($this->values, null);
}
$this->valid_placeholder_characters = array_merge(
range('a', 'z'),
range ('A', 'Z'),
range (0, 9),
array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_')
);
}

/**
Expand Down Expand Up @@ -162,6 +170,16 @@ public function getCurrentCharacter()
return mb_substr($this->statement, $this->current_index, 1, $this->charset);
}

/**
* Returns the character $n position after the current character
* @param $n
* @return string
*/
public function getCharacterFromCurrent($n)
{
return mb_substr($this->statement, $this->current_index + $n, 1, $this->charset);
}

/**
*
* Returns the modified SQL query
Expand Down Expand Up @@ -321,31 +339,20 @@ public function getCharset()
*/
public function getIdentifier()
{
return $this->capture('\\w+\\b');
}

/**
*
* Tries to matche a regular expression starting at current index and returns the result
*
* @param string $regexp
* @param int $capture_group
* @return string
*/
public function capture($regexp, $capture_group = 0)
{
$capture = '';
if ($this->last_index <= $this->current_index) {
return $capture;
}
mb_regex_encoding($this->charset);
if (mb_ereg_search_init($this->statement) !== false) {
mb_ereg_search_setpos($this->current_index);
if ($matches = mb_ereg_search_regs('\\G' . $regexp)) {
$capture = isset($matches[$capture_group]) ? $matches[$capture_group] : '';
$identifier = '';
$length = 0;
while (! $this->done())
{
$character = mb_substr($this->statement, $this->current_index + $length, 1, $this->charset);
if (! in_array($character, $this->valid_placeholder_characters, true))
{
return $identifier;
}
$identifier .= $character;
$length++;

}
return $capture;
return $identifier;
}

/**
Expand Down
10 changes: 9 additions & 1 deletion tests/Parser/PgsqlParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public function testCStyleStringConstants()

$sql = <<<SQL
SELECT E'Multiline'
'C-style escaping \' :foo \''
'C-style escaping \' :foo \' :foo'
SQL;
$parsedQuery = $this->parseSingleQuery($sql, $parameters);
$this->assertEquals($sql, $parsedQuery->getStatement());
Expand Down Expand Up @@ -206,6 +206,14 @@ public function testDollarQuotedStrings()
$sql = 'SELECT $outer$ nested strings $inner$:foo$inner$ $outer$';
$parsedQuery = $this->parseSingleQuery($sql, $parameters);
$this->assertEquals($sql, $parsedQuery->getStatement());

$sql = 'SELECT $€$hello$€$';
$parsedQuery = $this->parseSingleQuery($sql, $parameters);
$this->assertEquals($sql, $parsedQuery->getStatement());

$sql = 'SELECT $€$hello$€';
$parsedQuery = $this->parseSingleQuery($sql, $parameters);
$this->assertEquals($sql, $parsedQuery->getStatement());
}

public function testTypeCasting()
Expand Down

0 comments on commit 419904e

Please sign in to comment.