Completed
Push — master ( ae0103...9b98c5 )
by Joao
04:23 queued 56s
created

DbPdoDriver::createPboConnStr()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 11.1547

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 4
cts 17
cp 0.2353
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 15
nc 5
nop 1
crap 11.1547
1
<?php
2
3
namespace ByJG\AnyDataset\Store;
4
5
use ByJG\AnyDataset\DbDriverInterface;
6
use ByJG\AnyDataset\Exception\NotAvailableException;
7
use ByJG\AnyDataset\Dataset\DbIterator;
8
use ByJG\AnyDataset\Factory;
9
use ByJG\AnyDataset\Store\Helpers\SqlBind;
10
use ByJG\AnyDataset\Store\Helpers\SqlHelper;
11
use ByJG\Util\Uri;
12
use PDO;
13
use PDOStatement;
14
15
abstract class DbPdoDriver implements DbDriverInterface
16
{
17
18
    /**
19
     * @var PDO
20
     */
21
    protected $instance = null;
22
23
    protected $supportMultRowset = false;
24
25
    /**
26
     * @var Uri
27
     */
28
    protected $connectionUri;
29
30 13
    public function __construct(Uri $connUri, $preOptions = null, $postOptions = null)
31
    {
32 13
        $this->connectionUri = $connUri;
33
34 13
        if (!defined('PDO::ATTR_DRIVER_NAME')) {
35
            throw new NotAvailableException("Extension 'PDO' is not loaded");
36
        }
37
38 13
        if (!extension_loaded('pdo_' . strtolower($connUri->getScheme()))) {
39
            throw new NotAvailableException("Extension 'pdo_" . strtolower($connUri->getScheme()) . "' is not loaded");
40
        }
41
42 13
        $strcnn = $this->createPboConnStr($connUri);
43
44 13
        $this->createPdoInstance($strcnn, $preOptions, $postOptions);
45 13
    }
46
47 13
    protected function createPdoInstance($pdoConnectionString, $preOptions = null, $postOptions = null)
48
    {
49
        // Create Connection
50 13
        $this->instance = new PDO(
51 13
            $pdoConnectionString,
52 13
            $this->connectionUri->getUsername(),
53 13
            $this->connectionUri->getPassword(),
54
            (array) $preOptions
55 13
        );
56
57 13
        $this->connectionUri->withScheme($this->instance->getAttribute(PDO::ATTR_DRIVER_NAME));
58
59
        // Set Specific Attributes
60 13
        $this->instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
61 13
        $this->instance->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
62
63 13
        foreach ((array) $postOptions as $key => $value) {
64
            $this->instance->setAttribute($key, $value);
65 13
        }
66 13
    }
67
    
68 13
    protected function createPboConnStr(Uri $connUri)
69
    {
70 13
        $host = $connUri->getHost();
71 13
        if (empty($host)) {
72 13
            return $connUri->getScheme() . ":" . $connUri->getPath();
73
        }
74
75
        $database = preg_replace('~^/~', '', $connUri->getPath());
76
        if (!empty($database)) {
77
            $database = ";dbname=$database";
78
        }
79
80
        $strcnn = $connUri->getScheme() . ":"
81
            . "host=" . $connUri->getHost()
82
            . $database;
83
84
        if ($connUri->getPort() != "") {
85
            $strcnn .= ";port=" . $connUri->getPort();
86
        }
87
88
        $query = $connUri->getQuery();
89
        $strcnn .= ";" . implode(';', explode('&', $query));
90
91
        return $strcnn;
92
    }
93
    
94 1
    public function __destruct()
95
    {
96 1
        $this->instance = null;
97 1
    }
98
99
    /**
100
     *
101
     * @param string $sql
102
     * @param array $array
103
     * @return PDOStatement
104
     */
105 13
    protected function getDBStatement($sql, $array = null)
106
    {
107 13
        list($sql, $array) = SqlBind::parseSQL($this->connectionUri, $sql, $array);
108
109 13
        $stmt = $this->instance->prepare($sql);
110
111 13
        if (!empty($array)) {
112 8
            foreach ($array as $key => $value) {
113 8
                $stmt->bindValue(":" . SqlBind::keyAdj($key), $value);
114 8
            }
115 8
        }
116
117 13
        return $stmt;
118
    }
119
120 8
    public function getIterator($sql, $params = null)
121
    {
122 8
        $stmt = $this->getDBStatement($sql, $params);
123 8
        $stmt->execute();
124 8
        $iterator = new DbIterator($stmt);
125 8
        return $iterator;
126
    }
127
128 5
    public function getScalar($sql, $array = null)
129
    {
130 5
        $stmt = $this->getDBStatement($sql, $array);
131 5
        $stmt->execute();
132
133 5
        $scalar = $stmt->fetchColumn();
134
135 5
        $stmt->closeCursor();
136
137 5
        return $scalar;
138
    }
139
140
    public function getAllFields($tablename)
141
    {
142
        $fields = array();
143
        $statement = $this->instance->query(
144
            SqlHelper::createSafeSQL(
145
                "select * from @@table where 0=1",
146
                [
147
                    "@@table" => $tablename
148
                ]
149
            )
150
        );
151
        $fieldLength = $statement->columnCount();
152
        for ($i = 0; $i < $fieldLength; $i++) {
153
            $fld = $statement->getColumnMeta($i);
154
            $fields[] = strtolower($fld ["name"]);
155
        }
156
        return $fields;
157
    }
158
159 3
    public function beginTransaction()
160
    {
161 3
        $this->instance->beginTransaction();
162 3
    }
163
164 2
    public function commitTransaction()
165
    {
166 2
        $this->instance->commit();
167 2
    }
168
169 2
    public function rollbackTransaction()
170
    {
171 2
        $this->instance->rollBack();
172 2
    }
173
174 13
    public function execute($sql, $array = null)
175
    {
176 13
        $stmt = $this->getDBStatement($sql, $array);
177 13
        $result = $stmt->execute();
178
179 13
        if ($this->isSupportMultRowset()) {
180
            // Check error
181
            do {
0 ignored issues
show
Unused Code introduced by
This do loop is empty and can be removed.

This check looks for do loops that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

Consider removing the loop.

Loading history...
182
                // This loop is only to throw an error (if exists)
183
                // in case of execute multiple queries
184
            } while ($stmt->nextRowset());
185
        }
186
187 13
        return $result;
188
    }
189
190 4
    public function executeAndGetId($sql, $array = null)
191
    {
192 4
        return $this->getDbHelper()->executeAndGetInsertedId($this, $sql, $array);
193
    }
194
195
    /**
196
     *
197
     * @return PDO
198
     */
199 1
    public function getDbConnection()
200
    {
201 1
        return $this->instance;
202
    }
203
204
    public function getAttribute($name)
205
    {
206
        $this->instance->getAttribute($name);
207
    }
208
209
    public function setAttribute($name, $value)
210
    {
211
        $this->instance->setAttribute($name, $value);
212
    }
213
214
    protected $dbHelper;
215
216 5
    public function getDbHelper()
217
    {
218 5
        if (empty($this->dbHelper)) {
219 5
            $this->dbHelper = Factory::getDbFunctions($this->connectionUri);
220 5
        }
221 5
        return $this->dbHelper;
222
    }
223
224 1
    public function getUri()
225
    {
226 1
        return $this->connectionUri;
227
    }
228
229
    /**
230
     * @return bool
231
     */
232 13
    public function isSupportMultRowset()
233
    {
234 13
        return $this->supportMultRowset;
235
    }
236
237
    /**
238
     * @param bool $multipleRowSet
239
     */
240
    public function setSupportMultRowset($multipleRowSet)
241
    {
242
        $this->supportMultRowset = $multipleRowSet;
243
    }
244
}
245