/web/fuel/core/classes/database/pdo/connection.php

https://github.com/leonardteo/INSE6530 · PHP · 234 lines · 158 code · 40 blank · 36 comment · 13 complexity · 3994ffd34497abd890ff92d0ca8c0f18 MD5 · raw file

  1. <?php
  2. /**
  3. * PDO database connection.
  4. *
  5. * @package Fuel/Database
  6. * @category Drivers
  7. * @author Kohana Team
  8. * @copyright (c) 2008-2009 Kohana Team
  9. * @license http://kohanaphp.com/license
  10. */
  11. namespace Fuel\Core;
  12. class Database_PDO_Connection extends \Database_Connection {
  13. // PDO uses no quoting for identifiers
  14. protected $_identifier = '';
  15. // Allows transactions
  16. protected $_trans_enabled = false;
  17. // transaction errors
  18. public $trans_errors = false;
  19. // Know which kind of DB is used
  20. public $_db_type = '';
  21. protected function __construct($name, array $config)
  22. {
  23. parent::__construct($name, $config);
  24. if (isset($this->_config['identifier']))
  25. {
  26. // Allow the identifier to be overloaded per-connection
  27. $this->_identifier = (string) $this->_config['identifier'];
  28. }
  29. }
  30. public function connect()
  31. {
  32. if ($this->_connection)
  33. {
  34. return;
  35. }
  36. // Extract the connection parameters, adding required variabels
  37. extract($this->_config['connection'] + array(
  38. 'dsn' => '',
  39. 'username' => null,
  40. 'password' => null,
  41. 'persistent' => false,
  42. ));
  43. // Clear the connection parameters for security
  44. unset($this->_config['connection']);
  45. // determine db type
  46. $_dsn_find_collon = strpos($dsn, ':');
  47. $this->_db_type = $_dsn_find_collon ? substr($dsn, 0, $_dsn_find_collon) : null;
  48. // Force PDO to use exceptions for all errors
  49. $attrs = array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION);
  50. if ( ! empty($persistent))
  51. {
  52. // Make the connection persistent
  53. $attrs[\PDO::ATTR_PERSISTENT] = TRUE;
  54. }
  55. try
  56. {
  57. // Create a new PDO connection
  58. $this->_connection = new \PDO($dsn, $username, $password, $attrs);
  59. }
  60. catch (\PDOException $e)
  61. {
  62. throw new \Database_Exception($e->getMessage(), $e->getCode(), $e);
  63. }
  64. if ( ! empty($this->_config['charset']))
  65. {
  66. // Set the character set
  67. $this->set_charset($this->_config['charset']);
  68. }
  69. }
  70. public function disconnect()
  71. {
  72. // Destroy the PDO object
  73. $this->_connection = null;
  74. return TRUE;
  75. }
  76. public function set_charset($charset)
  77. {
  78. // Make sure the database is connected
  79. $this->_connection or $this->connect();
  80. // Execute a raw SET NAMES query
  81. $this->_connection->exec('SET NAMES '.$this->quote($charset));
  82. }
  83. public function query($type, $sql, $as_object)
  84. {
  85. // Make sure the database is connected
  86. $this->_connection or $this->connect();
  87. if ( ! empty($this->_config['profiling']))
  88. {
  89. // Benchmark this query for the current instance
  90. $benchmark = Profiler::start("Database ({$this->_instance})", $sql);
  91. }
  92. try
  93. {
  94. $result = $this->_connection->query($sql);
  95. }
  96. catch (\Exception $e)
  97. {
  98. if (isset($benchmark))
  99. {
  100. // This benchmark is worthless
  101. Profiler::delete($benchmark);
  102. }
  103. if ($type !== \DB::SELECT && $this->_trans_enabled)
  104. {
  105. // If we are using transactions, throwing an exception would defeat the purpose
  106. // We need to log the failures for transaction status
  107. if ( ! is_array($this->trans_errors))
  108. {
  109. $this->trans_errors = array();
  110. }
  111. $this->trans_errors[] = $e->getMessage().' with query: "'.$sql.'"';
  112. return false;
  113. }
  114. else
  115. {
  116. // Convert the exception in a database exception
  117. throw new \Database_Exception($e->getMessage().' with query: "'.$sql.'"');
  118. }
  119. }
  120. if (isset($benchmark))
  121. {
  122. Profiler::stop($benchmark);
  123. }
  124. // Set the last query
  125. $this->last_query = $sql;
  126. if ($type === \DB::SELECT)
  127. {
  128. // Convert the result into an array, as PDOStatement::rowCount is not reliable
  129. if ($as_object === FALSE)
  130. {
  131. $result->setFetchMode(\PDO::FETCH_ASSOC);
  132. }
  133. elseif (is_string($as_object))
  134. {
  135. $result->setFetchMode(\PDO::FETCH_CLASS, $as_object);
  136. }
  137. else
  138. {
  139. $result->setFetchMode(\PDO::FETCH_CLASS, 'stdClass');
  140. }
  141. $result = $result->fetchAll();
  142. // Return an iterator of results
  143. return new \Database_Result_Cached($result, $sql, $as_object);
  144. }
  145. elseif ($type === \DB::INSERT)
  146. {
  147. // Return a list of insert id and rows created
  148. return array(
  149. $this->_connection->lastInsertId(),
  150. $result->rowCount(),
  151. );
  152. }
  153. else
  154. {
  155. // Return the number of rows affected
  156. return $result->errorCode() === '00000' ? $result->rowCount() : -1;
  157. }
  158. }
  159. public function list_tables($like = null)
  160. {
  161. throw new \Fuel_Exception('Database method '.__METHOD__.' is not supported by '.__CLASS__);
  162. }
  163. public function list_columns($table, $like = null)
  164. {
  165. throw new \Fuel_Exception('Database method '.__METHOD__.' is not supported by '.__CLASS__);
  166. }
  167. public function escape($value)
  168. {
  169. // Make sure the database is connected
  170. $this->_connection or $this->connect();
  171. return $this->_connection->quote($value);
  172. }
  173. public function transactional($use_trans = true)
  174. {
  175. if (is_bool($use_trans))
  176. {
  177. $this->_trans_enabled = $use_trans;
  178. }
  179. }
  180. public function start_transaction()
  181. {
  182. $this->transactional();
  183. $this->_connection or $this->connect();
  184. $this->_connection->beginTransaction();
  185. }
  186. public function commit_transaction()
  187. {
  188. $this->_connection->commit();
  189. }
  190. public function rollback_transaction()
  191. {
  192. $this->_connection->rollBack();
  193. }
  194. } // End Database_PDO