Passed
Push — 1.x ( 1fc25c...4e8027 )
by Adrian
05:24 queued 13s
created

Client::index()   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
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
 * Manticore  client object
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
    protected $lastResponse;
51
52
    /*
53
     * $config can be a connection array or
54
     * $config['connections] = array of connections
55
     * $config['connectionStrategy'] = class name of pool strategy
56
     */
57
    public function __construct($config = [], LoggerInterface $logger = null)
58
    {
59
        $this->setConfig($config);
60
        $this->logger = $logger ?? new NullLogger();
61
        $this->initConnections();
62
    }
63
64
    protected function initConnections()
65
    {
66
        $connections = [];
67
        if (isset($this->config['connections'])) {
68
            foreach ($this->config['connections'] as $connection) {
69
                if (is_array($connection)) {
70
                    $connections[] = Connection::create($connection);
71
                } else {
72
                    $connections[] = $connection;
73
                }
74
            }
75
        }
76
77
        if (empty($connections)) {
78
            $connections[] = Connection::create($this->config);
79
        }
80
        if (isset($this->config['connectionStrategy'])) {
81
            if (is_string($this->config['connectionStrategy'])) {
82
                $strategyName = '\\Manticoresearch\\Connection\\Strategy\\' . $this->config['connectionStrategy'];
83
                if (class_exists($strategyName)) {
84
                    $strategy = new $strategyName();
85
                } elseif (class_exists($this->config['connectionStrategy'])) {
86
                    $strategyName = $this->config['connectionStrategy'];
87
                    $strategy = new $strategyName();
88
                }
89
            } elseif ($this->config['connectionStrategy'] instanceof SelectorInterface) {
90
                $strategy = $this->config['connectionStrategy'];
91
            } else {
92
                throw new RuntimeException('Cannot create a strategy based on provided settings!');
93
            }
94
        } else {
95
            $strategy = new $this->connectionStrategy;
96
        }
97
        if (!isset($this->config['retries'])) {
98
            $this->config['retries'] = count($connections);
99
        }
100
        $this->connectionPool = new Connection\ConnectionPool(
101
            $connections,
102
            $strategy ?? new $this->connectionStrategy,
103
            $this->config['retries']
104
        );
105
    }
106
107
    /**
108
     * @param string|array $hosts
109
     */
110
    public function setHosts($hosts)
111
    {
112
        $this->config['connections'] = $hosts;
113
        $this->initConnections();
114
    }
115
116
    /**
117
     * @param array $config
118
     * @return $this
119
     */
120
    public function setConfig(array $config): self
121
    {
122
        $this->config = array_merge($this->config, $config);
123
        return $this;
124
    }
125
126
    /**
127
     * @param array $config
128
     * @return Client
129
     */
130
    public static function create($config): Client
131
    {
132
        return self::createFromArray($config);
133
    }
134
135
    /**
136
     * @param array $config
137
     * @return Client
138
     */
139
    public static function createFromArray($config): Client
140
    {
141
        return new self($config);
142
    }
143
144
    /**
145
     * @return mixed
146
     */
147
    public function getConnections()
148
    {
149
        return $this->connectionPool->getConnections();
150
    }
151
152
    /**
153
     * @return ConnectionPool
154
     */
155
    public function getConnectionPool(): ConnectionPool
156
    {
157
        return $this->connectionPool;
158
    }
159
160
    /**
161
     * Endpoint: search
162
     * @param array $params
163
     * @param bool $obj
164
     * @return array|Response
165
     */
166
    public function search(array $params = [], $obj = false)
167
    {
168
        $endpoint = new Endpoints\Search($params);
169
        $response = $this->request($endpoint);
170
        if ($obj === true) {
171
            return $response;
172
        } else {
173
            return $response->getResponse();
174
        }
175
    }
176
177
    /**
178
     * Endpoint: insert
179
     * @param array $params
180
     * @return array
181
     */
182
    public function insert(array $params = [])
183
    {
184
        $endpoint = new Endpoints\Insert($params);
185
        $response = $this->request($endpoint);
186
187
        return $response->getResponse();
188
    }
189
190
    /**
191
     * Endpoint: replace
192
     * @param array $params
193
     * @return mixed
194
     */
195
    public function replace(array $params = [])
196
    {
197
        $endpoint = new Endpoints\Replace($params);
198
        $response = $this->request($endpoint);
199
200
        return $response->getResponse();
201
    }
202
203
    /**
204
     * Endpoint: update
205
     * @param array $params
206
     * @return array
207
     */
