Passed
Branch master (2bdc71)
by Csaba
06:03 queued 04:17
created

Resource::patch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
namespace Fathomminds\Rest\Database\DynamoDb;
3
4
use Aws\Sdk;
5
use Aws\DynamoDb\DynamoDbClient as Client;
6
use Fathomminds\Rest\Exceptions\RestException;
7
use Fathomminds\Rest\Contracts\IResource;
8
use Fathomminds\Rest\Helpers\Uuid;
9
use Aws\DynamoDb\Exception\DynamoDbException;
10
use Fathomminds\Rest\Database\DynamoDb\QueryConstructor;
11
12
class Resource implements IResource
13
{
14
    protected $client;
15
    protected $databaseName;
16
    protected $collection;
17
    protected $fullTableName;
18
    protected $resourceName;
19
    protected $primaryKey;
20
    protected $queryConstructor;
21
22 20
    public function __construct($resourceName, $primaryKey, Client $client = null, $databaseName = null)
23
    {
24 20
        $this->resourceName = $resourceName;
25 20
        $this->primaryKey = $primaryKey;
26 20
        $this->client = $client === null ? $this->createClient() : $client;
27 20
        $this->databaseName = $databaseName === null ? $this->getFullDatabaseName() : $databaseName;
28 20
        $this->fullTableName = $this->databaseName . '-' . $this->resourceName;
29 20
        $this->queryConstructor = new QueryConstructor;
30 20
    }
31
32 1
    private function createClient()
33
    {
34 1
        $sdk = new Sdk([
35 1
            'region'   => getenv('AWS_SDK_REGION'),
36 1
            'version'  => getenv('AWS_SDK_VERSION'),
37
            'http' => [
38 1
                'verify' => getenv('AWS_SDK_HTTP_VERIFY') === 'false' ? false : getenv('AWS_SDK_HTTP_VERIFY'),
39
            ]
40
        ]);
41 1
        return $sdk->createDynamoDb();
42
    }
43
44 1
    private function getFullDatabaseName()
45
    {
46 1
        return getenv('AWS_DYNAMODB_NAMESPACE') . '-' . getenv('AWS_DYNAMODB_DATABASE');
47
    }
48
49 2
    public function get($resourceId = null)
50
    {
51 2
        if ($resourceId !== null) {
52 1
            return $this->getOne($resourceId);
53
        }
54 1
        return $this->getAll();
55
    }
56
57 1
    protected function getOne($resourceId)
58
    {
59 1
        $query = $this->queryConstructor->createGetQuery($this->fullTableName, $this->primaryKey, $resourceId);
60 1
        $res = $this->client->getItem($query);
61 1
        return $this->queryConstructor->unmarshalItem($res['Item']);
62
    }
63
64 1
    protected function getAll()
65
    {
66 1
        $query = $this->queryConstructor->createScanQuery($this->fullTableName);
67 1
        $res = $this->client->scan($query);
68 1
        return $this->queryConstructor->unmarshalBatch($res['Items']);
69
    }
70
71 2
    protected function throwAwsPostError($exception)
72
    {
73 2
        switch ($exception->getAwsErrorCode()) {
74 2
            case 'ConditionalCheckFailedException':
75 1
                throw new RestException(
76 1
                    'Primary key collision',
77 1
                    ['exception' => $exception]
78
                );
79
        }
80 1
        throw new RestException($exception->getMessage(), ['exception' => $exception]);
81
    }
82
83 6
    public function post($newResource)
84
    {
85
        try {
86 6
            $query = $this->queryConstructor->createPostQuery($this->fullTableName, $this->primaryKey, $newResource);
87 6
            $this->client->putItem($query);
88 4
        } catch (DynamoDbException $ex) {
89 2
            $this->throwAwsPostError($ex);
90 2
        } catch (\Exception $ex) {
91 2
            throw new RestException($ex->getMessage(), ['exception' => $ex]);
92
        }
93 2
        return $newResource;
94
    }
95
96 2
    protected function throwAwsPutError($exception)
97
    {
98 2
        switch ($exception->getAwsErrorCode()) {
99 2
            case 'ConditionalCheckFailedException':
100 1
                throw new RestException(
101 1
                    'Resource does not exist',
102 1
                    ['exception' => $exception]
103
                );
104
        }
105 1
        throw new RestException($exception->getMessage(), ['exception' => $exception]);
106
    }
107
108 3
    public function patch($resourceId, $newResource)
109
    {
110 3
        return $this->put($resourceId, $newResource);
111
    }
112
113 8
    public function put($resourceId, $newResource)
114
    {
115
        try {
116 8
            $newResource->{$this->primaryKey} = $resourceId;
117 8
            $query = $this->queryConstructor->createPutQuery($this->fullTableName, $this->primaryKey, $newResource);
118 8
            $res = $this->client->putItem($query);
119 4
        } catch (DynamoDbException $ex) {
120 2
            $this->throwAwsPutError($ex);
121 2
        } catch (\Exception $ex) {
122 2
            throw new RestException($ex->getMessage(), ['result'=>empty($res)?null:$res]);
123
        }
124 4
        return $newResource;
125
    }
126
127 2
    public function delete($resourceId)
128
    {
129
        try {
130 2
            $query = $this->queryConstructor->createDeleteQuery($this->fullTableName, $this->primaryKey, $resourceId);
131 2
            $res = $this->client->deleteItem($query);
132 1
            return $resourceId;
133 1
        } catch (\Exception $ex) {
134 1
            throw new RestException($ex->getMessage(), ['result'=>empty($res)?null:$res]);
135
        }
136
    }
137
}
138