Skip to content

Commit 0948287

Browse files
committed
Add ability to decorate query
1 parent 7050232 commit 0948287

File tree

5 files changed

+102
-5
lines changed

5 files changed

+102
-5
lines changed

README.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Supports all key types - primary hash key and composite keys.
2727
* [findOrFail()](#findorfail)
2828
* [Query scope](#query-scope)
2929
* [REMOVE — Deleting Attributes From An Item](#remove--deleting-attributes-from-an-item)
30-
* [toSql() style](#tosql-style)
30+
* [toSql() Style](#tosql-style)
31+
* [Decorate Query](#decorate-query)
3132
* [Indexes](#indexes)
3233
* [Composite Keys](#composite-keys)
3334
* [Requirements](#requirements)
@@ -258,19 +259,49 @@ Model::find('foo')->removeAttribute('name', 'description', 'nested.foo', 'nested
258259
```
259260
260261
261-
#### toSql() style
262+
#### toSql() Style
262263
263264
For debugging purposes, you can choose to convert to the actual DynamoDb query
264265
265266
```php
266267
$raw = $model->where('count', '>', 10)->toDynamoDbQuery();
268+
// $op is either "Scan" or "Query"
267269
$op = $raw->op;
270+
// The query body being sent to AWS
268271
$query = $raw->query;
269272
```
270273
271-
where `$op` will be either `Scan` or `Query` and `$query` will be the query body being sent to AWS.
274+
where `$raw` is an instance of [RawDynamoDbQuery](./src/RawDynamoDbQuery.php)
272275
273276
277+
#### Decorate Query
278+
279+
Use `decorate` when you want to enhance the query. For example:
280+
281+
To set the order of the sort key:
282+
283+
```php
284+
$items = $model
285+
->where('hash', 'hash-value')
286+
->where('range', '>', 10)
287+
->decorate(function (RawDynamoDbQuery $raw) {
288+
// desc order
289+
$raw->query['ScanIndexForward'] = false;
290+
})
291+
->get();
292+
```
293+
294+
To force to use "Query" instead of "Scan" if the library fails to detect the correct operation:
295+
296+
```php
297+
$items = $model
298+
->where('hash', 'hash-value')
299+
->decorate(function (RawDynamoDbQuery $raw) {
300+
$raw->op = 'Query';
301+
})
302+
->get();
303+
```
304+
274305
Indexes
275306
-----------
276307
If your table has indexes, make sure to declare them in your model class like so

src/DynamoDbQueryBuilder.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class DynamoDbQueryBuilder
3838
*/
3939
protected $client;
4040

41+
/**
42+
* @var Closure
43+
*/
44+
protected $decorator;
45+
4146
/**
4247
* Applied global scopes.
4348
*
@@ -557,6 +562,12 @@ public function count()
557562
return $this->getAll($this->model->getKeyNames())->count();
558563
}
559564

565+
public function decorate(Closure $closure)
566+
{
567+
$this->decorator = $closure;
568+
return $this;
569+
}
570+
560571
protected function getAll(
561572
$columns = [],
562573
$limit = DynamoDbQueryBuilder::MAX_LIMIT,
@@ -572,6 +583,10 @@ protected function getAll(
572583

573584
$raw = $this->toDynamoDbQuery($columns, $limit);
574585

586+
if ($this->decorator) {
587+
call_user_func($this->decorator, $raw);
588+
}
589+
575590
if ($useIterator) {
576591
$iterator = $this->client->getIterator($raw->op, $raw->query);
577592

src/RawDynamoDbQuery.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
class RawDynamoDbQuery implements \IteratorAggregate, \ArrayAccess, \Countable
1111
{
1212
/**
13+
* Either 'Scan', or 'Query'
14+
*
1315
* @var string
1416
*/
1517
public $op;
1618

1719
/**
20+
* The query body being sent to AWS
21+
*
1822
* @var array
1923
*/
2024
public $query;

tests/DynamoDbCompositeModelTest.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace BaoPham\DynamoDb\Tests;
44

55
use BaoPham\DynamoDb\NotSupportedException;
6+
use BaoPham\DynamoDb\RawDynamoDbQuery;
67
use \Illuminate\Database\Eloquent\ModelNotFoundException;
78

89
/**
@@ -384,7 +385,7 @@ public function testRemoveAttributesOnModel()
384385

385386
public function testAfterForQueryOperation()
386387
{
387-
for ($i = 0; $i < 10; $i++) {
388+
foreach (range(0, 9) as $i) {
388389
$this->seed(['count' => ['N' => $i]]);
389390
}
390391

@@ -405,6 +406,29 @@ public function testAfterForQueryOperation()
405406
$this->assertEquals(range(0, 9), $paginationResult->sort()->values()->toArray());
406407
}
407408

409+
public function testDecorateRawQuery()
410+
{
411+
foreach (range(0, 9) as $i) {
412+
$this->seed(['id' => ['S' => 'id'], 'count' => ['N' => $i]]);
413+
}
414+
415+
$query = $this->testModel
416+
->where('id', 'id')
417+
->where('count', '>=', 0);
418+
419+
$forward = $query->get();
420+
421+
$this->assertEquals(range(0, 9), $forward->pluck('count')->toArray());
422+
423+
$query->decorate(function (RawDynamoDbQuery $raw) {
424+
$raw->query['ScanIndexForward'] = false;
425+
});
426+
427+
$reverse = $query->get();
428+
429+
$this->assertEquals(range(9, 0, -1), $reverse->pluck('count')->toArray());
430+
}
431+
408432
public function seed($attributes = [], $exclude = [])
409433
{
410434
$item = [

tests/DynamoDbModelTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace BaoPham\DynamoDb\Tests;
44

55
use BaoPham\DynamoDb\NotSupportedException;
6+
use BaoPham\DynamoDb\RawDynamoDbQuery;
67
use \Illuminate\Database\Eloquent\ModelNotFoundException;
78

89
/**
@@ -721,7 +722,7 @@ public function testAfterForQueryOperation()
721722

722723
public function testAfterForScanOperation()
723724
{
724-
for ($i = 0; $i < 10; $i++) {
725+
foreach (range(0, 9) as $i) {
725726
$this->seed(['count' => ['N' => $i]]);
726727
}
727728

@@ -741,6 +742,28 @@ public function testAfterForScanOperation()
741742
$this->assertEquals(range(0, 9), $paginationResult->sort()->values()->toArray());
742743
}
743744

745+
public function testDecorateRawQuery()
746+
{
747+
foreach (range(0, 9) as $i) {
748+
$this->seed(['count' => ['N' => $i]]);
749+
}
750+
751+
$items = $this->testModel
752+
->decorate(function (RawDynamoDbQuery $raw) {
753+
$raw->op = 'Scan';
754+
$raw->query['FilterExpression'] = '#count > :count';
755+
$raw->query['ExpressionAttributeNames'] = [
756+
'#count' => 'count'
757+
];
758+
$raw->query['ExpressionAttributeValues'] = [
759+
':count' => ['N' => 0],
760+
];
761+
})
762+
->get();
763+
764+
$this->assertEquals(range(1, 9), $items->pluck('count')->sort()->values()->toArray());
765+
}
766+
744767
protected function assertRemoveAttributes($item)
745768
{
746769
$this->assertNull($item->name);

0 commit comments

Comments
 (0)