Completed
Push — master ( d0befd...ebeab2 )
by Guillermo A.
01:55
created

DynamoDbAdapter::delete()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 8
rs 10
ccs 6
cts 6
cp 1
cc 2
nc 3
nop 1
crap 2
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 16
    public function __construct(DynamoDbClient $client, Marshaler $marshaler)
40
    {
41 16
        $this->setClient($client);
42 16
        $this->marshaler = $marshaler;
43 16
        RequestFactory::setMarshaler($marshaler);
44 16
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49 8
    public function createTable(array $data): bool
50
    {
51
        try {
52 8
            $query = RequestFactory::factory('create-table', $this->tableName, $data)->get();
53 8
            $this->client->createTable($query);
54 6
            $this->client->waitUntil('TableExists', ['TableName' => $this->tableName]);
55 6
            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 7
    public function deleteTable(): bool
67
    {
68
        try {
69 7
            $query = RequestFactory::factory('delete-table', $this->tableName)->get();
70 7
            $this->client->deleteTable($query);
71 6
            $this->client->waitUntil('TableNotExists', ['TableName' => $this->tableName]);
72 6
            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 1
    public function tableExists(): bool
96
    {
97 1
        $tables = $this->listTables();
98 1
        return in_array(
99 1
            strtolower($this->tableName),
100 1
            array_map('strtolower', $tables)
101
        );
102
    }
103
104
    /**
105
     * {@inheritDoc}
106
     */
107 16
    public function listTables(): array
108
    {
109 16
        $query = RequestFactory::factory('list-tables')->get();
110 16
        $results = $this->client->listTables($query);
111 16
        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...
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117 3
    public function findAll(int $offset = 0, ?int $limit = null): CollectionInterface
118
    {
119
        try {
120 3
            $query = RequestFactory::factory('scan', $this->tableName)->get();
121 3
            $results = $this->client->scan($query);
122 2
            $rows = [];
123 2
            foreach ($results['Items'] as $item) {
124 1
                $rows[] = $this->marshaler->unmarshalItem($item);
125
            }
126 2
            $collection = Collection::make($rows);
127 2
            return $collection->limit($offset, $limit);
128 1
        } catch (DynamoDbException $ex) {
129 1
            throw new DbException($ex->getMessage());
130
        }
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136 2
    public function findLatest(): array
137
    {
138
        try {
139 2
            $query = RequestFactory::factory('scan', $this->tableName)
140 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

140
                ->/** @scrutinizer ignore-call */ setLimit(1)
Loading history...
141 2
                ->get();
142 2
            $results = $this->client->scan($query);
143 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...
144 1
        } catch (DynamoDbException $ex) {
145 1
            throw new DbException($ex->getMessage());
146
        }
147
    }
148
149
    /**
150
     * {@inheritDoc}
151
     */
152 2
    public function findById($id): array
153
    {
154 2
        return $this->findByPrimaryKey($id);
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160 2
    public function findByPrimaryKey($primaryKey): array
161
    {
162
        try {
163 2
            $query = RequestFactory::factory('get-item', $this->tableName, $primaryKey)->get();
164 2
            $results = $this->client->getItem($query);
165 1
            if (is_array($results['Item'])) {
166 1
                return $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

166
                return $this->marshaler->unmarshalItem(/** @scrutinizer ignore-type */ $results['Item']);
Loading history...
Bug Best Practice introduced by
The expression return $this->marshaler-...lItem($results['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...
167
            }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 165 is false. This is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
168 1
        } catch (DynamoDbException $ex) {
169 1
            throw new DbException($ex->getMessage());
170
        }
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176 5
    public function insert(array $data): bool
177
    {
178
        try {
179 5
            $query = RequestFactory::factory('put-item', $this->tableName, $data)->get();
180 5
            $this->client->putItem($query);
181 4
            return true;
182 1
        } catch (DynamoDbException $ex) {
183 1
            throw new DbException($ex->getMessage());
184
        }
185
    }
186
187
    /**
188
     * {@inheritDoc}
189
     */
190 2
    public function delete($id): bool
191
    {
192
        try {
193 2
            $query = RequestFactory::factory('delete-item', $this->tableName, $id)->get();
194 2
            $this->client->deleteItem($query);
195 1
            return true;
196 1
        } catch (DynamoDbException $ex) {
197 1
            throw new DbException($ex->getMessage());
198
        }
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204 15
    public function useTable(string $tableName): AdapterInterface
205
    {
206 15
        $this->tableName = $tableName;
207 15
        return $this;
208
    }
209
210
    /**
211
     * {@inheritDoc}
212
     */
213 16
    public function setClient($client): AdapterInterface
214
    {
215 16
        $this->client = $client;
216 16
        return $this;
217
    }
218
219
    /**
220
     * {@inheritDoc}
221
     */
222 1
    public function getClient(): DynamoDbClient
223
    {
224 1
        return $this->client;
225
    }
226
}
227