Passed
Push — master ( 480c95...b5488a )
by Gabor
03:51
created

SqlQueryAdapter::fetchData()   B

Complexity

Conditions 6
Paths 13

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 11.7224

Importance

Changes 0
Metric Value
cc 6
eloc 24
nc 13
nop 2
dl 0
loc 44
ccs 11
cts 24
cp 0.4583
crap 11.7224
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2018 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link http://www.gixx-web.com
11
 */
12
declare(strict_types = 1);
13
14
namespace WebHemi\Data\Query\SQL;
15
16
use InvalidArgumentException;
17
use PDO;
18
use RuntimeException;
19
use WebHemi\Data\Driver\DriverInterface;
20
use WebHemi\Data\Driver\PDO\MySQL\DriverAdapter as SQLDriverAdapter;
21
use WebHemi\Data\Query\QueryInterface;
22
23
/**
24
 * Class SqlQueryAdapter
25
 */
26
class SqlQueryAdapter implements QueryInterface
27
{
28
    /**
29
     * @var DriverInterface
30
     */
31
    private $driverAdapter;
32
33
    /**
34
     * @var array
35
     */
36
    private $identifierList = [];
37
38
    /**
39
     * QueryInterface constructor.
40
     *
41
     * @param DriverInterface $driverAdapter
42
     */
43
    public function __construct(DriverInterface $driverAdapter)
44
    {
45
        $this->driverAdapter = $driverAdapter;
46
        $this->init();
47
    }
48
49
    /**
50
     * Collects all the valid statements.
51
     */
52
    private function init() : void
53
    {
54
        $statementFiles = glob(__DIR__.'/statements/*.sql', GLOB_BRACE);
55
56
        foreach ($statementFiles as $file) {
57
            $this->identifierList[basename($file, '.sql')] = $file;
58
        }
59
    }
60
61
    /**
62
     * Returns the Data Driver instance.
63
     *
64
     * @return DriverInterface
65
     */
66 1
    public function getDriver() : DriverInterface
67
    {
68 1
        return $this->driverAdapter;
69
    }
70
71
    /**
72
     * Returns all the query identifiers assigned to the query adapter.
73
     *
74
     * @return array
75
     */
76
    public function getQueryIdentifierList() : array
77
    {
78
        return $this->identifierList;
79
    }
80
81
    /**
82
     * Fetches data buy executing a query identified by ID.
83
     *
84
     * @param string $queryIdentifier
85
     * @param array $parameters
86
     * @throws InvalidArgumentException
87
     * @throws RuntimeException
88
     * @return array
89
     */
90 1
    public function fetchData(string $queryIdentifier, array $parameters = []) : array
91
    {
92 1
        if (!isset($this->identifierList[$queryIdentifier])) {
93
            throw new InvalidArgumentException(
94
                sprintf('No such query found for this adapter: "%s"', $queryIdentifier),
95
                1000
96
            );
97
        }
98
99 1
        $query = file_get_contents($this->identifierList[$queryIdentifier]);
100
101
        // This nasty trick helps us to be able to parameterize the ORDER BY statement.
102 1
        if (isset($parameters[':orderBy'])) {
103
            $orderBy = $parameters[':orderBy'];
104
            unset($parameters[':orderBy']);
105
106
            $query = str_replace(':orderBy', $orderBy, $query);
107
        }
108
109
        /** @var SQLDriverAdapter $driver */
110 1
        $driver = $this->getDriver();
111 1
        $statement = $driver->prepare($query);
112
113 1
        foreach ($parameters as $parameter => $value) {
114 1
            $statement->bindValue($parameter, $value, $this->getValueType($value));
115
        }
116
117
        try {
118 1
            $executedSuccessful = $statement->execute();
119
        } catch (\Throwable $exception) {
120
            throw new RuntimeException(
121
                sprintf('Error executing query for "%s". %s', $queryIdentifier, $exception->getMessage()),
122
                1000
123
            );
124
        }
125
126 1
        if (!$executedSuccessful) {
127
            throw new RuntimeException(
128
                sprintf('Error running query: "%s"', $queryIdentifier),
129
                1001
130
            );
131
        }
132
133 1
        return $statement->fetchAll(PDO::FETCH_ASSOC);
134
    }
135
136
    /**
137
     * Returns the PDO type of the value.
138
     *
139
     * @param mixed $value
140
     * @return int
141
     */
142 1
    private function getValueType($value) : int
143
    {
144 1
        $type = PDO::PARAM_STR;
145
146 1
        if (is_numeric($value)) {
147 1
            $type = PDO::PARAM_INT;
148
        } elseif (is_null($value)) {
149
            $type = PDO::PARAM_NULL;
150
        } elseif (is_bool($value)) {
151
            $type = PDO::PARAM_BOOL;
152
        }
153
154 1
        return $type;
155
    }
156
}
157