Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TDbConnection class file
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TDbConnection.php 2505 2008-08-27 15:06:25Z tof $
10
 * @package System.Data
11
 */
12
 
13
Prado::using('System.Data.TDbTransaction');
14
Prado::using('System.Data.TDbCommand');
15
 
16
/**
17
 * TDbConnection class
18
 *
19
 * TDbConnection represents a connection to a database.
20
 *
21
 * TDbConnection works together with {@link TDbCommand}, {@link TDbDataReader}
22
 * and {@link TDbTransaction} to provide data access to various DBMS
23
 * in a common set of APIs. They are a thin wrapper of the {@link http://www.php.net/manual/en/ref.pdo.php PDO}
24
 * PHP extension.
25
 *
26
 * To establish a connection, set {@link setActive Active} to true after
27
 * specifying {@link setConnectionString ConnectionString}, {@link setUsername Username}
28
 * and {@link setPassword Password}.
29
 *
30
 * Since 3.1.2, the connection charset can be set (for MySQL and PostgreSQL databases only)
31
 * using the {@link setCharset Charset} property. The value of this property is database dependant.
32
 * e.g. for mysql, you can use 'latin1' for cp1252 West European, 'utf8' for unicode, ...
33
 *
34
 * The following example shows how to create a TDbConnection instance and establish
35
 * the actual connection:
36
 * <code>
37
 * $connection=new TDbConnection($dsn,$username,$password);
38
 * $connection->Active=true;
39
 * </code>
40
 *
41
 * After the DB connection is established, one can execute an SQL statement like the following:
42
 * <code>
43
 * $command=$connection->createCommand($sqlStatement);
44
 * $command->execute();   // a non-query SQL statement execution
45
 * // or execute an SQL query and fetch the result set
46
 * $reader=$command->query();
47
 *
48
 * // each $row is an array representing a row of data
49
 * foreach($reader as $row) ...
50
 * </code>
51
 *
52
 * One can do prepared SQL execution and bind parameters to the prepared SQL:
53
 * <code>
54
 * $command=$connection->createCommand($sqlStatement);
55
 * $command->bindParameter($name1,$value1);
56
 * $command->bindParameter($name2,$value2);
57
 * $command->execute();
58
 * </code>
59
 *
60
 * To use transaction, do like the following:
61
 * <code>
62
 * $transaction=$connection->beginTransaction();
63
 * try
64
 * {
65
 *    $connection->createCommand($sql1)->execute();
66
 *    $connection->createCommand($sql2)->execute();
67
 *    //.... other SQL executions
68
 *    $transaction->commit();
69
 * }
70
 * catch(Exception $e)
71
 * {
72
 *    $transaction->rollBack();
73
 * }
74
 * </code>
75
 *
76
 * TDbConnection provides a set of methods to support setting and querying
77
 * of certain DBMS attributes, such as {@link getNullConversion NullConversion}.
78
 *
79
 * @author Qiang Xue <qiang.xue@gmail.com>
80
 * @version $Id: TDbConnection.php 2505 2008-08-27 15:06:25Z tof $
81
 * @package System.Data
82
 * @since 3.0
83
 */
