Passed
Pull Request — master (#7)
by Sandro
02:03
created

TransactionalClient::add()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * Sandro Keil (https://sandro-keil.de)
4
 *
5
 * @link      http://github.com/sandrokeil/arangodb-php-client for the canonical source repository
6
 * @copyright Copyright (c) 2018-2019 Sandro Keil
7
 * @license   http://github.com/sandrokeil/arangodb-php-client/blob/master/LICENSE.md New BSD License
8
 */
9
10
declare(strict_types=1);
11
12
namespace ArangoDb\Http;
13
14
use ArangoDb\Type\Batch;
15
use ArangoDb\Type\GuardSupport;
16
use ArangoDb\Type\Transaction as TransactionType;
17
use ArangoDb\Type\Transactional;
18
use ArangoDb\Type\Type;
19
use Fig\Http\Message\StatusCodeInterface;
20
use Psr\Http\Client\ClientInterface;
21
use Psr\Http\Message\RequestInterface;
22
use Psr\Http\Message\ResponseFactoryInterface;
23
use Psr\Http\Message\ResponseInterface;
24
use Psr\Http\Message\StreamFactoryInterface;
25
26
final class TransactionalClient implements ClientInterface, TypeSupport, TransactionSupport
27
{
28
    /**
29
     * @var TypeSupport
30
     */
31
    private $client;
32
33
    /**
34
     * @var ResponseFactoryInterface
35
     */
36
    private $responseFactory;
37
38
    /**
39
     * Types
40
     *
41
     * @var Type[]
42
     */
43
    private $types = [];
44
45
    /**
46
     * Types
47
     *
48
     * @var Transactional[]
49
     */
50
    private $transactionalTypes = [];
51
52 9
    public function __construct(TypeSupport $client, ResponseFactoryInterface $responseFactory)
53
    {
54 9
        $this->client = $client;
55 9
        $this->responseFactory = $responseFactory;
56 9
    }
57
58
    public function sendType(Type $type): ResponseInterface
59
    {
60
        return $this->client->sendType($type);
61
    }
62
63
    public function sendRequest(RequestInterface $request): ResponseInterface
64
    {
65
        return $this->client->sendRequest($request);
0 ignored issues
show
Bug introduced by
The method sendRequest() does not exist on ArangoDb\Http\TypeSupport. Since it exists in all sub-types, consider adding an abstract or default implementation to ArangoDb\Http\TypeSupport. ( Ignorable by Annotation )

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

65
        return $this->client->/** @scrutinizer ignore-call */ sendRequest($request);
Loading history...
66
    }
67
68 8
    public function send(array $params = [], bool $waitForSync = false): ResponseInterface
69
    {
70 8
        if (0 !== count($this->types)) {
71 2
            $this->client->sendType(
72 2
                Batch::fromTypes(...$this->types)
73
            );
74
        }
75
76 8
        $actions = '';
77 8
        $collectionsWrite = [[]];
78 8
        $collectionsRead = [[]];
79 8
        $return = [];
80 8
        $guards = [];
81
82 8
        if (0 === count($this->transactionalTypes)) {
83 1
            return $this->responseFactory->createResponse(StatusCodeInterface::STATUS_OK);
84
        }
85
86 7
        foreach ($this->transactionalTypes as $key => $type) {
87 7
            $collectionsWrite[] = $type->collectionsWrite();
88 7
            $collectionsRead[] = $type->collectionsRead();
89
90 7
            if ($type instanceof GuardSupport
91 7
                && ($guard = $type->guard()) !== null
92
            ) {
93 1
                $guards[] = $guard;
94 1
                $key = $guard->contentId();
95
            }
96 7
            $actions .= str_replace('var rId', 'var rId' . $key, $type->toJs());
97 7
            $return[] = 'rId' . $key;
98
        }
99 7
        $collectionsWrite = array_merge(...$collectionsWrite);
100 7
        $collectionsRead = array_merge(...$collectionsRead);
101
102 7
        $response = $this->client->sendType(
103 7
            TransactionType::with(
104 7
                sprintf(
105 7
                    'function () {var db = require("@arangodb").db;%s return {%s}}',
106 7
                    $actions,
107 7
                    implode(',', $return)
108
                ),
109 7
                array_unique($collectionsWrite),
110 7
                $params,
111 7
                array_unique($collectionsRead),
112 7
                $waitForSync
113
            )
114
        );
115
116 7
        if (0 !== count($guards)) {
117
            \array_walk($guards, static function ($guard) use ($response) {
118 1
                $guard($response);
119 1
            });
120
        }
121
122 7
        $this->types = [];
123 7
        $this->transactionalTypes = [];
124
125 7
        return $response;
126
    }
127
128
    /**
129
     * Add type
130
     *
131
     * @param Type $type
132
     */
133 4
    public function add(Type $type): void
134
    {
135 4
        if ($type instanceof Transactional) {
136 4
            $this->transactionalTypes[] = $type;
137 4
            return;
138
        }
139 3
        $this->types[] = $type;
140 3
    }
141
142
    /**
143
     * Adds multiple types
144
     *
145
     * @param Type ...$types
146
     */
147 4
    public function addList(Type ...$types): void
148
    {
149 4
        foreach ($types as $type) {
150 4
            if ($type instanceof Transactional) {
151 4
                $this->transactionalTypes[] = $type;
152 4
                continue;
153
            }
154
            $this->types[] = $type;
155
        }
156 4
    }
157
158
    /**
159
     * Counts non transactional types
160
     *
161
     * @return int
162
     */
163 3
    public function countTypes(): int
164
    {
165 3
        return count($this->types);
166
    }
167
168
    /**
169
     * Counts transactional types
170
     *
171
     * @return int
172
     */
173 3
    public function countTransactionalTypes(): int
174
    {
175 3
        return count($this->transactionalTypes);
176
    }
177
178
    /**
179
     * Resets all types and transactional types
180
     */
181 1
    public function reset(): void
182
    {
183 1
        $this->types = [];
184 1
        $this->transactionalTypes = [];
185 1
    }
186
}
187