MysqliDriver   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 97.44%

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 101
wmc 13
lcom 2
cbo 6
ccs 38
cts 39
cp 0.9744
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A connect() 0 13 2
A query() 0 9 2
A poll() 0 15 3
A info() 0 5 1
A read() 0 12 3
A error() 0 5 1
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