Skip to content

Commit a2c880c

Browse files
committed
Support updateItem
1 parent c60cc50 commit a2c880c

File tree

4 files changed

+209
-2
lines changed

4 files changed

+209
-2
lines changed

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,34 @@ $item = DB::table('Thread')
125125

126126
#### UpdateItem
127127

128-
We didn't implement this yet.
128+
Currently, we only support simple SET and REMOVE actions.
129+
130+
If value is set, `updateItem` will SET them.
131+
132+
```php
133+
DB::table('Thread')
134+
->key([
135+
'ForumName' => 'Laravel',
136+
'Subject' => 'Laravel Thread 1'
137+
])->updateItem([
138+
'LastPostedBy' => 'User A', // SET
139+
'Replies' => 1 // SET
140+
]);
141+
```
142+
143+
If value is null, `updateItem` will REMOVE them.
144+
145+
```php
146+
DB::table('Thread')
147+
->key([
148+
'ForumName' => 'Laravel',
149+
'Subject' => 'Laravel Thread 1'
150+
])->updateItem([
151+
'LastPostedBy' => null, // REMOVE
152+
'Replies' => null, // REMOVE
153+
'Message' => 'Updated' // SET
154+
]);
155+
```
129156

130157
#### DeleteItem
131158

src/Kitar/Dynamodb/Query/Builder.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ class Builder extends BaseBuilder
3333
*/
3434
public $item = [];
3535

36+
/**
37+
* The key/values to update.
38+
*/
39+
public $updates = [
40+
'set' => [],
41+
'remove' => []
42+
];
43+
3644
/**
3745
* ConsistentRead option.
3846
* @var boolean|null
@@ -161,6 +169,7 @@ public function whereAs($condition_key_name)
161169

162170
/**
163171
* Get item.
172+
* @param array|null $key
164173
* @return Illuminate\Support\Collection|null
165174
*/
166175
public function getItem($key = null)
@@ -174,7 +183,8 @@ public function getItem($key = null)
174183

175184
/**
176185
* Put item.
177-
* @return \Aws\Result;
186+
* @param array $item
187+
* @return \Aws\Result
178188
*/
179189
public function putItem($item)
180190
{
@@ -185,6 +195,7 @@ public function putItem($item)
185195

186196
/**
187197
* Delete item.
198+
* @param array $key|null;
188199
* @return \Aws\Result;
189200
*/
190201
public function deleteItem($key)
@@ -196,6 +207,31 @@ public function deleteItem($key)
196207
return $this->process('deleteItem', null);
197208
}
198209

