From 5325de6a5349ac0e0a940696afe0ab54de7e697a Mon Sep 17 00:00:00 2001 From: Bas Date: Mon, 22 Nov 2021 19:25:46 +0100 Subject: [PATCH] Bind expressions contain their data; even when added to a new query as an expression --- src/Expressions/BindExpression.php | 33 +++++++++++++++ src/Expressions/LiteralExpression.php | 2 +- src/QueryBuilder.php | 2 +- src/Traits/NormalizesExpressions.php | 15 ++++++- tests/Unit/Expressions/BindExpressionTest.php | 40 +++++++++++++++++++ tests/Unit/SubqueryTest.php | 1 + 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 tests/Unit/Expressions/BindExpressionTest.php diff --git a/src/Expressions/BindExpression.php b/src/Expressions/BindExpression.php index 68651b9..50a67e5 100644 --- a/src/Expressions/BindExpression.php +++ b/src/Expressions/BindExpression.php @@ -4,9 +4,42 @@ namespace LaravelFreelancerNL\FluentAQL\Expressions; +use LaravelFreelancerNL\FluentAQL\QueryBuilder; + /** * AQL literal expression. */ class BindExpression extends LiteralExpression implements ExpressionInterface { + protected string $bindVariable; + + protected mixed $data = null; + + public function __construct(string $bindVariable, mixed $data = null) + { + $this->bindVariable = $bindVariable; + + $this->data = $data; + } + + /** + * Compile expression output. + * + * @param QueryBuilder $queryBuilder + * @return string + */ + public function compile(QueryBuilder $queryBuilder): string + { + return $this->bindVariable; + } + + public function getBindVariable(): string + { + return $this->bindVariable; + } + + public function getData(): mixed + { + return $this->data; + } } diff --git a/src/Expressions/LiteralExpression.php b/src/Expressions/LiteralExpression.php index ddcef9d..9275dac 100644 --- a/src/Expressions/LiteralExpression.php +++ b/src/Expressions/LiteralExpression.php @@ -17,7 +17,7 @@ class LiteralExpression extends Expression implements ExpressionInterface * @param QueryBuilder $queryBuilder * @return string */ - public function compile(QueryBuilder $queryBuilder = null): string + public function compile(QueryBuilder $queryBuilder): string { return (string) $this->expression; } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index c017902..fbc60f5 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -203,7 +203,7 @@ public function bind( $to = $this->grammar->formatBind($to, false); - return new BindExpression($to); + return new BindExpression($to, $data); } /** diff --git a/src/Traits/NormalizesExpressions.php b/src/Traits/NormalizesExpressions.php index cdc81cb..31ead51 100644 --- a/src/Traits/NormalizesExpressions.php +++ b/src/Traits/NormalizesExpressions.php @@ -18,7 +18,6 @@ trait NormalizesExpressions { - /** * @param object|array|string|int|float|bool|null $data */ @@ -36,6 +35,8 @@ public function normalizeArgument( array|string $allowedExpressionTypes = null ): Expression { if ($argument instanceof Expression) { + $argument = $this->processBindExpression($argument); + return $argument; } @@ -266,4 +267,16 @@ protected function normalizeObject( return new ObjectExpression($this->normalizeIterable((array) $argument, $allowedExpressionTypes)); } + + public function processBindExpression(Expression $argument): Expression + { + if ($argument instanceof BindExpression) { + $bindKey = ltrim($argument->getBindVariable(), '@'); + + if (!isset($this->binds[$bindKey])) { + $this->binds[$bindKey] = $argument->getData(); + } + } + return $argument; + } } diff --git a/tests/Unit/Expressions/BindExpressionTest.php b/tests/Unit/Expressions/BindExpressionTest.php new file mode 100644 index 0000000..399ea65 --- /dev/null +++ b/tests/Unit/Expressions/BindExpressionTest.php @@ -0,0 +1,40 @@ +compile($qb); + + self::assertEquals($bindVar, $result); + self::assertEquals($data, $expression->getData()); + } + + public function testBindExpressionIsAddedToNewQuery() + { + $bindVar = '@myBind'; + $data = 'test'; + $bindExpression = new BindExpression($bindVar, $data); + + $qb = (new QueryBuilder())->filter('test', '==', $bindExpression); + $qb->get(); + + $this->assertCount(1, $qb->binds); + $this->assertSame($data, array_shift($qb->binds)); + } +} diff --git a/tests/Unit/SubqueryTest.php b/tests/Unit/SubqueryTest.php index 744914b..c56c835 100644 --- a/tests/Unit/SubqueryTest.php +++ b/tests/Unit/SubqueryTest.php @@ -44,6 +44,7 @@ public function testSubQueryWithBinds() ->filter('u.active', '==', 'something to bind') ->return('u._key') ->get(); + self::assertEquals( 'FOR u IN users FILTER u.active == @' . $subQuery->getQueryId() . '_1 RETURN u._key', $subQuery->query