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 { |
|
|
|
|
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
|
|
|
|
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.