84
class TDbConnection extends TComponent
85
{
86
	private $_dsn='';
87
	private $_username='';
88
	private $_password='';
89
	private $_charset='';
90
	private $_attributes=array();
91
	private $_active=false;
92
	private $_pdo=null;
93
	private $_transaction;
94
 
95
	/**
96
	 * Constructor.
97
	 * Note, the DB connection is not established when this connection
98
	 * instance is created. Set {@link setActive Active} property to true
99
	 * to establish the connection.
100
	 * Since 3.1.2, you can set the charset for MySql connection
101
	 *
102
	 * @param string The Data Source Name, or DSN, contains the information required to connect to the database.
103
	 * @param string The user name for the DSN string.
104
	 * @param string The password for the DSN string.
105
	 * @param string Charset used for DB Connection (MySql & pgsql only). If not set, will use the default charset of your database server
106
	 * @see http://www.php.net/manual/en/function.PDO-construct.php
107
	 */
108
	public function __construct($dsn='',$username='',$password='', $charset='')
109
	{
110
		$this->_dsn=$dsn;
111
		$this->_username=$username;
112
		$this->_password=$password;
113
		$this->_charset=$charset;
114
	}
115
 
116
	/**
117
	 * Close the connection when serializing.
118
	 */
119
	public function __sleep()
120
	{
121
		$this->close();
122
		return array_keys(get_object_vars($this));
123
	}
124
 
125
	/**
126
	 * @return array list of available PDO drivers
127
	 * @see http://www.php.net/manual/en/function.PDO-getAvailableDrivers.php
128
	 */
129
	public static function getAvailableDrivers()
130
	{
131
		return PDO::getAvailableDrivers();
132
	}
133
 
134
	/**
135
	 * @return boolean whether the DB connection is established
136
	 */
137
	public function getActive()
138
	{
139
		return $this->_active;
140
	}
141
 
142
	/**
143
	 * Open or close the DB connection.
144
	 * @param boolean whether to open or close DB connection
145
	 * @throws TDbException if connection fails
146
	 */
147
	public function setActive($value)
148
	{
149
		$value=TPropertyValue::ensureBoolean($value);
150
		if($value!==$this->_active)
151
		{
152
			if($value)
153
				$this->open();
154
			else
155
				$this->close();
156
		}
157
	}
158
 
159
	/**
160
	 * Opens DB connection if it is currently not
161
	 * @throws TDbException if connection fails
162
	 */
163
	protected function open()
164
	{
165
		if($this->_pdo===null)
166
		{
167
			try
168
			{
169
				$this->_pdo=new PDO($this->getConnectionString(),$this->getUsername(),
170
									$this->getPassword(),$this->_attributes);
171
				// This attribute is only useful for PDO::MySql driver.
172
				// Ignore the warning if a driver doesn't understand this.
173
				@$this->_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
174
				$this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
175
				$this->_active=true;
176
				$this->setConnectionCharset();
177
			}
178
			catch(PDOException $e)
179
			{
180
				throw new TDbException('dbconnection_open_failed',$e->getMessage());
181
			}
182
		}
183
	}
184
 
185
	/**
186
	 * Closes the currently active DB connection.
187
	 * It does nothing if the connection is already closed.
188
	 */
189
	protected function close()
190
	{
191
		$this->_pdo=null;
192
		$this->_active=false;
193
	}
194
 
195
	/*
196
	 * Set the database connection charset.
197
	 * Only MySql databases are supported for now.
198
	 * @since 3.1.2
199
	 */
200
	protected function setConnectionCharset()
201
	{
202
		if ($this->_charset === '' || $this->_active === false)
203
			return;
204
		switch ($this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME))
205
		{
206
			case 'mysql':
207
				$stmt = $this->_pdo->prepare('SET CHARACTER SET ?');
208
			break;
209
			case 'pgsql':
210
				$stmt = $this->_pdo->prepare('SET client_encoding TO ?');
211
			break;
212
		}
213
		$stmt->execute(array($this->_charset));
214
	}
215
 
216
	/**
217
	 * @return string The Data Source Name, or DSN, contains the information required to connect to the database.
218
	 */
219
	public function getConnectionString()
220
	{
221
		return $this->_dsn;
222
	}
223
 
224
	/**
225
	 * @param string The Data Source Name, or DSN, contains the information required to connect to the database.
226
	 * @see http://www.php.net/manual/en/function.PDO-construct.php
227
	 */
228
	public function setConnectionString($value)
229
	{
230
		$this->_dsn=$value;
231
	}
232
 
233
	/**
234
	 * @return string the username for establishing DB connection. Defaults to empty string.
235
	 */
236
	public function getUsername()
237
	{
238
		return $this->_username;
239
	}
240
 
241
	/**
242
	 * @param string the username for establishing DB connection
243
	 */
244
	public function setUsername($value)
245
	{
246
		$this->_username=$value;
247
	}
248
 
249
	/**
250
	 * @return string the password for establishing DB connection. Defaults to empty string.
251
	 */
252
	public function getPassword()
253
	{
254
		return $this->_password;
255
	}
256
 
257
	/**
258
	 * @param string the password for establishing DB connection
259
	 */
260
	public function setPassword($value)
261
	{
262
		$this->_password=$value;
263
	}
264
 
265
	/**
266
	 * @return string the charset used for database connection. Defaults to emtpy string.
267
	 */
268
	public function getCharset ()
269
	{
270
		return $this>_charset;
271
	}
272
 
273
	/**
274
	 * @param string the charset used for database connection
275
	 */
276
	public function setCharset ($value)
277
	{
278
		$this->_charset=$value;
279
		$this->setConnectionCharset();
280
	}
281
 
282
	/**
283
	 * @return PDO the PDO instance, null if the connection is not established yet
284
	 */
285
	public function getPdoInstance()
286
	{
287
		return $this->_pdo;
288
	}
289
 
290
	/**
291
	 * Creates a command for execution.
292
	 * @param string SQL statement associated with the new command.
293
	 * @return TDbCommand the DB command
294
	 * @throws TDbException if the connection is not active
295
	 */
296
	public function createCommand($sql)
297
	{
298
		if($this->getActive())
299
			return new TDbCommand($this,$sql);
300
		else
301
			throw new TDbException('dbconnection_connection_inactive');
302
	}
303
 
304
	/**
305
	 * @return TDbTransaction the currently active transaction. Null if no active transaction.
306
	 */
