QueryOperation::setSortKeyConditionExpression()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
namespace Guillermoandrae\DynamoDb\Operation;
4
5
use Aws\DynamoDb\DynamoDbClient;
6
use Aws\DynamoDb\Exception\DynamoDbException;
7
use Aws\DynamoDb\Marshaler;
8
use ErrorException;
9
use Guillermoandrae\Common\Collection;
10
use Guillermoandrae\Common\CollectionInterface;
11
use Guillermoandrae\DynamoDb\Constant\Operators;
12
use Guillermoandrae\DynamoDb\Contract\AbstractSearchOperation;
13
use Guillermoandrae\DynamoDb\Factory\ExceptionFactory;
14
15
/**
16
 * Query operation.
17
 *
18
 * Note about offset and limit: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Limit
19
 *
20
 * @author Guillermo A. Fisher <[email protected]>
21
 * @link https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#query
22
 */
23
final class QueryOperation extends AbstractSearchOperation
24
{
25
    /**
26
     * @var string The condition that specifies the key values for items to be retrieved.
27
     */
28
    private string $keyConditionExpression = '';
29
30
    /**
31
     * @var boolean Whether or not to scan forward.
32
     */
33
    private bool $scanIndexForward = false;
34
35
    /**
36
     * QueryRequest constructor.
37
     *
38
     * @param DynamoDbClient $client The DynamoDb client.
39
     * @param Marshaler $marshaler The Marshaler.
40
     * @param string $tableName The table name.
41
     * @param array|null $keyConditions OPTIONAL The key conditions.
42
     * @throws ErrorException
43
     */
44 18
    public function __construct(
45
        DynamoDbClient $client,
46
        Marshaler      $marshaler,
47
        string         $tableName,
48
        ?array         $keyConditions = []
49
    ) {
50 18
        parent::__construct($client, $marshaler, $tableName);
51 18
        if (!empty($keyConditions)) {
52 1
            foreach ($keyConditions as $key => $condition) {
53 1
                switch ($key) {
54 1
                    case 'partition':
55
                        $this->setPartitionKeyConditionExpression(
56 1
                            $condition['name'],
57 1
                            $condition['value']
58 1
                        );
59 1
                        break;
60 1
                    case 'sort':
61
                        $this->setSortKeyConditionExpression(
62
                            $condition['name'],
63
                            $condition['operator'],
64 18
                            $condition['value']
65
                        );
66
                        break;
67
                    default:
68
                        $this->setExpression([
69
                            $key => $condition,
70
                        ]);
71
                        break;
72
                }
73
            }
74 3
        }
75
    }
76 3
77 3
    /**
78 3
     * Sets condition expression for the partition key.
79 3
     *
80
     * @param string $keyName The name of the partition key.
81
     * @param mixed $value The desired value.
82
     * @return QueryOperation This object.
83
     * @throws ErrorException Thrown when an unsupported operator is requested.
84
     */
85
    public function setPartitionKeyConditionExpression(string $keyName, mixed $value): QueryOperation
86
    {
87
        $partitionKeyConditionExpression = $this->parseExpression(Operators::EQ, $keyName);
88
        $this->addExpressionAttributeValue($keyName, $value);
89
        $this->keyConditionExpression = $partitionKeyConditionExpression;
90
        return $this;
91 2
    }
92
93 2
    /**
94 2
     * Sets condition expressions for the sort key.
95 2
     *
96 2
     * @param string $keyName The name of the sort key.
97
     * @param string $operator The operator.
98
     * @param mixed $value The desired value.
99
     * @return QueryOperation This object.
100
     * @throws ErrorException Thrown when an unsupported operator is requested.
101
     */
102
    public function setSortKeyConditionExpression(string $keyName, string $operator, mixed $value): QueryOperation
103
    {
104
        $sortKeyConditionExpression = $this->parseExpression($operator, $keyName);
105 1
        $this->addExpressionAttributeValue($keyName, $value);
106
        $this->keyConditionExpression .= ' AND ' . $sortKeyConditionExpression;
107 1
        return $this;
108 1
    }
109
110
    /**
111 2
     * Registers the ScanIndexForward value with this object.
112
     *
113
     * @param boolean $scanIndexForward Whether or not to scan forward.
114 2
     * @return QueryOperation This object.
115 1
     */
116 1
    public function setScanIndexForward(bool $scanIndexForward): QueryOperation
117 1
    {
118
        $this->scanIndexForward = $scanIndexForward;
119 1
        return $this;
120 1
    }
121 1
122
    public function execute(): CollectionInterface
123
    {
124
        try {
125 17
            $results = $this->client->query($this->toArray());
126
            $rows = [];
127 17
            foreach ($results['Items'] as $item) {
128 17
                $rows[] = $this->marshaler->unmarshalItem($item);
129 17
            }
130 3
            return Collection::make($rows)->limit($this->offset);
131
        } catch (DynamoDbException $ex) {
132 17
            throw ExceptionFactory::factory($ex);
133
        }
134
    }
135
136
    public function toArray(): array
137
    {
138
        $operation = parent::toArray();
139
        $operation['ScanIndexForward'] = $this->scanIndexForward;
140
        if (!empty($this->keyConditionExpression)) {
141
            $operation['KeyConditionExpression'] = $this->keyConditionExpression;
142
        }
143
        return $operation;
144
    }
145
}
146