Completed
Push — master ( 346131...a9d641 )
by Adrian
02:26
created

Client::getLastResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Manticoresearch;
6
7
use Manticoresearch\Connection\ConnectionPool;
8
use Manticoresearch\Connection\Strategy\SelectorInterface;
9
use Manticoresearch\Connection\Strategy\StaticRoundRobin;
10
11
use Manticoresearch\Endpoints\Pq;
12
use Manticoresearch\Exceptions\ConnectionException;
13
use Manticoresearch\Exceptions\NoMoreNodesException;
14
use Manticoresearch\Exceptions\RuntimeException;
15
use Psr\Log\LoggerInterface;
16
use Psr\Log\NullLogger;
17
18
/**
19
 * Class Client
20
 * @package Manticoresearch
21
 * @category Manticoresearch
22
 * @author Adrian Nuta <[email protected]>
23
 * @link https://manticoresearch.com
24
 */
25
class Client
26
{
27
    /**
28
     *
29
     */
30
    const VERSION = '1.0.0';
31
32
    /**
33
     * @var array
34
     */
35
    protected $_config = [];
36
    /**
37
     * @var string
38
     */
39
    private $_connectionStrategy = StaticRoundRobin::class;
40
    /**
41
     * @var ConnectionPool
42
     */
43
    protected $_connectionPool;
44
45
    /**
46
     * @var LoggerInterface|NullLogger
47
     */
48
    protected $_logger;
49
50
    /*
51
     * $config can be a connection array or
52
     * $config['connections] = array of connections
53
     * $config['connectionStrategy'] = class name of pool strategy
54
     */
55
    public function __construct($config = [], LoggerInterface $logger = null)
56
    {
57
        $this->setConfig($config);
58
        $this->_logger = $logger ?? new NullLogger();
59
        $this->_initConnections();
60
61
    }
62
63
    protected function _initConnections()
64
    {
65
        $connections = [];
66
        if (isset($this->_config['connections'])) {
67
            foreach ($this->_config['connections'] as $connection) {
68
                if (is_array($connection)) {
69
                    $connections[] = Connection::create($connection);
70
                } else {
71
                    $connections[] = $connection;
72
                }
73
74
            }
75
76
        }
77
78
        if (empty($connections)) {
79
            $connections[] = Connection::create($this->_config);
80
        }
81
        if (isset($this->_config['connectionStrategy'])) {
82
            if (is_string($this->_config['connectionStrategy'])) {
83
                $strategyName = '\\Manticoresearch\\Connection\\Strategy\\' . $this->_config['connectionStrategy'];
84
                if (class_exists($strategyName)) {
85
                    $strategy = new $strategyName();
86
                } elseif (class_exists($this->_config['connectionStrategy'])) {
87
                    $strategyName = $this->_config['connectionStrategy'];
88
                    $strategy = new $strategyName();
89
                }
90
            } elseif ($this->_config['connectionStrategy'] instanceof SelectorInterface) {
91
                $strategy = $this->_config['connectionStrategy'];
92
            } else {
93
                throw new RuntimeException('Cannot create a strategy based on provided settings!');
94
            }
95
        } else {
96
            $strategy = new $this->_connectionStrategy;
97
        }
98
        if (!isset($this->_config['retries'])) {
99
            $this->_config['retries'] = count($connections);
100
        }
101
        $this->_connectionPool = new Connection\ConnectionPool($connections, $strategy, $this->_config['retries']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $strategy does not seem to be defined for all execution paths leading up to this point.
Loading history...
102
    }
103
104
    /**
105
     * @param $hosts
106
     */
107
    public function setHosts($hosts)
108
    {
109
        $this->_config['connections'] = $hosts;
110
        $this->_initConnections();
111
    }
112
113
    /**
114
     * @param array $config
115
     * @return $this
116
     */
117
    public function setConfig(array $config): self
118
    {
119
        $this->_config = array_merge($this->_config, $config);
120
        return $this;
121
    }
122
123
    /**
124
     * @param $config
125
     * @return Client
126
     */
127
    public static function create($config): Client
128
    {
129
        return self::createFromArray($config);
130
    }
131
132
    /**
133
     * @param $config
134
     * @return Client
135
     */
136
    public static function createFromArray($config): Client
137
    {
138
139
        return new self($config);
140
    }
141
142
    /**
143
     * @return mixed
144
     */
145
    public function getConnections()
146
    {
147
        return $this->_connectionPool->getConnections();
148
    }
149
150
    /**
151
     * @return mixed
152
     */
153
    public function getConnectionPool():ConnectionPool
154
    {
155
        return $this->_connectionPool;
156
    }
157
158
    /**
159
     * Endpoint: search
160
     * @param array $params
161
     */
162
    public function search(array $params = [])
163
    {
164
165
166
        $endpoint = new Endpoints\Search($params);
167
        $response = $this->request($endpoint);
168
        return $response->getResponse();
169
    }
170
171
    /**
172
     * Endpoint: insert
173
     * @param array $params
174
     */
175
    public function insert(array $params = [])
176
    {
177
178
        $endpoint = new Endpoints\Insert($params);
179
        $response = $this->request($endpoint);
180
181
        return $response->getResponse();
182
    }
183
184
    /**
185
     * Endpoint: replace
186
     * @param array $params
187
     * @return mixed
188
     */
189
    public function replace(array $params = [])
190
    {
191
192
        $endpoint = new Endpoints\Replace($params);
193
        $response = $this->request($endpoint);
194
195
        return $response->getResponse();
196
    }
197
198
    /**
199
     * Endpoint: update
200
     * @param array $params
201
     */
202
    public function update(array $params = [])
203
    {
204
205
        $endpoint = new Endpoints\Update($params);
206
        $response = $this->request($endpoint);
207
208
        return $response->getResponse();
209
    }
210
211
    /**
212
     * Endpoint: sql
213
     * @param array $params
214
     */
215
    public function sql(array $params = [])
216
    {
217
        $endpoint = new Endpoints\Sql($params);
218
        if (isset($params['mode'])) {
219
            $endpoint->setMode($params['mode']);
220
            $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
221
        } else {
222
            $response = $this->request($endpoint);
223
        }
224
        return $response->getResponse();
225
    }
226
227
    /**
228
     * Endpoint: delete
229
     * @param array $params
230
     * @return array
231
     */
232
    public function delete(array $params = [])
233
    {
234
235
        $endpoint = new Endpoints\Delete($params);
236
        $response = $this->request($endpoint);
237
238
        return $response->getResponse();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response->getResponse() also could return the type string which is incompatible with the documented return type array.
Loading history...
239
    }
240
241
    /**
242
     * Endpoint: pq
243
     */
244
    public function pq(): Pq
245
    {
246
247
        return new Pq($this);
248
    }
249
250
    /**
251
     * Endpoint: indices
252
     */
253
    public function indices(): Indices
254
    {
255
256
        return new Indices($this);
257
    }
258
259
    /**
260
     * Endpoint: nodes
261
     */
262
    public function nodes(): Nodes
263
    {
264
265
        return new Nodes($this);
266
    }
267
268
    public function cluster(): Cluster
269
    {
270
        return new Cluster($this);
271
    }
272
273
    /**
274
     * Endpoint: bulk
275
     * @param array $params
276
     * @return array
277
     */
278
    public function bulk(array $params = [])
279
    {
280
        $endpoint = new Endpoints\Bulk($params);
281
        $response = $this->request($endpoint);
282
283
        return $response->getResponse();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response->getResponse() also could return the type string which is incompatible with the documented return type array.
Loading history...
284
    }
285
286
    /**
287
     * Endpoint: suggest
288
     * @param array $params
289
     * @return array
290
     */
291
    public function suggest(array $params = [])
292
    {
293
        $endpoint = new Endpoints\Suggest($params);
294
        $endpoint->setIndex($params['index']);
295
        $endpoint->setBody($params['body']);
296
        $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
297
        return $response->getResponse();
298
    }
299
300
    public function keywords(array $params = [])
301
    {
302
        $endpoint = new Endpoints\Keywords($params);
303
        $endpoint->setIndex($params['index']);
304
        $endpoint->setBody($params['body']);
305
        $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
306
        return $response->getResponse();
307
    }
308
309
310
    /*
311
     * @return Response
312
     */
313
314
    public function request(Request $request, array $params = []): Response
315
    {
316
317
318
        try {
319
            $connection = $this->_connectionPool->getConnection();
320
            $response = $connection->getTransportHandler($this->_logger)->execute($request, $params);
0 ignored issues
show
introduced by
The method execute() does not exist on Manticoresearch\Transport. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

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

320
            $response = $connection->getTransportHandler($this->_logger)->/** @scrutinizer ignore-call */ execute($request, $params);
Loading history...
321
        } catch (NoMoreNodesException $e) {
322
            $this->_logger->error('Manticore Search Request out of retries:', [
323
                'exception' => $e->getMessage(),
324
                'request' => $request->toArray()
325
            ]);
326
            throw $e;
327
        } catch (ConnectionException $e) {
328
            $this->_logger->warning('Manticore Search Request failed '.$this->_connectionPool->retries_attempts.':', [
329
                'exception' => $e->getMessage(),
330
                'request' => $e->getRequest()->toArray()
331
            ]);
332
            $connection->mark(false);
333
            return $this->request($request, $params);
334
        }
335
        return $response;
336
    }
337
338
339
}