Completed
Pull Request — master (#37)
by Eugene
09:23 queued 07:55
created

Client::getSpaceIdByName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
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
use Tarantool\Client\Schema\Criteria;
30
use Tarantool\Client\Schema\Index;
31
use Tarantool\Client\Schema\Space;
32
33
final class Client
34
{
35
    private $handler;
36
    private $spaces = [];
37
38 250
    public function __construct(Handler $handler)
39
    {
40 250
        $this->handler = $handler;
41 250
    }
42
43
    public static function fromDefaults() : self
44
    {
45
        return new self(new DefaultHandler(
46
            StreamConnection::createTcp(),
47
            new PurePacker()
48
        ));
49
    }
50
51
    public static function fromOptions(array $options) : self
52
    {
53
        $connectionOptions = [];
54
        if (isset($options['connect_timeout'])) {
55
            $connectionOptions['connect_timeout'] = $options['connect_timeout'];
56
        }
57
        if (isset($options['socket_timeout'])) {
58
            $connectionOptions['socket_timeout'] = $options['socket_timeout'];
59
        }
60
        if (isset($options['tcp_nodelay'])) {
61
            $connectionOptions['tcp_nodelay'] = $options['tcp_nodelay'];
62
        }
63
64
        $connection = StreamConnection::create($options['uri'] ?? StreamConnection::DEFAULT_URI, $connectionOptions);
65
        $handler = new DefaultHandler($connection, new PurePacker());
66
67
        if (isset($options['username'])) {
68
            $handler = MiddlewareHandler::create($handler, new AuthMiddleware($options['username'], $options['password'] ?? ''));
69
        }
70
        if (isset($options['max_retries']) && 0 !== $options['max_retries']) {
71
            $handler = MiddlewareHandler::create($handler, RetryMiddleware::linear($options['max_retries']));
72
        }
73
74
        return new self($handler);
75
    }
76
77
    public static function fromDsn(string $dsn) : self
78
    {
79
        $dsn = Dsn::parse($dsn);
80
81
        $connectionOptions = [];
82
        if (null !== $timeout = $dsn->getInt('connect_timeout')) {
83
            $connectionOptions['connect_timeout'] = $timeout;
84
        }
85
        if (null !== $timeout = $dsn->getInt('socket_timeout')) {
86
            $connectionOptions['socket_timeout'] = $timeout;
87
        }
88
        if (null !== $tcpNoDelay = $dsn->getBool('socket_timeout')) {
89
            $connectionOptions['tcp_nodelay'] = $tcpNoDelay;
90
        }
91
92
        $connection = $dsn->isTcp()
93
            ? StreamConnection::createTcp($dsn->getConnectionUri(), $connectionOptions)
94
            : StreamConnection::createUds($dsn->getConnectionUri(), $connectionOptions);
95
96
        $handler = new DefaultHandler($connection, new PurePacker());
97
98
        if ($username = $dsn->getUsername()) {
99
            $handler = MiddlewareHandler::create($handler, new AuthMiddleware($username, $dsn->getPassword() ?? ''));
100
        }
101
        if ($maxRetries = $dsn->getInt('max_retries')) {
102
            $handler = MiddlewareHandler::create($handler, RetryMiddleware::linear($maxRetries));
103
        }
104
105
        return new self($handler);
106
    }
107
108
    public function withMiddleware(Middleware $middleware, Middleware ...$middlewares) : self
109
    {
110
        $new = clone $this;
111
        $new->handler = MiddlewareHandler::create($new->handler, $middleware, ...$middlewares);
112
113
        return $new;
114
    }
115
116 12
    public function getHandler() : Handler
117
    {
118 12
        return $this->handler;
119
    }
120
121 54
    public function ping() : void
122
    {
123 54
        $this->handler->handle(new Ping());
124 4
    }
125
126 104
    public function getSpace(string $spaceName) : Space
127
    {
128 104
        if (isset($this->spaces[$spaceName])) {
129 2
            return $this->spaces[$spaceName];
130
        }
131
132 104
        $spaceId = $this->getSpaceIdByName($spaceName);
133
134 100
        return $this->spaces[$spaceName] = $this->spaces[$spaceId] = new Space($this->handler, $spaceId);
135
    }
136
137 110
    public function getSpaceById(int $spaceId) : Space
138
    {
139 110
        if (isset($this->spaces[$spaceId])) {
140
            return $this->spaces[$spaceId];
141
        }
142
143 110
        return $this->spaces[$spaceId] = new Space($this->handler, $spaceId);
144
    }
145
146 4
    public function call(string $funcName, ...$args) : array
147
    {
148 4
        $request = new Call($funcName, $args);
149
150 4
        return $this->handler->handle($request)->getBodyField(IProto::DATA);
151
    }
152
153 8
    public function executeQuery(string $sql, ...$params) : SqlQueryResult
154
    {
155 8
        $request = new Execute($sql, $params);
156 8
        $response = $this->handler->handle($request);
157
158 8
        return new SqlQueryResult(
159 8
            $response->getBodyField(IProto::DATA),
160 8
            $response->getBodyField(IProto::METADATA)
161
        );
162
    }
163
164 10
    public function executeUpdate(string $sql, ...$params) : SqlUpdateResult
165
    {
166 10
        $request = new Execute($sql, $params);
167
168 10
        return new SqlUpdateResult(
169 10
            $this->handler->handle($request)->getBodyField(IProto::SQL_INFO)
170
        );
171
    }
172
173 116
    public function evaluate(string $expr, ...$args) : array
174
    {
175 116
        $request = new Evaluate($expr, $args);
176
177 116
        return $this->handler->handle($request)->getBodyField(IProto::DATA);
178
    }
179
180 4
    public function flushSpaces() : void
181
    {
182 4
        $this->spaces = [];
183 4
    }
184
185 104
    private function getSpaceIdByName(string $spaceName) : int
186
    {
187 104
        $schema = $this->getSpaceById(Space::VSPACE_ID);
188 104
        $data = $schema->select(Criteria::key([$spaceName])->andIndex(Index::SPACE_NAME));
189
190 104
        if ([] === $data) {
191 4
            throw RequestFailed::unknownSpace($spaceName);
192
        }
193
194 100
        return $data[0][0];
195
    }
196
}
197