Completed
Push — master ( ebeab2...e57d07 )
by Guillermo A.
02:03
created

DynamoDbAdapter::findById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 1
c 2
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Guillermoandrae\Db\DynamoDb;
4
5
use Aws\DynamoDb\DynamoDbClient;
6
use Aws\DynamoDb\Exception\DynamoDbException;
7
use Aws\DynamoDb\Marshaler;
8
use Guillermoandrae\Common\Collection;
9
use Guillermoandrae\Common\CollectionInterface;
10
use Guillermoandrae\Db\AdapterInterface;
11
use Guillermoandrae\Db\DbException;
12
use InvalidArgumentException;
13
14
final class DynamoDbAdapter implements AdapterInterface
15
{
16
    /**
17
     * @var DynamoDbClient The DynamoDb client.
18
     */
19
    private $client;
20
21
    /**
22
     * @var Marshaler The JSON Marshaler.
23
     */
24
    private $marshaler;
25
26
    /**
27
     * @var string The table name.
28
     */
29
    private $tableName;
30
31
    /**
32
     * Registers the client and marshaler with this object. Sets up the
33
     * Repository factory and passes the Marshaler over to the request factory
34
     * as well.
35
     *
36
     * @param DynamoDbClient $client The DynamoDb client.
37
     * @param Marshaler $marshaler The JSON Marshaler.
38
     */
39 17
    public function __construct(DynamoDbClient $client, Marshaler $marshaler)
40
    {
41 17
        $this->setClient($client);
42 17
        $this->marshaler = $marshaler;
43 17
        RequestFactory::setMarshaler($marshaler);
44 17
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49 9
    public function createTable(array $data): bool
50
    {
51
        try {
52 9
            $query = RequestFactory::factory('create-table', $this->tableName, $data)->get();
53 9
            $this->client->createTable($query);
54 7
            $this->client->waitUntil('TableExists', ['TableName' => $this->tableName]);
55 7
            return true;
56 2
        } catch (DynamoDbException $ex) {
57 1
            throw new DbException($ex->getMessage());
58 1
        } catch (InvalidArgumentException $ex) {
59 1
            throw new DbException('Bad key schema: ' . $ex->getMessage());
60
        }
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66 8
    public function deleteTable(): bool
67
    {
68
        try {
69 8
            $query = RequestFactory::factory('delete-table', $this->tableName)->get();
70 8
            $this->client->deleteTable($query);
71 7
            $this->client->waitUntil('TableNotExists', ['TableName' => $this->tableName]);
72 7
            return true;
73 1
        } catch (DynamoDbException $ex) {
74 1
            throw new DbException($ex->getMessage());
75
        }
76
    }
77
78
    /**
79
     * {@inheritDoc}
80
     */
81 2
    public function describeTable(): array
82
    {
83
        try {
84 2
            $query = RequestFactory::factory('describe-table', $this->tableName)->get();
85 2
            $result = $this->client->describeTable($query);
86 1
            return $result['Table'];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result['Table'] could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
87 1
        } catch (DynamoDbException $ex) {
88 1
            throw new DbException($ex->getMessage());
89
        }
90
    }
91
92
     /**
93
     * {@inheritDoc}
94
     */
95 2
    public function tableExists(string $tableName = ''): bool
96
    {
97 2
        $tableName = !empty($tableName) ? $tableName : $this->tableName;
98 2
        $tables = $this->listTables();
99 2
        return in_array(
100 2
            strtolower($tableName),
101 2
            array_map('strtolower', $tables)
102
        );
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108 17
    public function listTables(): array
109
    {
110 17
        $query = RequestFactory::factory('list-tables')->get();
111 17
        $results = $this->client->listTables($query);
112 17
        return $results['TableNames'];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $results['TableNames'] could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
113
    }
114
115
    /**
116
     * {@inheritDoc}
117
     */
118 3
    public function findAll(int $offset = 0, ?int $limit = null): CollectionInterface
119
    {
120
        try {
121 3
            $query = RequestFactory::factory('scan', $this->tableName)->get();
122 3
            $results = $this->client->scan($query);
123 2
            $rows = [];
124 2
            foreach ($results['Items'] as $item) {
125 1
                $rows[] = $this->marshaler->unmarshalItem($item);
126
            }
127 2
            $collection = Collection::make($rows);
128 2
            return $collection->limit($offset, $limit);
129 1
        } catch (DynamoDbException $ex) {
130 1
            throw new DbException($ex->getMessage());
131
        }
132
    }
133
134
    /**
135
     * {@inheritDoc}
136
     */
137 2
    public function findLatest(): array
138
    {
139
        try {
140 2
            $query = RequestFactory::factory('scan', $this->tableName)
141 2
                ->setLimit(1)
0 ignored issues
show
Bug introduced by
The method setLimit() does not exist on Guillermoandrae\Db\DynamoDb\RequestInterface. It seems like you code against a sub-type of Guillermoandrae\Db\DynamoDb\RequestInterface such as Guillermoandrae\Db\DynamoDb\ListTablesRequest or Guillermoandrae\Db\Dynam...rExpressionAwareRequest. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
                ->/** @scrutinizer ignore-call */ setLimit(1)
Loading history...
142 2
                ->get();
143 2
            $results = $this->client->scan($query);
144 1
            return $this->marshaler->unmarshalItem($results['Items'][0]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->marshaler-...m($results['Items'][0]) could return the type stdClass which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
145 1
        } catch (DynamoDbException $ex) {
146 1
            throw new DbException($ex->getMessage());
147
        }
148
    }
149
150
    /**
151
     * {@inheritDoc}
152
     */
153 2
    public function findById($id): array
154
    {
155 2
        return $this->findByPrimaryKey($id);
156
    }
157
158
    /**
159
     * {@inheritDoc}
160
     */
161 2
    public function findByPrimaryKey($primaryKey): array
162
    {
163
        try {
164 2
            $query = RequestFactory::factory('get-item', $this->tableName, $primaryKey)->get();
165 2
            $results = $this->client->getItem($query);
166 1
            $item = [];
167 1
            if (is_array($results['Item'])) {
168 1
                $item = $this->marshaler->unmarshalItem($results['Item']);
0 ignored issues
show
Bug introduced by
It seems like $results['Item'] can also be of type null; however, parameter $data of Aws\DynamoDb\Marshaler::unmarshalItem() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

168
                $item = $this->marshaler->unmarshalItem(/** @scrutinizer ignore-type */ $results['Item']);
Loading history...
169
            }
170 1
            return $item;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $item could return the type stdClass which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
171 1
        } catch (DynamoDbException $ex) {
172 1
            throw new DbException($ex->getMessage());
173
        }
174
    }
175
176
    /**
177
     * {@inheritDoc}
178
     */
179 5
    public function insert(array $data): bool
180
    {
181
        try {
182 5
            $query = RequestFactory::factory('put-item', $this->tableName, $data)->get();
183 5
            $this->client->putItem($query);
184 4
            return true;
185 1
        } catch (DynamoDbException $ex) {
186 1
            throw new DbException($ex->getMessage());
187
        }
188
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193 2
    public function delete($id): bool
194
    {
195
        try {
196 2
            $query = RequestFactory::factory('delete-item', $this->tableName, $id)->get();
197 2
            $this->client->deleteItem($query);
198 1
            return true;
199 1
        } catch (DynamoDbException $ex) {
200 1
            throw new DbException($ex->getMessage());
201
        }
202
    }
203
204
    /**
205
     * {@inheritDoc}
206
     */
207 16
    public function useTable(string $tableName): AdapterInterface
208
    {
209 16
        $this->tableName = $tableName;
210 16
        return $this;
211
    }
212
213
    /**
214
     * {@inheritDoc}
215
     */
216 17
    public function setClient($client): AdapterInterface
217
    {
218 17
        $this->client = $client;
219 17
        return $this;
220
    }
221
222
    /**
223
     * {@inheritDoc}
224
     */
225 1
    public function getClient(): DynamoDbClient
226
    {
227 1
        return $this->client;
228
    }
229
}
230