Repository navigation
Expand file tree
/
Copy pathConnection.php
More file actions
347 lines (294 loc) · 7.35 KB
/
Copy pathConnection.php
File metadata and controls
347 lines (294 loc) · 7.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
<?php
/**
* SugiPHP Database Abstraction Layer Connection
*
* @package SugiPHP.DBAL
* @author Plamen Popov <tzappa@gmail.com>
* @license http://opensource.org/licenses/mit-license.php (MIT License)
*/
namespace SugiPHP\DBAL;
use PDO;
class Connection extends PDO implements PdoInterface
{
/**
* The Data Source Name.
*
* @var string
*/
protected $dsn;
/**
* The user name for the DSN string. This parameter is optional for some PDO drivers.
*
* @var string
*/
protected $username;
/**
* The password for the DSN string. This parameter is optional for some PDO drivers.
*
* @var string
*/
protected $password;
/**
* A key=>value array of driver-specific connection options.
*
* @var array
*/
protected $options;
/**
* A key=>value array of common and driver-specific attributes on the database handle.
*
* @var array
*/
protected $attributes = array(
// Set error handling to Exception
self::ATTR_ERRMODE => self::ERRMODE_EXCEPTION,
// Fetch return results as associative array
self::ATTR_DEFAULT_FETCH_MODE => self::FETCH_ASSOC,
);
protected $pdo;
protected $eventListener;
/**
* Needed for establishing a lazy connection.
*
* @param string $dsn
* @param string $username
* @param string $password
* @param array $options
*/
public function __construct($dsn, $username = "", $password = "", array $options = array())
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->options = $options;
}
/**
* Establishing connection with the database.
* After connecting to the database sets attributes.
*
* @throws PDOException if the attempt to connect to the requested database fails.
*/
public function connect()
{
if ($this->pdo) {
return ;
}
$event = $this->startEvent(__FUNCTION__);
// establish database connection
parent::__construct($this->dsn, $this->username, $this->password, $this->options);
$this->endEvent($event);
$this->pdo = $this;
foreach ($this->attributes as $attribute => $value) {
parent::setAttribute($attribute, $value);
}
// Use custom PDOStatement to log/profile execute methods
parent::setAttribute(PDO::ATTR_STATEMENT_CLASS, array("\\SugiPHP\\DBAL\\Statement", array($this)));
}
/**
* Set an attribute.
*
* @see http://php.net/manual/en/pdo.setattribute.php
*
* @param int $attribute
* @param mixed $value
*
* @return boolean TRUE on success or FALSE on failure.
*/
public function setAttribute($attribute, $value)
{
// If the connection is established set attribute right away
if ($this->pdo) {
return parent::setAttribute($attribute, $value);
}
// otherwise store it until connection is established
$this->attributes[$attribute] = $value;
// 100% success rate!
return true;
}
/**
* Retrieve a database connection attribute.
*
* @param int $attribute
*
* @return mixed
*/
public function getAttribute($attribute)
{
// If the connection is not established
// but we set the attribute already
if (!$this->pdo && isset($this->attributes[$attribute])) {
return $this->attributes[$attribute];
}
$this->connect();
return parent::getAttribute($attribute);
}
/**
* Fetch the SQLSTATE associated with the last operation on the database handle
*
* @return mixed Returns NULL if no operation has been run on the database handle.
*/
public function errorCode()
{
$this->connect();
return parent::errorCode();
}
/**
* Fetch extended error information associated with the last operation on the database handle.
*
* @return array
*/
public function errorInfo()
{
$this->connect();
return parent::errorInfo();
}
/**
* Execute an SQL statement and return the number of affected rows.
*
* @param string $statement
*
* @return int|FALSE Returns the number of rows that were modified or deleted
* by the SQL statement you issued. If no rows were affected, exec() returns 0.
* boolean FALSE is returned if the statement fails.
*/
public function exec($statement)
{
$this->connect();
$event = $this->startEvent(__FUNCTON__, $statement);
$result = parent::exec($statement);
$this->endEvent($event);
return $result;
}
/**
* Executes an SQL statement, returning a result set as a PDOStatement object
* NOTE: The query() method can receive not only one, but 3 or 4 parameters.
*
* @see http://php.net/manual/en/pdo.query.php
*
* @param string $statement
*
* @return PDOStatement or FALSE on failure.
*/
public function query($statement)
{
$this->connect();
$args = func_get_args();
$argsCnt = count($args);
$event = $this->startEvent(__FUNCTION__, $statement);
if ($argsCnt == 2) {
$result = parent::query($statement, $args[1]);
} elseif ($argsCnt == 3) {
$result = parent::query($statement, $args[1], $args[2]);
} elseif ($argsCnt == 4) {
$result = parent::query($statement, $args[1], $args[2], $args[3]);
} else {
$result = parent::query($statement);
}
$this->endEvent($event);
return $result;
}
/**
* Prepares a statement for execution and returns a statement object.
*
* @param string $statement
* @param array $options Driver options
*
* @return PDOStatement, FALSE or emits PDOException (depending on error handling).
*/
public function prepare($statement, $options = array())
{
$this->connect();
return parent::prepare($statement, $options);
}
/**
* Returns the ID of the last inserted row or sequence value.
*
* @param string $name Name of the sequence object from which the ID should be returned
*
* @return string
*/
public function lastInsertId($name = null)
{
$this->connect();
return parent::lastInsertId($name);
}
/**
* Quotes a string for use in a query.
*
* @param string $string The string to be quoted.
* @param int $parameter_type Provides a data type hint for drivers that have alternate quoting styles.
*
* @return string
*/
public function quote($string, $parameter_type = PDO::PARAM_STR)
{
$this->connect();
return parent::quote($string, $parameter_type);
}
/**
* Initiates a transaction.
*
* @return boolean TRUE on success or FALSE on failure.
*/
public function beginTransaction()
{
$this->connect();
return parent::beginTransaction();
}
/**
* Checks if inside a transaction.
*
* @return boolean TRUE if a transaction is currently active, and FALSE if not.
*/
public function inTransaction()
{
$this->connect();
return parent::inTransaction();
}
/**
* Commits a transaction.
*
* @return boolean TRUE on success or FALSE on failure.
*/
public function commit()
{
$this->connect();
return parent::commit();
}
/**
* Rolls back a transaction
*
* @return boolean TRUE on success or FALSE on failure.
*/
public function rollBack()
{
$this->connect();
return parent::rollBack();
}
public function setEventListener(callable $callable)
{
$this->eventListener = $callable;
}
public function startEvent($function, $statement = null)
{
if (!$this->eventListener) {
return ;
}
$event = array(
"function" => $function,
"statement" => $statement,
"start" => microtime(true),
);
return $event;
}
public function endEvent($event)
{
if ($event && $this->eventListener) {
$event["end"] = microtime(true);
$event["duration"] = $event["end"] - $event["start"];
$func = $this->eventListener;
$func($event);
}
return $event;
}
}