Client::escape()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 0
cts 10
cp 0
rs 9.4285
cc 1
eloc 6
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Thruster\Component\MysqlClient;
4
5
use mysqli;
6
use Thruster\Component\EventLoop\EventLoopInterface;
7
use Thruster\Component\EventLoop\Timer;
8
use Thruster\Component\MysqlClient\Exception\ConnectionException;
9
use Thruster\Component\MysqlClient\Exception\QueryException;
10
use Thruster\Component\Promise\Deferred;
11
use Thruster\Component\Promise\ExtendedPromiseInterface;
12
use Thruster\Component\Promise\FulfilledPromise;
13
use Thruster\Component\Promise\RejectedPromise;
14
15
/**
16
 * Class Client
17
 *
18
 * @package Thruster\Component\MysqlClient
19
 * @author  Aurimas Niekis <[email protected]>
20
 */
21
class Client
22
{
23
    /**
24
     * @var EventLoopInterface
25
     */
26
    private $loop;
27
28
    /**
29
     * @var ConnectionPool
30
     */
31
    private $connectionPool;
32
33
    public function __construct(EventLoopInterface $loop, ConnectionPool $connectionPool)
34
    {
35
        $this->loop           = $loop;
36
        $this->connectionPool = $connectionPool;
37
    }
38
39
    public function query($sql) : ExtendedPromiseInterface
40
    {
41
        return $this->connectionPool->getConnection()->then(
42
            function (mysqli $connection) use ($sql) {
43
                $status = $connection->query($sql, MYSQLI_ASYNC);
44
45
                if (false === $status) {
46
                    $this->connectionPool->freeConnection($connection);
47
48
                    return new RejectedPromise(new QueryException($connection->error, $connection->errno));
49
                }
50
51
                $deferred = new Deferred();
52
53
                $this->loop->addPeriodicTimer(0.001, function (Timer $timer) use ($deferred, $connection) {
54
                    $links = $errors = $reject = [$connection];
55
56
                    mysqli_poll($links, $errors, $reject, 0);
57
                    $read = in_array($connection, $links, true);
58
                    $error = in_array($connection, $errors, true);
59
                    $reject = in_array($connection, $reject, true);
60
61
                    if ($read || $error || $reject) {
62
                        if ($read) {
63
                            $result = $connection->reap_async_query();
64
65
                            if (false === $result) {
66
                                $deferred->reject(QueryException::create($connection->error, $connection->errno));
67
                            } else {
68
                                $deferred->resolve($result);
69
                            }
70
                        } elseif ($error) {
71
                            $deferred->reject(QueryException::create($connection->error, $connection->errno));
72
                        } else {
73
                            $deferred->reject(new QueryException('Query was rejected'));
74
                        }
75
76
                        $timer->cancel();
77
                        $this->connectionPool->freeConnection($connection);
78
                    }
79
                });
80
81
                return $deferred->promise();
82
            }
83
        );
84
    }
85
86
    public function escape($input) : ExtendedPromiseInterface
87
    {
88
        return $this->connectionPool->getConnection()->then(
89
            function (mysqli $connection) use ($input) {
90
                $result = $connection->real_escape_string($input);
91
92
                $this->connectionPool->freeConnection($connection);
93
94
                return new FulfilledPromise($result);
95
            }
96
        );
97
    }
98
}
99