From d2df23f1f4ef62d3109cffd3796d782596c32d67 Mon Sep 17 00:00:00 2001 From: Bao Pham Date: Sun, 13 Aug 2017 01:05:29 +0800 Subject: [PATCH] Add whereIn support Close #39 --- src/ComparisonOperator.php | 6 +++++ src/DynamoDbModel.php | 1 - src/DynamoDbQueryBuilder.php | 44 +++++++++++++++++++++++++++++++++++- tests/DynamoDbModelTest.php | 16 +++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/ComparisonOperator.php b/src/ComparisonOperator.php index 277f5cc..3c957e2 100644 --- a/src/ComparisonOperator.php +++ b/src/ComparisonOperator.php @@ -87,4 +87,10 @@ public static function isValidQueryDynamoDbOperator($dynamoDbOperator, $isRangeK { return in_array($dynamoDbOperator, static::getQuerySupportedOperators($isRangeKey)); } + + public static function is($op, $opToCompare) + { + $mapping = static::getOperatorMapping(); + return $mapping[strtolower($op)] === $opToCompare; + } } diff --git a/src/DynamoDbModel.php b/src/DynamoDbModel.php index b80b9d1..f419adf 100644 --- a/src/DynamoDbModel.php +++ b/src/DynamoDbModel.php @@ -49,7 +49,6 @@ abstract class DynamoDbModel extends Model */ protected $dynamoDbIndexKeys = []; - /** * Array of your composite key. * ['hash', 'range'] diff --git a/src/DynamoDbQueryBuilder.php b/src/DynamoDbQueryBuilder.php index 62452c9..eb50326 100644 --- a/src/DynamoDbQueryBuilder.php +++ b/src/DynamoDbQueryBuilder.php @@ -3,7 +3,9 @@ namespace BaoPham\DynamoDb; use Aws\DynamoDb\DynamoDbClient; +use Closure; use Exception; +use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Eloquent\Collection; use \Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Facades\Log; @@ -116,7 +118,10 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' $valueList = [$attributeValueList['AttributeValueList']]; - if (strtolower($operator) === 'between') { + if ( + ComparisonOperator::is($operator, ComparisonOperator::BETWEEN) || + ComparisonOperator::is($operator, ComparisonOperator::IN) + ) { $valueList = head($valueList)['L']; } @@ -128,6 +133,43 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' return $this; } + /** + * Add a "where in" clause to the query. + * + * @param string $column + * @param mixed $values + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereIn($column, $values, $boolean = 'and', $not = false) + { + if ($boolean != 'and') { + throw new NotSupportedException('Only support "and" in whereIn clause'); + } + + if ($not) { + throw new NotSupportedException('"not in" is not a valid DynamoDB comparison operator'); + } + + // If the value is a query builder instance, not supported + if ($values instanceof static) { + throw new NotSupportedException('Value is a query builder instance'); + } + + // If the value of the where in clause is actually a Closure, not supported + if ($values instanceof Closure) { + throw new NotSupportedException('Value is a Closure'); + } + + // Next, if the value is Arrayable we need to cast it to its raw array form + if ($values instanceof Arrayable) { + $values = $values->toArray(); + } + + return $this->where($column, ComparisonOperator::IN, $values); + } + /** * Implements the Query Chunk method * diff --git a/tests/DynamoDbModelTest.php b/tests/DynamoDbModelTest.php index 56173cd..a9ff7d1 100644 --- a/tests/DynamoDbModelTest.php +++ b/tests/DynamoDbModelTest.php @@ -380,6 +380,22 @@ public function testDifferentQueries() $this->assertEquals($this->testModel->unmarshalItem($expectedBar), $barQuery->first()->toArray()); } + public function testWhereIn() + { + $this->seed(['name' => ['S' => 'foo']]); + $this->seed(['name' => ['S' => 'foo']]); + $this->seed(['name' => ['S' => 'bar']]); + $this->seed(['name' => ['S' => 'foobar']]); + + $items = $this->testModel->whereIn('name', ['foo', 'bar'])->get(); + + $this->assertCount(3, $items->toArray()); + + foreach ($items as $item) { + $this->assertContains($item->name, ['foo', 'bar']); + } + } + public function testChunkScan() { $this->seed(['name' => ['S' => 'Foo']]);