210+
/**
211+
* Update item.
212+
* @param mixed $item
213+
* @return void
214+
*/
215+
public function updateItem($item)
216+
{
217+
foreach ($item as $name => $value) {
218+
219+
$name = $this->expression_attributes->addName($name);
220+
221+
// If value is null, it will pass to REMOVE actions.
222+
if ($value === null) {
223+
$this->updates['remove'][] = $name;
224+
225+
// If value set, it will pass to SET actions.
226+
} else {
227+
$value = $this->expression_attributes->addValue($value);
228+
$this->updates['set'][] = "{$name} = {$value}";
229+
}
230+
}
231+
232+
return $this->process('updateItem', null);
233+
}
234+
199235
/**
200236
* Query.
201237
* @return Illuminate\Support\Collection
@@ -376,6 +412,7 @@ protected function process($query_method, $processor_method)
376412
$this->grammar->compileIndexName($this->index),
377413
$this->grammar->compileKey($this->key),
378414
$this->grammar->compileItem($this->item),
415+
$this->grammar->compileUpdates($this->updates),
379416
$this->grammar->compileConsistentRead($this->consistent_read),
380417
$this->grammar->compileExpressionAttributes($this->expression_attributes),
381418
);

src/Kitar/Dynamodb/Query/Grammar.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,32 @@ public function compileItem($item)
104104
];
105105
}
106106

107+
/**
108+
* Compile the Updates attribute.
109+
* @param array $updates
110+
* @return array
111+
*/
112+
public function compileUpdates($updates)
113+
{
114+
$expressions = [];
115+
116+
if (! empty($updates['set'])) {
117+
$expressions[] = 'set ' . implode(', ', $updates['set']);
118+
}
119+
120+
if (! empty($updates['remove'])) {
121+
$expressions[] = 'remove ' . implode(', ', $updates['remove']);
122+
}
123+
124+
if (empty($expressions)) {
125+
return [];
126+
}
127+
128+
return [
129+
'UpdateExpression' => implode(' ', $expressions)
130+
];
131+
}
132+
107133
/**
108134
* Compile the ConsistentRead attribute.
109135
* @param bool $bool

tests/Query/BuilderTest.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,123 @@ public function it_can_process_delete_item()
414414
$this->assertNull($query['processor']);
415415
}
416416

417+
/** @test */
418+
public function it_can_process_update_item()
419+
{
420+
$method = 'updateItem';
421+
$params = [
422+
'TableName' => 'Thread',
423+
'Key' => [
424+
'ForumName' => [
425+
'S' => 'Laravel'
426+
],
427+
'Subject' => [
428+
'S' => 'Laravel Thread 1'
429+
]
430+
],
431+
'UpdateExpression' => 'set #1 = :1, #2 = :2 remove #3, #4',
432+
'ExpressionAttributeNames' => [
433+
'#1' => 'LastPostedBy',
434+
'#2' => 'Replies',
435+
'#3' => 'Tags',
436+
'#4' => 'Views'
437+
],
438+
'ExpressionAttributeValues' => [
439+
':1' => [
440+
'S' => 'User A'
441+
],
442+
':2' => [
443+
'N' => '1'
444+
]
445+
]
446+
];
447+
448+
$query = $this->newQuery('Thread')
449+
->key([
450+
'ForumName' => 'Laravel',
451+
'Subject' => 'Laravel Thread 1'
452+
])->updateItem([
453+
'LastPostedBy' => 'User A',
454+
'Replies' => 1,
455+
'Tags' => null,
456+
'Views' => null
457+
]);
458+
459+
$this->assertEquals($method, $query['method']);
460+
$this->assertEquals($params, $query['params']);
461+
$this->assertNull($query['processor']);
462+
}
463+
464+
/** @test */
465+
public function it_can_set_single_attribute()
466+
{
467+
$query = $this->newQuery('Thread')
468+
->key([
469+
'ForumName' => 'Laravel',
470+
'Subject' => 'Laravel Thread 1'
471+
])->updateItem([
472+
'LastPostedBy' => 'User A',
473+
]);
474+
475+
$this->assertEquals(
476+
$query['params']['UpdateExpression'],
477+
'set #1 = :1'
478+
);
479+
}
480+
481+
/** @test */
482+
public function it_can_set_multiple_attributes()
483+
{
484+
$query = $this->newQuery('Thread')
485+
->key([
486+
'ForumName' => 'Laravel',
487+
'Subject' => 'Laravel Thread 1'
488+
])->updateItem([
489+
'LastPostedBy' => 'User A',
490+
'Replies' => 1,
491+
]);
492+
493+
$this->assertEquals(
494+
$query['params']['UpdateExpression'],
495+
'set #1 = :1, #2 = :2'
496+
);
497+
}
498+
499+
/** @test */
500+
public function it_can_remove_single_attribute()
501+
{
502+
$query = $this->newQuery('Thread')
503+
->key([
504+
'ForumName' => 'Laravel',
505+
'Subject' => 'Laravel Thread 1'
506+
])->updateItem([
507+
'Tags' => null,
508+
]);
509+
510+
$this->assertEquals(
511+
$query['params']['UpdateExpression'],
512+
'remove #1'
513+
);
514+
}
515+
516+
/** @test */
517+
public function it_can_remove_multiple_attributes()
518+
{
519+
$query = $this->newQuery('Thread')
520+
->key([
521+
'ForumName' => 'Laravel',
522+
'Subject' => 'Laravel Thread 1'
523+
])->updateItem([
524+
'Tags' => null,
525+
'Views' => null
526+
]);
527+
528+
$this->assertEquals(
529+
$query['params']['UpdateExpression'],
530+
'remove #1, #2'
531+
);
532+
}
533+
417534
/** @test */
418535
public function it_can_process_query()
419536
{

0 commit comments

Comments
 (0)