Skip to content

Commit

Permalink
Update test according to main PR (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov authored Apr 12, 2024
1 parent 104ec81 commit fc7567b
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 8 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# PostgreSQL driver for Yii Database Change Log

## 1.3.1 under development
## 2.0.0 under development

- no changes in this release.
- Enh #336: Implement `SqlParser` and `ExpressionBuilder` driver classes (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
5 changes: 4 additions & 1 deletion rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
/**
* Disabled ./tests directory due to different branches with main package when testing
*/
// __DIR__ . '/tests',
]);

// register a single rule
Expand Down
16 changes: 16 additions & 0 deletions src/Builder/ExpressionBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Pgsql\Builder;

use Yiisoft\Db\Expression\AbstractExpressionBuilder;
use Yiisoft\Db\Pgsql\SqlParser;

final class ExpressionBuilder extends AbstractExpressionBuilder
{
protected function createSqlParser(string $sql): SqlParser
{
return new SqlParser($sql);
}
}
3 changes: 3 additions & 0 deletions src/DQLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
namespace Yiisoft\Db\Pgsql;

use Yiisoft\Db\Expression\ArrayExpression;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Expression\ExpressionBuilderInterface;
use Yiisoft\Db\Expression\JsonExpression;
use Yiisoft\Db\Pgsql\Builder\ArrayExpressionBuilder;
use Yiisoft\Db\Pgsql\Builder\StructuredExpressionBuilder;
use Yiisoft\Db\Pgsql\Builder\ExpressionBuilder;
use Yiisoft\Db\Pgsql\Builder\JsonExpressionBuilder;
use Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder;
use Yiisoft\Db\QueryBuilder\Condition\LikeCondition;
Expand Down Expand Up @@ -52,6 +54,7 @@ protected function defaultExpressionBuilders(): array
ArrayExpression::class => ArrayExpressionBuilder::class,
JsonExpression::class => JsonExpressionBuilder::class,
StructuredExpression::class => StructuredExpressionBuilder::class,
Expression::class => ExpressionBuilder::class,
]);
}
}
87 changes: 87 additions & 0 deletions src/SqlParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Pgsql;

use Yiisoft\Db\Syntax\AbstractSqlParser;