208
    public function update(array $params = [])
209
    {
210
        $endpoint = new Endpoints\Update($params);
211
        $response = $this->request($endpoint);
212
213
        return $response->getResponse();
214
    }
215
216
    /**
217
     * Endpoint: sql
218
     * @param array $params
219
     * @return array
220
     */
221
    public function sql(array $params = [])
222
    {
223
        $endpoint = new Endpoints\Sql($params);
224
        if (isset($params['mode'])) {
225
            $endpoint->setMode($params['mode']);
226
            $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
227
        } else {
228
            $response = $this->request($endpoint);
229
        }
230
        return $response->getResponse();
231
    }
232
233
    /**
234
     * Endpoint: delete
235
     * @param array $params
236
     * @return array
237
     */
238
    public function delete(array $params = [])
239
    {
240
        $endpoint = new Endpoints\Delete($params);
241
        $response = $this->request($endpoint);
242
243
        return $response->getResponse();
244
    }
245
246
    /**
247
     * Endpoint: pq
248
     */
249
    public function pq(): Pq
250
    {
251
        return new Pq($this);
252
    }
253
254
    /**
255
     * Endpoint: indices
256
     */
257
    public function indices(): Indices
258
    {
259
        return new Indices($this);
260
    }
261
262
    /**
263
     * Endpoint: nodes
264
     */
265
    public function nodes(): Nodes
266
    {
267
        return new Nodes($this);
268
    }
269
270
    public function cluster(): Cluster
271
    {
272
        return new Cluster($this);
273
    }
274
275
    /**
276
     * Return Index object
277
     *
278
     * @param string|null $name Name of index
279
     *
280
     * @return \Manticoresearch\Index
281
     */
282
    public function index(string $name = null): Index
283
    {
284
        return new Index($this, $name);
285
    }
286
287
    /**
288
     * Endpoint: bulk
289
     * @param array $params
290
     * @return array
291
     */
292
    public function bulk(array $params = [])
293
    {
294
        $endpoint = new Endpoints\Bulk($params);
295
        $response = $this->request($endpoint);
296
297
        return $response->getResponse();
298
    }
299
300
    /**
301
     * Endpoint: suggest
302
     * @param array $params
303
     * @return array
304
     */
305
    public function suggest(array $params = [])
306
    {
307
        $endpoint = new Endpoints\Suggest();
308
        $endpoint->setIndex($params['index']);
309
        $endpoint->setBody($params['body']);
310
        $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
311
        return $response->getResponse();
312
    }
313
314
    public function keywords(array $params = [])
315
    {
316
        $endpoint = new Endpoints\Keywords();
317
        $endpoint->setIndex($params['index']);
318
        $endpoint->setBody($params['body']);
319
        $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
320
        return $response->getResponse();
321
    }
322
323
    public function explainQuery(array $params = [])
324
    {
325
        $endpoint = new Endpoints\ExplainQuery();
326
        $endpoint->setIndex($params['index']);
327
        $endpoint->setBody($params['body']);
328
        $response = $this->request($endpoint, ['responseClass' => 'Manticoresearch\\Response\\SqlToArray']);
329
        return $response->getResponse();
330
    }
331
332
333
    /*
334
     * @return Response
335
     */
336
337
    public function request(Request $request, array $params = []): Response
338
    {
339
        try {
340
            $connection = $this->connectionPool->getConnection();
341
            $this->lastResponse = $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

341
            $this->lastResponse = $connection->getTransportHandler($this->logger)->/** @scrutinizer ignore-call */ execute($request, $params);
Loading history...
342
        } catch (NoMoreNodesException $e) {
343
            $this->logger->error('Manticore Search Request out of retries:', [
344
                'exception' => $e->getMessage(),
345
                'request' => $request->toArray()
346
            ]);
347
            $this->initConnections();
348
            throw $e;
349
        } catch (ConnectionException $e) {
350
            $this->logger->warning('Manticore Search Request failed ' . $this->connectionPool->retries_attempts . ':', [
351
                'exception' => $e->getMessage(),
352
                'request' => $e->getRequest()->toArray()
353
            ]);
354
355
            if (isset($connection)) {
356
                $connection->mark(false);
357
            }
358
359
            return $this->request($request, $params);
360
        }
361
        return $this->lastResponse;
362
    }
363
364
    /*
365
 *
366
 * @return Response
367
 */
368
369
    public function getLastResponse(): Response
370
    {
371
        return $this->lastResponse;
372
    }
373
}
374