MysqliDriver::query()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 2
crap 2
1
<?php
2
3
/**
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2015 Repo2
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all
16
 * copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
 * SOFTWARE.
25
 */
26
27
namespace Repo2\QueryReactor\Driver\Mysqli;
28
29
use Psr\Log\LoggerInterface;
30
use Repo2\QueryBuilder;
31
use Repo2\QueryReactor\Driver;
32
use Repo2\QueryReactor\Result;
33
34
class MysqliDriver implements Driver
35
{
36
    /** @var LoggerInterface */
37
    private $logger;
38
39
    /** @var int */
40
    private $timeout;
41
42
    /**
43
     * @param LoggerInterface $logger
44
     * @param int $timeout
45
     */
46 57
    public function __construct(LoggerInterface $logger, $timeout = 1)
47
    {
48 57
        $this->logger = $logger;
49 57
        $this->timeout = $timeout;
50 57
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55 54
    public function connect(array $params, $username, $passwd)
56
    {
57 54
        $link = mysqli_init();
58 54
        set_error_handler(function () {
59 54
        });
60 54
        if (!$link->real_connect($params['host'], $username, $passwd, $params['dbname'])) {
61 3
            restore_error_handler();
62 3
            throw new MysqliException($link->connect_error, $link->connect_errno);
63
        }
64 51
        restore_error_handler();
65 51
        $this->logger->debug(sprintf('Connected to %s.', $this->info($link)));
66 51
        return $link;
67
    }
68
69
    /**
70
     * @inheritDoc
71
     */
72 51
    public function query($link, QueryBuilder\ExpressionInterface $expr)
73
    {
74
        /* @var $link \mysqli */
75 51
        $sql = $expr->compile(new QueryBuilder\Driver\Mysqli($link));
76 51
        if (false === $link->query($sql, MYSQLI_ASYNC)) {
77 3
            throw $this->error($link);
78
        }
79 48
        $this->logger->debug(sprintf('Running %s on %s.', $sql, $this->info($link)));
80 48
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85 51
    public function poll(array $links)
86
    {
87 51
        $read = $error = $reject = $links;
88
89 51
        if (false === mysqli_poll($read, $error, $reject, $this->timeout)) {
90
            throw new MysqliException(sprintf('Maximum polling time of %d seconds exceeded.', $this->timeout));
91
        }
92
93 51
        foreach ($reject as $link) {
94
            /* @var $link \mysqli */
95 3
            throw new MysqliException(sprintf('The connection to the host %s is rejected.', $link->host_info));
96 48
        }
97
98 48
        return [$read, $error];
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104 51
    public function info($link)
105
    {
106
        /* @var $link \mysqli */
107 51
        return sprintf('%s (thread %d)', $link->host_info, $link->thread_id);
108
    }
109
110
    /**
111
     * @inheritDoc
112
     */
113 48
    public function read($link)
114
    {
115
        /* @var $link \mysqli */
116 48
        $result = $link->reap_async_query();
117 48
        if (false === $result) {
118 9
            throw $this->error($link);
119
        }
120 48
        if ($result instanceof \mysqli_result) {
121 30
            return new MysqliResult($result);
122
        }
123 48
        return new Result\NobodyResult($link->affected_rows);
124
    }
125
126
    /**
127
     * @inheritDoc
128
     */
129 9
    public function error($link)
130
    {
131
        /* @var $link \mysqli */
132 9
        return new MysqliException($link->error, $link->errno);
133
    }
134
}
135