final class SqlParser extends AbstractSqlParser
{
public function getNextPlaceholder(int|null &$position = null): string|null
{
$result = null;
$length = $this->length - 1;

while ($this->position < $length) {
$pos = $this->position++;

match ($this->sql[$pos]) {
':' => ($word = $this->parseWord()) === ''
? $this->skipChars(':')
: $result = ':' . $word,
'"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]),
'e', 'E' => $this->sql[$this->position] === "'"

Check warning on line 24 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "Identical": --- Original +++ New @@ @@ match ($this->sql[$pos]) { ':' => ($word = $this->parseWord()) === '' ? $this->skipChars(':') : ($result = ':' . $word), '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), - 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), + 'e', 'E' => $this->sql[$this->position] !== "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null,

Check warning on line 24 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "Ternary": --- Original +++ New @@ @@ match ($this->sql[$pos]) { ':' => ($word = $this->parseWord()) === '' ? $this->skipChars(':') : ($result = ':' . $word), '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), - 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), + 'e', 'E' => $this->sql[$this->position] === "'" ? $this->skipIdentifier() : ++$this->position && $this->skipQuotedWithEscape("'"), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null,
? ++$this->position && $this->skipQuotedWithEscape("'")

Check warning on line 25 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndNegation": --- Original +++ New @@ @@ match ($this->sql[$pos]) { ':' => ($word = $this->parseWord()) === '' ? $this->skipChars(':') : ($result = ':' . $word), '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), - 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), + 'e', 'E' => $this->sql[$this->position] === "'" ? !(++$this->position && $this->skipQuotedWithEscape("'")) : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null,

Check warning on line 25 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndSingleSubExprNegation": --- Original +++ New @@ @@ match ($this->sql[$pos]) { ':' => ($word = $this->parseWord()) === '' ? $this->skipChars(':') : ($result = ':' . $word), '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), - 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), + 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && !$this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null,
: $this->skipIdentifier(),
'$' => $this->skipQuotedWithDollar(),
'-' => $this->sql[$this->position] === '-'
? ++$this->position && $this->skipToAfterChar("\n")

Check warning on line 29 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "Increment": --- Original +++ New @@ @@ '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), - '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, + '-' => $this->sql[$this->position] === '-' ? --$this->position && $this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null, // Identifiers can contain dollar sign which can be used for quoting. Skip them. '_', 'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(),

Check warning on line 29 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndNegation": --- Original +++ New @@ @@ '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), - '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, + '-' => $this->sql[$this->position] === '-' ? !(++$this->position && $this->skipToAfterChar("\n")) : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null, // Identifiers can contain dollar sign which can be used for quoting. Skip them. '_', 'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(),

Check warning on line 29 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndSingleSubExprNegation": --- Original +++ New @@ @@ '"', "'" => $this->skipQuotedWithoutEscape($this->sql[$pos]), 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), - '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, + '-' => $this->sql[$this->position] === '-' ? ++$this->position && !$this->skipToAfterChar("\n") : null, '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null, // Identifiers can contain dollar sign which can be used for quoting. Skip them. '_', 'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(),
: null,
'/' => $this->sql[$this->position] === '*'
? ++$this->position && $this->skipToAfterString('*/')

Check warning on line 32 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "Increment": --- Original +++ New @@ @@ 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, - '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null, + '/' => $this->sql[$this->position] === '*' ? --$this->position && $this->skipToAfterString('*/') : null, // Identifiers can contain dollar sign which can be used for quoting. Skip them. '_', 'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(), default => null,

Check warning on line 32 in src/SqlParser.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndNegation": --- Original +++ New @@ @@ 'e', 'E' => $this->sql[$this->position] === "'" ? ++$this->position && $this->skipQuotedWithEscape("'") : $this->skipIdentifier(), '$' => $this->skipQuotedWithDollar(), '-' => $this->sql[$this->position] === '-' ? ++$this->position && $this->skipToAfterChar("\n") : null, - '/' => $this->sql[$this->position] === '*' ? ++$this->position && $this->skipToAfterString('*/') : null, + '/' => $this->sql[$this->position] === '*' ? !(++$this->position && $this->skipToAfterString('*/')) : null, // Identifiers can contain dollar sign which can be used for quoting. Skip them. '_', 'a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(), default => null,
: null,
// Identifiers can contain dollar sign which can be used for quoting. Skip them.
'_','a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' => $this->skipIdentifier(),
default => null,
};

if ($result !== null) {
$position = $pos;

return $result;
}
}

return null;
}

/**
* Skips dollar-quoted string.
*/
private function skipQuotedWithDollar(): void
{
$pos = $this->position;
$identifier = $this->parseIdentifier();

if ($this->sql[$this->position] !== '$') {
$this->position = $pos;
return;
}

++$this->position;

$this->skipToAfterString('$' . $identifier . '$');
}

/**
* Skips an identifier. Equals to `[$\w]+` in regular expressions.
*/
private function skipIdentifier(): void
{
$continue = true;

while ($continue && $this->position < $this->length) {
match ($this->sql[$this->position]) {
'$', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z' => ++$this->position,
default => $continue = false,
};
}
}
}
5 changes: 3 additions & 2 deletions tests/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,10 @@ public function testUpdate(
array $columns,
array|string $conditions,
array $params,
string $expected
array $expectedValues,
int $expectedCount,
): void {
parent::testUpdate($table, $columns, $conditions, $params, $expected);
parent::testUpdate($table, $columns, $conditions, $params, $expectedValues, $expectedCount);
}

/**
Expand Down
50 changes: 50 additions & 0 deletions tests/Provider/SqlParserProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Pgsql\Tests\Provider;

class SqlParserProvider extends \Yiisoft\Db\Tests\Provider\SqlParserProvider
{
public static function getNextPlaceholder(): array
{
return [
...parent::getNextPlaceholder(),
[
"name = e':name' AND age = :age",
':age',
26,
],
[
"name = E':name' AND age = :age",
':age',
26,
],
[
"name = E':name' AND age = :age",
':age',
26,
],
[
'name = $$:name$$ AND age = :age',
':age',
27,
],
[
'name = $q$:name$q$ AND age = :age',
':age',
29,
],
[
'name = $name AND age = :age',
':age',
23,
],
[
'name = name$1$ AND age = :age',
':age',
25,
],
];
}
}
7 changes: 4 additions & 3 deletions tests/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,11 @@ public function testUpdate(
string $table,
array $columns,
array|string $condition,
string $expectedSQL,
array $expectedParams
array $params,
string $expectedSql,
array $expectedParams,
): void {
parent::testUpdate($table, $columns, $condition, $expectedSQL, $expectedParams);
parent::testUpdate($table, $columns, $condition, $params, $expectedSql, $expectedParams);
}

/**
Expand Down
25 changes: 25 additions & 0 deletions tests/SqlParserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Pgsql\Tests;

use Yiisoft\Db\Pgsql\SqlParser;
use Yiisoft\Db\Tests\AbstractSqlParserTest;

/**
* @group pgsql
*/
final class SqlParserTest extends AbstractSqlParserTest
{
protected function createSqlParser(string $sql): SqlParser
{
return new SqlParser($sql);
}

/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\SqlParserProvider::getNextPlaceholder */
public function testGetNextPlaceholder(string $sql, string|null $expectedPlaceholder, int|null $expectedPosition): void
{
parent::testGetNextPlaceholder($sql, $expectedPlaceholder, $expectedPosition);
}
}

0 comments on commit fc7567b

Please sign in to comment.