Passed
Pull Request — master (#37)
by Eugene
05:25
created

Client::getSpaceIdByName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 10
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Tarantool Client package.
7
 *
8
 * (c) Eugene Leonovich <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Tarantool\Client;
15
16
use Tarantool\Client\Connection\StreamConnection;
17
use Tarantool\Client\Exception\RequestFailed;
18
use Tarantool\Client\Handler\DefaultHandler;
19
use Tarantool\Client\Handler\Handler;
20
use Tarantool\Client\Handler\MiddlewareHandler;
21
use Tarantool\Client\Middleware\AuthMiddleware;
22
use Tarantool\Client\Middleware\Middleware;
23
use Tarantool\Client\Middleware\RetryMiddleware;
24
use Tarantool\Client\Packer\PurePacker;
25
use Tarantool\Client\Request\Call;
26
use Tarantool\Client\Request\Evaluate;
27
use Tarantool\Client\Request\Execute;
28
use Tarantool\Client\Request\Ping;
29 55
use Tarantool\Client\Schema\Criteria;
30
use Tarantool\Client\Schema\Index;
31 55
use Tarantool\Client\Schema\Space;
32 55
33 55
final class Client
34
{
35 3
    private $handler;
36
    private $spaces = [];
37 3
38
    public function __construct(Handler $handler)
39
    {
40 2
        $this->handler = $handler;
41
    }
42 2
43
    public static function fromDefaults() : self
44
    {
45 54
        return new self(new DefaultHandler(
46
            StreamConnection::createTcp(),
47 54
            new PurePacker()
48
        ));
49 33
    }
50 2
51
    public static function fromOptions(array $options) : self
52 33
    {
53
        $connectionOptions = [];
54 51
        if (isset($options['connect_timeout'])) {
55
            $connectionOptions['connect_timeout'] = $options['connect_timeout'];
56 51
        }
57 51
        if (isset($options['socket_timeout'])) {
58 51
            $connectionOptions['socket_timeout'] = $options['socket_timeout'];
59
        }
60 14
        if (isset($options['tcp_nodelay'])) {
61
            $connectionOptions['tcp_nodelay'] = $options['tcp_nodelay'];
62 14
        }
63
64
        $connection = StreamConnection::create($options['uri'] ?? StreamConnection::DEFAULT_URI, $connectionOptions);
65 14
        $handler = new DefaultHandler($connection, new PurePacker());
66
67 14
        if (isset($options['username'])) {
68 12
            $handler = new MiddlewareHandler(
69
                new AuthMiddleware($options['username'], $options['password'] ?? ''),
70
                $handler
71 14
            );
72 14
        }
73
        if (isset($options['max_retries']) && 0 !== $options['max_retries']) {
74 10
            $handler = new MiddlewareHandler(
75 10
                RetryMiddleware::linear($options['max_retries']),
76
                $handler
77 10
            );
78
        }
79 10
80
        return new self($handler);
81
    }
82 10
83
    public static function fromDsn(string $dsn) : self
84 10
    {
85
        $dsn = Dsn::parse($dsn);
86 10
87
        $connectionOptions = [];
88
        if (null !== $timeout = $dsn->getInt('connect_timeout')) {
89
            $connectionOptions['connect_timeout'] = $timeout;
90
        }
91
        if (null !== $timeout = $dsn->getInt('socket_timeout')) {
92
            $connectionOptions['socket_timeout'] = $timeout;
93
        }
94 64
        if (null !== $tcpNoDelay = $dsn->getBool('socket_timeout')) {
95
            $connectionOptions['tcp_nodelay'] = $tcpNoDelay;
96 64
        }
97 58
98
        $connection = $dsn->isTcp()
99
            ? StreamConnection::createTcp($dsn->getConnectionUri(), $connectionOptions)
100 16
            : StreamConnection::createUds($dsn->getConnectionUri(), $connectionOptions);
101 10
102
        $handler = new DefaultHandler($connection, new PurePacker());
103
104 14
        if ($username = $dsn->getUsername()) {
105
            $handler = new MiddlewareHandler(
106 12
                new AuthMiddleware($username, $dsn->getPassword() ?? ''),
107
                $handler
108
            );
109 8
        }
110
        if ($maxRetries = $dsn->getInt('max_retries')) {
111 8
            $handler = new MiddlewareHandler(
112
                RetryMiddleware::linear($maxRetries),
113 8
                $handler
114
            );
115
        }
116 26
117
        return new self($handler);
118 26
    }
119
120 26
    public function withMiddleware(Middleware $middleware, Middleware ...$middlewares) : self
121
    {
122
        $new = clone $this;
123 12
        $new->handler = new MiddlewareHandler($middleware, $this->handler);
124
125 12
        if ($middlewares) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $middlewares of type array<integer,Tarantool\...\Middleware\Middleware> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
126 12
            $new->handler = MiddlewareHandler::create($new->handler, $middlewares);
127
        }
128 115
129
        return $new;
130 115
    }
131 30
132
    public function getHandler() : Handler
133
    {
134 113
        return $this->handler;
135 113
    }
136
137 109
    public function ping() : void
138
    {
139
        $this->handler->handle(new Ping());
140 14
    }
141
142 14
    public function getSpace(string $spaceName) : Space
143 14
    {
144 14
        if (isset($this->spaces[$spaceName])) {
145
            return $this->spaces[$spaceName];
146 14
        }
147 3
148
        $spaceId = $this->getSpaceIdByName($spaceName);
149
150 12
        return $this->spaces[$spaceName] = $this->spaces[$spaceId] = new Space($this->handler, $spaceId);
151
    }
152
153
    public function getSpaceById(int $spaceId) : Space
154
    {
155
        if (isset($this->spaces[$spaceId])) {
156
            return $this->spaces[$spaceId];
157
        }
158
159
        return $this->spaces[$spaceId] = new Space($this->handler, $spaceId);
160
    }
161
162
    public function call(string $funcName, ...$args) : array
163
    {
164
        $request = new Call($funcName, $args);
165
166
        return $this->handler->handle($request)->getBodyField(IProto::DATA);
167
    }
168
169
    public function executeQuery(string $sql, ...$params) : SqlQueryResult
170
    {
171
        $request = new Execute($sql, $params);
172
        $response = $this->handler->handle($request);
173
174
        return new SqlQueryResult(
175
            $response->getBodyField(IProto::DATA),
176
            $response->getBodyField(IProto::METADATA)
177
        );
178
    }
179
180
    public function executeUpdate(string $sql, ...$params) : SqlUpdateResult
181
    {
182
        $request = new Execute($sql, $params);
183
184
        return new SqlUpdateResult(
185
            $this->handler->handle($request)->getBodyField(IProto::SQL_INFO)
186
        );
187
    }
188
189
    public function evaluate(string $expr, ...$args) : array
190
    {
191
        $request = new Evaluate($expr, $args);
192
193
        return $this->handler->handle($request)->getBodyField(IProto::DATA);
194
    }
195
196
    public function flushSpaces() : void
197
    {
198
        $this->spaces = [];
199
    }
200
201
    private function getSpaceIdByName(string $spaceName) : int
202
    {
203
        $schema = $this->getSpaceById(Space::VSPACE_ID);
204
        $data = $schema->select(Criteria::key([$spaceName])->andIndex(Index::SPACE_NAME));
205
206
        if ([] === $data) {
207
            throw RequestFailed::unknownSpace($spaceName);
208
        }
209
210
        return $data[0][0];
211
    }
212
}
213