307
	public function getCurrentTransaction()
308
	{
309
		if($this->_transaction!==null)
310
		{
311
			if($this->_transaction->getActive())
312
				return $this->_transaction;
313
		}
314
		return null;
315
	}
316
 
317
	/**
318
	 * Starts a transaction.
319
	 * @return TDbTransaction the transaction initiated
320
	 * @throws TDbException if the connection is not active
321
	 */
322
	public function beginTransaction()
323
	{
324
		if($this->getActive())
325
		{
326
			$this->_pdo->beginTransaction();
327
			return $this->_transaction=new TDbTransaction($this);
328
		}
329
		else
330
			throw new TDbException('dbconnection_connection_inactive');
331
	}
332
 
333
	/**
334
	 * Returns the ID of the last inserted row or sequence value.
335
	 * @param string name of the sequence object (required by some DBMS)
336
	 * @return string the row ID of the last row inserted, or the last value retrieved from the sequence object
337
	 * @see http://www.php.net/manual/en/function.PDO-lastInsertId.php
338
	 */
339
	public function getLastInsertID($sequenceName='')
340
	{
341
		if($this->getActive())
342
			return $this->_pdo->lastInsertId($sequenceName);
343
		else
344
			throw new TDbException('dbconnection_connection_inactive');
345
	}
346
 
347
	/**
348
	 * Quotes a string for use in a query.
349
	 * @param string string to be quoted
350
	 * @return string the properly quoted string
351
	 * @see http://www.php.net/manual/en/function.PDO-quote.php
352
	 */
353
	public function quoteString($str)
354
	{
355
		if($this->getActive())
356
			return $this->_pdo->quote($str);
357
		else
358
			throw new TDbException('dbconnection_connection_inactive');
359
	}
360
 
361
	/**
362
	 * @return TDbColumnCaseMode the case of the column names
363
	 */
364
	public function getColumnCase()
365
	{
366
		switch($this->getAttribute(PDO::ATTR_CASE))
367
		{
368
			case PDO::CASE_NATURAL:
369
				return TDbColumnCaseMode::Preserved;
370
			case PDO::CASE_LOWER:
371
				return TDbColumnCaseMode::LowerCase;
372
			case PDO::CASE_UPPER:
373
				return TDbColumnCaseMode::UpperCase;
374
		}
375
	}
376
 
377
	/**
378
	 * @param TDbColumnCaseMode the case of the column names
379
	 */
380
	public function setColumnCase($value)
381
	{
382
		switch(TPropertyValue::ensureEnum($value,'TDbColumnCaseMode'))
383
		{
384
			case TDbColumnCaseMode::Preserved:
385
				$value=PDO::CASE_NATURAL;
386
				break;
387
			case TDbColumnCaseMode::LowerCase:
388
				$value=PDO::CASE_LOWER;
389
				break;
390
			case TDbColumnCaseMode::UpperCase:
391
				$value=PDO::CASE_UPPER;
392
				break;
393
		}
394
		$this->setAttribute(PDO::ATTR_CASE,$value);
395
	}
396
 
397
	/**
398
	 * @return TDbNullConversionMode how the null and empty strings are converted
399
	 */
400
	public function getNullConversion()
401
	{
402
		switch($this->getAttribute(PDO::ATTR_ORACLE_NULLS))
403
		{
404
			case PDO::NULL_NATURAL:
405
				return TDbNullConversionMode::Preserved;
406
			case PDO::NULL_EMPTY_STRING:
407
				return TDbNullConversionMode::EmptyStringToNull;
408
			case PDO::NULL_TO_STRING:
409
				return TDbNullConversionMode::NullToEmptyString;
410
		}
411
	}
412
 
413
	/**
414
	 * @param TDbNullConversionMode how the null and empty strings are converted
415
	 */
416
	public function setNullConversion($value)
417
	{
418
		switch(TPropertyValue::ensureEnum($value,'TDbNullConversionMode'))
419
		{
420
			case TDbNullConversionMode::Preserved:
421
				$value=PDO::NULL_NATURAL;
422
				break;
423
			case TDbNullConversionMode::EmptyStringToNull:
424
				$value=PDO::NULL_EMPTY_STRING;
425
				break;
426
			case TDbNullConversionMode::NullToEmptyString:
427
				$value=PDO::NULL_TO_STRING;
428
				break;
429
		}
430
		$this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
431
	}
432
 
433
	/**
434
	 * @return boolean whether creating or updating a DB record will be automatically committed.
435
	 * Some DBMS (such as sqlite) may not support this feature.
436
	 */
437
	public function getAutoCommit()
438
	{
439
		return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
440
	}
441
 
442
	/**
443
	 * @param boolean whether creating or updating a DB record will be automatically committed.
444
	 * Some DBMS (such as sqlite) may not support this feature.
445
	 */
