Passed
Push — master ( 7ed858...861abc )
by Gabor
02:38
created

QueryAdapter::fetchData()   B

Complexity

Conditions 6
Paths 24

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 9.8875

Importance

Changes 0
Metric Value
cc 6
eloc 21
nc 24
nop 2
dl 0
loc 39
ccs 11
cts 21
cp 0.5238
crap 9.8875
rs 8.9617
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\MySQL;
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 QueryAdapter
25
 */
26
class QueryAdapter implements QueryInterface
27
{
28
    /**
29
     * @var DriverInterface
30
     */
31
    protected $driverAdapter;
32
33
    /**
34
     * @var array
35
     */
36
    protected $identifierList;
37
38
    /**
39
     * @var string
40
     */
41
    protected static $statementPath = __DIR__.'/../MySQL/statements/*.sql';
42
43
    /**
44
     * QueryInterface constructor.
45
     *
46
     * @param DriverInterface $driverAdapter
47
     */
48
    public function __construct(DriverInterface $driverAdapter)
49
    {
50
        $this->driverAdapter = $driverAdapter;
51
        $this->init();
52
    }
53
54
    /**
55
     * Collects all the valid statements.
56
     */
57
    protected function init() : void
58
    {
59
        $this->identifierList = [];
60
        $statementFiles = glob(static::$statementPath, GLOB_BRACE);
61
62
        foreach ($statementFiles as $file) {
63
            $this->identifierList[basename($file, '.sql')] = $file;
64
        }
65
    }
66
67
    /**
68
     * Returns the Data Driver instance.
69
     *
70
     * @return DriverInterface
71
     */
72 1
    public function getDriver() : DriverInterface
73
    {
74 1
        return $this->driverAdapter;
75
    }
76
77
    /**
78
     * Fetches data buy executing a query identified by ID.
79
     *
80
     * @param string $query
81
     * @param array $parameters
82
     * @throws InvalidArgumentException
83
     * @throws RuntimeException
84
     * @return array
85
     */
86 1
    public function fetchData(string $query, array $parameters = []) : array
87
    {
88 1
        if (isset($this->identifierList[$query])) {
89 1
            $query = file_get_contents($this->identifierList[$query]);
90
        }
91
92
        // This nasty trick helps us to be able to parameterize the ORDER BY statement.
93 1
        if (isset($parameters[':orderBy'])) {
94
            $orderBy = $parameters[':orderBy'];
95
            unset($parameters[':orderBy']);
96
97
            $query = str_replace(':orderBy', $orderBy, $query);
98
        }
99
100
        /** @var SQLDriverAdapter $driver */
101 1
        $driver = $this->getDriver();
102 1
        $statement = $driver->prepare($query);
103
104 1
        foreach ($parameters as $parameter => $value) {
105 1
            $statement->bindValue($parameter, $value, $this->getValueType($value));
106
        }
107
108
        try {
109 1
            $executedSuccessful = $statement->execute();
110
        } catch (\Throwable $exception) {
111
            throw new RuntimeException(
112
                sprintf('Error executing query for "%s". %s', $query, $exception->getMessage()),
113
                1000
114
            );
115
        }
116
117 1
        if (!$executedSuccessful) {
118
            throw new RuntimeException(
119
                sprintf('Error running query: "%s"', $query),
120
                1001
121
            );
122
        }
123
124 1
        return $statement->fetchAll(PDO::FETCH_ASSOC);
125
    }
126
127
    /**
128
     * Returns the PDO type of the value.
129
     *
130
     * @param mixed $value
131
     * @return int
132
     */
133 1
    protected function getValueType($value) : int
134
    {
135 1
        $type = PDO::PARAM_STR;
136
137 1
        if (is_numeric($value)) {
138 1
            $type = PDO::PARAM_INT;
139
        } elseif (is_null($value)) {
140
            $type = PDO::PARAM_NULL;
141
        } elseif (is_bool($value)) {
142
            $type = PDO::PARAM_BOOL;
143
        }
144
145 1
        return $type;
146
    }
147
}
148