/library/Zend/Db/Adapter/Driver/Pdo/Connection.php

https://github.com/bate/zf2 · PHP · 370 lines · 234 code · 40 blank · 96 comment · 24 complexity · 70b94c7e64fd248a2e3d141e06ab5526 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Db
  9. */
  10. namespace Zend\Db\Adapter\Driver\Pdo;
  11. use Zend\Db\Adapter\Driver\ConnectionInterface;
  12. use Zend\Db\Adapter\Driver\DriverInterface;
  13. use Zend\Db\Adapter\Exception;
  14. /**
  15. * @category Zend
  16. * @package Zend_Db
  17. * @subpackage Adapter
  18. */
  19. class Connection implements ConnectionInterface
  20. {
  21. /**
  22. * @var Pdo
  23. */
  24. protected $driver = null;
  25. /**
  26. * @var string
  27. */
  28. protected $driverName = null;
  29. /**
  30. * @var array
  31. */
  32. protected $connectionParameters = array();
  33. /**
  34. * @var \PDO
  35. */
  36. protected $resource = null;
  37. /**
  38. * @var bool
  39. */
  40. protected $inTransaction = false;
  41. /**
  42. * @param array|\PDO|null $connectionParameters
  43. * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
  44. */
  45. public function __construct($connectionParameters = null)
  46. {
  47. if (is_array($connectionParameters)) {
  48. $this->setConnectionParameters($connectionParameters);
  49. } elseif ($connectionParameters instanceof \PDO) {
  50. $this->setResource($connectionParameters);
  51. } elseif (null !== $connectionParameters) {
  52. throw new Exception\InvalidArgumentException('$connection must be an array of parameters, a PDO object or null');
  53. }
  54. }
  55. /**
  56. * @param Pdo $driver
  57. * @return Connection
  58. */
  59. public function setDriver(Pdo $driver)
  60. {
  61. $this->driver = $driver;
  62. return $this;
  63. }
  64. /**
  65. * @return null|string
  66. */
  67. public function getDriverName()
  68. {
  69. return $this->driverName;
  70. }
  71. /**
  72. * @param array $connectionParameters
  73. */
  74. public function setConnectionParameters(array $connectionParameters)
  75. {
  76. $this->connectionParameters = $connectionParameters;
  77. if (isset($connectionParameters['dsn'])) {
  78. $this->driverName = substr($connectionParameters['dsn'], 0,
  79. strpos($connectionParameters['dsn'], ':')
  80. );
  81. } elseif (isset($connectionParameters['pdodriver'])) {
  82. $this->driverName = strtolower($connectionParameters['pdodriver']);
  83. } elseif (isset($connectionParameters['driver'])) {
  84. $this->driverName = strtolower(substr(
  85. str_replace(array('-', '_', ' '), '', $connectionParameters['driver']),
  86. 3
  87. ));
  88. }
  89. }
  90. /**
  91. * @return array
  92. */
  93. public function getConnectionParameters()
  94. {
  95. return $this->connectionParameters;
  96. }
  97. /**
  98. * Get current schema
  99. *
  100. * @return string
  101. */
  102. public function getCurrentSchema()
  103. {
  104. if (!$this->isConnected()) {
  105. $this->connect();
  106. }
  107. switch ($this->driverName) {
  108. case 'mysql':
  109. $sql = 'SELECT DATABASE()';
  110. break;
  111. case 'sqlite':
  112. return 'main';
  113. case 'pgsql':
  114. default:
  115. $sql = 'SELECT CURRENT_SCHEMA';
  116. break;
  117. }
  118. /** @var $result \PDOStatement */
  119. $result = $this->resource->query($sql);
  120. if ($result instanceof \PDOStatement) {
  121. return $result->fetchColumn();
  122. }
  123. return false;
  124. }
  125. /**
  126. * Set resource
  127. *
  128. * @param \PDO $resource
  129. * @return Connection
  130. */
  131. public function setResource(\PDO $resource)
  132. {
  133. $this->resource = $resource;
  134. $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
  135. return $this;
  136. }
  137. /**
  138. * @return \PDO
  139. */
  140. public function getResource()
  141. {
  142. return $this->resource;
  143. }
  144. /**
  145. * @return Connection
  146. * @throws \Exception
  147. */
  148. public function connect()
  149. {
  150. if ($this->resource) {
  151. return $this;
  152. }
  153. $dsn = $username = $password = $hostname = $database = null;
  154. $options = array();
  155. foreach ($this->connectionParameters as $key => $value) {
  156. switch (strtolower($key)) {
  157. case 'dsn':
  158. $dsn = $value;
  159. break;
  160. case 'driver':
  161. $value = strtolower($value);
  162. if (strpos($value, 'pdo') === 0) {
  163. $pdoDriver = strtolower(substr(str_replace(array('-', '_', ' '), '', $value), 3));
  164. }
  165. break;
  166. case 'pdodriver':
  167. $pdoDriver = (string) $value;
  168. break;
  169. case 'user':
  170. case 'username':
  171. $username = (string) $value;
  172. break;
  173. case 'pass':
  174. case 'password':
  175. $password = (string) $value;
  176. break;
  177. case 'host':
  178. case 'hostname':
  179. $hostname = (string) $value;
  180. break;
  181. case 'database':
  182. case 'dbname':
  183. $database = (string) $value;
  184. break;
  185. case 'driver_options':
  186. case 'options':
  187. $value = (array) $value;
  188. $options = array_diff_key($options, $value) + $value;
  189. break;
  190. default:
  191. $options[$key] = $value;
  192. break;
  193. }
  194. }
  195. if (!isset($dsn) && isset($pdoDriver)) {
  196. $dsn = array();
  197. switch ($pdoDriver) {
  198. case 'sqlite':
  199. $dsn[] = $database;
  200. break;
  201. default:
  202. if (isset($database)) {
  203. $dsn[] = "dbname={$database}";
  204. }
  205. if (isset($hostname)) {
  206. $dsn[] = "host={$hostname}";
  207. }
  208. break;
  209. }
  210. $dsn = $pdoDriver . ':' . implode(';', $dsn);
  211. } elseif (!isset($dsn)) {
  212. throw new Exception\InvalidConnectionParametersException(
  213. 'A dsn was not provided or could not be constructed from your parameters',
  214. $this->connectionParameters
  215. );
  216. }
  217. try {
  218. $this->resource = new \PDO($dsn, $username, $password, $options);
  219. $this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
  220. $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
  221. } catch (\PDOException $e) {
  222. throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $e->getCode(), $e);
  223. }
  224. return $this;
  225. }
  226. /**
  227. * @return bool
  228. */
  229. public function isConnected()
  230. {
  231. return ($this->resource instanceof \PDO);
  232. }
  233. /**
  234. * @return Connection
  235. */
  236. public function disconnect()
  237. {
  238. if ($this->isConnected()) {
  239. $this->resource = null;
  240. }
  241. return $this;
  242. }
  243. /**
  244. * @return Connection
  245. */
  246. public function beginTransaction()
  247. {
  248. if (!$this->isConnected()) {
  249. $this->connect();
  250. }
  251. $this->resource->beginTransaction();
  252. $this->inTransaction = true;
  253. return $this;
  254. }
  255. /**
  256. * @return Connection
  257. */
  258. public function commit()
  259. {
  260. if (!$this->isConnected()) {
  261. $this->connect();
  262. }
  263. $this->resource->commit();
  264. $this->inTransaction = false;
  265. return $this;
  266. }
  267. /**
  268. * @return Connection
  269. * @throws \Exception
  270. */
  271. public function rollback()
  272. {
  273. if (!$this->isConnected()) {
  274. throw new Exception\RuntimeException('Must be connected before you can rollback');
  275. }
  276. if (!$this->inTransaction) {
  277. throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback');
  278. }
  279. $this->resource->rollBack();
  280. return $this;
  281. }
  282. /**
  283. * @param $sql
  284. * @return Result
  285. * @throws \Zend\Db\Adapter\Exception\InvalidQueryException
  286. */
  287. public function execute($sql)
  288. {
  289. if (!$this->isConnected()) {
  290. $this->connect();
  291. }
  292. $resultResource = $this->resource->query($sql);
  293. if ($resultResource === false) {
  294. $errorInfo = $this->resource->errorInfo();
  295. throw new Exception\InvalidQueryException($errorInfo[2]);
  296. }
  297. $result = $this->driver->createResult($resultResource, $sql);
  298. return $result;
  299. }
  300. /**
  301. * @param string $sql
  302. * @return Statement
  303. */
  304. public function prepare($sql)
  305. {
  306. if (!$this->isConnected()) {
  307. $this->connect();
  308. }
  309. $statement = $this->driver->createStatement($sql);
  310. return $statement;
  311. }
  312. /**
  313. * Get last generated id
  314. *
  315. * @param string $name
  316. * @return integer|null|false
  317. */
  318. public function getLastGeneratedValue($name = null)
  319. {
  320. if ($name === null && $this->driverName == 'pgsql') {
  321. return null;
  322. }
  323. try {
  324. return $this->resource->lastInsertId($name);
  325. } catch (\Exception $e) {
  326. // do nothing
  327. }
  328. return false;
  329. }
  330. }