Skip to content

Commit

Permalink
Merge pull request #141 from JLacoude/regexp-begone
Browse files Browse the repository at this point in the history
Removing all calls to capture
  • Loading branch information
Paul M. Jones authored Jan 22, 2017
2 parents e8307ed + 85c0df1 commit 16c0715
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 34 deletions.
11 changes: 9 additions & 2 deletions src/Parser/AbstractParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,15 @@ protected function handleNumberedParameter($state)
*/
protected function handleSemiColon($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 @@ -90,10 +90,22 @@ protected function handlePossibleCStyleString($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 @@ -110,7 +122,17 @@ protected function handlePossibleCStyleString($state)
*/
protected function handleDollar($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
58 changes: 31 additions & 27 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 @@ -154,6 +162,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 @@ -314,34 +332,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;
}
$regexp = "/\G{$regexp}/u";
if (preg_match_all(
$regexp,
$this->statement,
$matches,
PREG_SET_ORDER,
$this->current_index
)) {
$capture = isset($matches[$capture_group][0]) ? $matches[$capture_group][0] : '';
$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
12 changes: 10 additions & 2 deletions tests/Parser/PgsqlParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ public function testCStyleStringConstants()
$this->assertEquals($sql, $parsedQuery->getString());

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

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

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

public function testTypeCasting()
Expand Down

0 comments on commit 16c0715

Please sign in to comment.