diff --git a/src/DynamoBreezeService.php b/src/DynamoBreezeService.php index 3e7795a..08cb5a5 100644 --- a/src/DynamoBreezeService.php +++ b/src/DynamoBreezeService.php @@ -75,6 +75,18 @@ public function accessPattern(string $patternName, array $dataProvider): self return $this; } + /** + * Insert a record into DynamoDB. + * + * @return mixed + */ + public function insertRecord(array $parameters) + { + $parameters = array_merge(['TableName' => $this->queryBuilder->getTableName()], $parameters); + + return $this->getDynamoDbClient()->putItem($parameters); + } + public function get(): DynamoBreezeResult { $patternConfig = $this->config['tables'][$this->tableIdentifier]['access_patterns'][$this->queryBuilder->getAccessPatternName()]; @@ -88,22 +100,35 @@ public function get(): DynamoBreezeResult return new DynamoBreezeResult($result); } - /** - * Insert a record into DynamoDB. - * - * @return mixed - */ - public function insertRecord(array $parameters) + public function batchGet(array $batchItems): DynamoBreezeResult { - $parameters = array_merge(['TableName' => $this->queryBuilder->getTableName()], $parameters); + $requestItems = []; + + foreach ($batchItems as $tableIdentifier => $details) { + $keys = []; + foreach ($details['keys'] as $keyData) { + $keys[] = $this->expressionAttributeHandler->marshaler->marshalItem($keyData); + } + + $requestItems[$this->config['tables'][$tableIdentifier]['table_name']] = [ + 'Keys' => $keys, + // TODO Other parameters like 'ProjectionExpression' + ]; + } - return $this->getDynamoDbClient()->putItem($parameters); + $result = $this->getDynamoDbClient()->batchGetItem([ + 'RequestItems' => $requestItems, + // TODO 'ReturnConsumedCapacity' => 'TOTAL', // optional + ]); + + return new DynamoBreezeResult($result); } /** - * Update a record in DynamoDB. + * Insert a record into DynamoDB. * * @return mixed + * @return mixed */ public function updateRecord(array $parameters) { diff --git a/src/ExpressionAttributeHandler.php b/src/ExpressionAttributeHandler.php index bb337ca..b88cf7b 100644 --- a/src/ExpressionAttributeHandler.php +++ b/src/ExpressionAttributeHandler.php @@ -6,7 +6,7 @@ class ExpressionAttributeHandler { - protected Marshaler $marshaler; + public Marshaler $marshaler; public function __construct(Marshaler $marshaler) { diff --git a/tests/Feature/ExampleFeatureTest.php b/tests/Feature/ExampleFeatureTest.php index b2d1b30..9fb96d7 100644 --- a/tests/Feature/ExampleFeatureTest.php +++ b/tests/Feature/ExampleFeatureTest.php @@ -16,16 +16,6 @@ class ExampleFeatureTest extends FeatureTestCase private const TABLE_IDENTIFIER = 'social_media'; - public function setUp(): void - { - parent::setUp(); - $posts = [ - ['PK' => 'USER#1', 'SK' => 'POST#123', 'CategoryId' => 'A', 'Content' => 'Hello, World!', 'Timestamp' => time()], - ['PK' => 'USER#1', 'SK' => 'POST#124', 'CategoryId' => 'B', 'Content' => 'My second post!', 'Timestamp' => time()], - ]; - $this->seedDynamoDbTable($posts, self::TABLE_IDENTIFIER); - } - /** * @dataProvider tableCreationProvider */ @@ -119,11 +109,53 @@ public function tableCreationProvider() public function testFetchUserPosts(): void { + $posts = [ + ['PK' => 'USER#1', 'SK' => 'POST#123', 'CategoryId' => 'A', 'Content' => 'Hello, World!', 'Timestamp' => time()], + ['PK' => 'USER#1', 'SK' => 'POST#124', 'CategoryId' => 'B', 'Content' => 'My second post!', 'Timestamp' => time()], + ]; + + $this->seedDynamoDbTable($posts, self::TABLE_IDENTIFIER); $this->assertEquals(2, $this->fetchUserPosts(1)->getCount()); } + public function testBatchGetUserPosts(): void + { + $posts = [ + ['PK' => 'USER#1', 'SK' => 'POST#123', 'CategoryId' => 'A', 'Content' => 'Hello, World!', 'Timestamp' => time()], + ['PK' => 'USER#1', 'SK' => 'POST#124', 'CategoryId' => 'B', 'Content' => 'My second post!', 'Timestamp' => time()], + ['PK' => 'USER#2', 'SK' => 'POST#123', 'CategoryId' => 'A', 'Content' => 'Hello, World!', 'Timestamp' => time()], + ['PK' => 'USER#3', 'SK' => 'POST#1', 'CategoryId' => 'B', 'Content' => 'My second post!', 'Timestamp' => time()], + ]; + $this->seedDynamoDbTable($posts, self::TABLE_IDENTIFIER); + + // Define the keys for the items we want to retrieve. + $keysToGet = [ + ['PK' => 'USER#1', 'SK' => 'POST#123'], + ['PK' => 'USER#1', 'SK' => 'POST#124'], + ['PK' => 'USER#2', 'SK' => 'POST#123'], + ['PK' => 'USER#3', 'SK' => 'POST#1'], + ]; + + $result = DynamoBreeze::withTableIdentifier(self::TABLE_IDENTIFIER) + ->batchGet([ + self::TABLE_IDENTIFIER => [ + 'keys' => $keysToGet, + ], + ]); + + $retrievedPosts = $result->getRawResult()->get('Responses')['SocialMediaTable']; + + $this->assertCount(4, $retrievedPosts); + } + public function testFindPostsByUserWithFilter(): void { + $posts = [ + ['PK' => 'USER#1', 'SK' => 'POST#123', 'CategoryId' => 'A', 'Content' => 'Hello, World!', 'Timestamp' => time()], + ['PK' => 'USER#1', 'SK' => 'POST#124', 'CategoryId' => 'B', 'Content' => 'My second post!', 'Timestamp' => time()], + ]; + $this->seedDynamoDbTable($posts, self::TABLE_IDENTIFIER); + $result = DynamoBreeze::withTableIdentifier(self::TABLE_IDENTIFIER) ->accessPattern('FindPostsByUserWithFilter', [ 'user_id' => 1,