446
	public function setAutoCommit($value)
447
	{
448
		$this->setAttribute(PDO::ATTR_AUTOCOMMIT,TPropertyValue::ensureBoolean($value));
449
	}
450
 
451
	/**
452
	 * @return boolean whether the connection is persistent or not
453
	 * Some DBMS (such as sqlite) may not support this feature.
454
	 */
455
	public function getPersistent()
456
	{
457
		return $this->getAttribute(PDO::ATTR_PERSISTENT);
458
	}
459
 
460
	/**
461
	 * @param boolean whether the connection is persistent or not
462
	 * Some DBMS (such as sqlite) may not support this feature.
463
	 */
464
	public function setPersistent($value)
465
	{
466
		return $this->setAttribute(PDO::ATTR_PERSISTENT,TPropertyValue::ensureBoolean($value));
467
	}
468
 
469
	/**
470
	 * @return string name of the DB driver
471
	 */
472
	public function getDriverName()
473
	{
474
		return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
475
	}
476
 
477
	/**
478
	 * @return string the version information of the DB driver
479
	 */
480
	public function getClientVersion()
481
	{
482
		return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
483
	}
484
 
485
	/**
486
	 * @return string the status of the connection
487
	 * Some DBMS (such as sqlite) may not support this feature.
488
	 */
489
	public function getConnectionStatus()
490
	{
491
		return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
492
	}
493
 
494
	/**
495
	 * @return boolean whether the connection performs data prefetching
496
	 */
497
	public function getPrefetch()
498
	{
499
		return $this->getAttribute(PDO::ATTR_PREFETCH);
500
	}
501
 
502
	/**
503
	 * @return string the information of DBMS server
504
	 */
505
	public function getServerInfo()
506
	{
507
		return $this->getAttribute(PDO::ATTR_SERVER_INFO);
508
	}
509
 
510
	/**
511
	 * @return string the version information of DBMS server
512
	 */
513
	public function getServerVersion()
514
	{
515
		return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
516
	}
517
 
518
	/**
519
	 * @return int timeout settings for the connection
520
	 */
521
	public function getTimeout()
522
	{
523
		return $this->getAttribute(PDO::ATTR_TIMEOUT);
524
	}
525
 
526
	/**
527
	 * Obtains a specific DB connection attribute information.
528
	 * @param int the attribute to be queried
529
	 * @return mixed the corresponding attribute information
530
	 * @see http://www.php.net/manual/en/function.PDO-getAttribute.php
531
	 */
532
	public function getAttribute($name)
533
	{
534
		if($this->getActive())
535
			return $this->_pdo->getAttribute($name);
536
		else
537
			throw new TDbException('dbconnection_connection_inactive');
538
	}
539
 
540
	/**
541
	 * Sets an attribute on the database connection.
542
	 * @param int the attribute to be set
543
	 * @param mixed the attribute value
544
	 * @see http://www.php.net/manual/en/function.PDO-setAttribute.php
545
	 */
546
	public function setAttribute($name,$value)
547
	{
548
		if($this->_pdo instanceof PDO)
549
			$this->_pdo->setAttribute($name,$value);
550
		else
551
			$this->_attributes[$name]=$value;
552
	}
553
}
554
 
555
/**
556
 * TDbColumnCaseMode
557
 *
558
 * @author Qiang Xue <qiang.xue@gmail.com>
559
 * @version $Id: TDbConnection.php 2505 2008-08-27 15:06:25Z tof $
560
 * @package System.Data
561
 * @since 3.0
562
 */
563
class TDbColumnCaseMode extends TEnumerable
564
{
565
	/**
566
	 * Column name cases are kept as is from the database
567
	 */
568
	const Preserved='Preserved';
569
	/**
570
	 * Column names are converted to lower case
571
	 */
572
	const LowerCase='LowerCase';
573
	/**
574
	 * Column names are converted to upper case
575
	 */
576
	const UpperCase='UpperCase';
577
}
578
 
579
/**
580
 * TDbNullConversionMode
581
 *
582
 * @author Qiang Xue <qiang.xue@gmail.com>
583
 * @version $Id: TDbConnection.php 2505 2008-08-27 15:06:25Z tof $
584
 * @package System.Data
585
 * @since 3.0
586
 */
587
class TDbNullConversionMode extends TEnumerable
588
{
589
	/**
590
	 * No conversion is performed for null and empty values.
591
	 */
592
	const Preserved='Preserved';
593
	/**
594
	 * NULL is converted to empty string
595
	 */
596
	const NullToEmptyString='NullToEmptyString';
597
	/**
598
	 * Empty string is converted to NULL
599
	 */
600
	const EmptyStringToNull='EmptyStringToNull';
601
}
602
 
603
?>