/vendor/nette/nette/Nette/Database/Statement.php

https://bitbucket.org/iiic/iszp · PHP · 223 lines · 109 code · 66 blank · 48 comment · 11 complexity · 8bedcc62ddc375bbf02985fed1f67495 MD5 · raw file

  1. <?php
  2. /**
  3. * This file is part of the Nette Framework (http://nette.org)
  4. *
  5. * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6. *
  7. * For the full copyright and license information, please view
  8. * the file license.txt that was distributed with this source code.
  9. */
  10. namespace Nette\Database;
  11. use Nette,
  12. PDO,
  13. Nette\ObjectMixin;
  14. /**
  15. * Represents a prepared statement / result set.
  16. *
  17. * @author David Grudl
  18. *
  19. * @property-read Connection $connection
  20. * @property-write $fetchMode
  21. */
  22. class Statement extends \PDOStatement
  23. {
  24. /** @var Connection */
  25. private $connection;
  26. /** @var float */
  27. private $time;
  28. /** @var array */
  29. private $types;
  30. protected function __construct(Connection $connection)
  31. {
  32. $this->connection = $connection;
  33. $this->setFetchMode(PDO::FETCH_CLASS, 'Nette\Database\Row', array($this));
  34. }
  35. /**
  36. * @return Connection
  37. */
  38. public function getConnection()
  39. {
  40. return $this->connection;
  41. }
  42. /**
  43. * Executes statement.
  44. * @param array
  45. * @return Statement provides a fluent interface
  46. */
  47. public function execute($params = array())
  48. {
  49. static $types = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT,
  50. 'resource' => PDO::PARAM_LOB, 'NULL' => PDO::PARAM_NULL);
  51. foreach ($params as $key => $value) {
  52. $type = gettype($value);
  53. $this->bindValue(is_int($key) ? $key + 1 : $key, $value, isset($types[$type]) ? $types[$type] : PDO::PARAM_STR);
  54. }
  55. $time = microtime(TRUE);
  56. try {
  57. parent::execute();
  58. } catch (\PDOException $e) {
  59. $e->queryString = $this->queryString;
  60. throw $e;
  61. }
  62. $this->time = microtime(TRUE) - $time;
  63. $this->connection->__call('onQuery', array($this, $params)); // $this->connection->onQuery() in PHP 5.3
  64. return $this;
  65. }
  66. /**
  67. * Fetches into an array where the 1st column is a key and all subsequent columns are values.
  68. * @return array
  69. */
  70. public function fetchPairs()
  71. {
  72. return $this->fetchAll(PDO::FETCH_KEY_PAIR); // since PHP 5.2.3
  73. }
  74. /**
  75. * Normalizes result row.
  76. * @param array
  77. * @return array
  78. */
  79. public function normalizeRow($row)
  80. {
  81. foreach ($this->detectColumnTypes() as $key => $type) {
  82. $value = $row[$key];
  83. if ($value === NULL || $value === FALSE || $type === IReflection::FIELD_TEXT) {
  84. } elseif ($type === IReflection::FIELD_INTEGER) {
  85. $row[$key] = is_float($tmp = $value * 1) ? $value : $tmp;
  86. } elseif ($type === IReflection::FIELD_FLOAT) {
  87. $value = strpos($value, '.') === FALSE ? $value : rtrim(rtrim($value, '0'), '.');
  88. $float = (float) $value;
  89. $row[$key] = (string) $float === $value ? $float : $value;
  90. } elseif ($type === IReflection::FIELD_BOOL) {
  91. $row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
  92. } elseif ($type === IReflection::FIELD_DATETIME || $type === IReflection::FIELD_DATE || $type === IReflection::FIELD_TIME) {
  93. $row[$key] = new Nette\DateTime($value);
  94. }
  95. }
  96. return $this->connection->getSupplementalDriver()->normalizeRow($row, $this);
  97. }
  98. private function detectColumnTypes()
  99. {
  100. if ($this->types === NULL) {
  101. $this->types = array();
  102. if ($this->connection->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_COLUMNS_META)) { // workaround for PHP bugs #53782, #54695
  103. $col = 0;
  104. while ($meta = $this->getColumnMeta($col++)) {
  105. if (isset($meta['native_type'])) {
  106. $this->types[$meta['name']] = Helpers::detectType($meta['native_type']);
  107. }
  108. }
  109. }
  110. }
  111. return $this->types;
  112. }
  113. /**
  114. * @return float
  115. */
  116. public function getTime()
  117. {
  118. return $this->time;
  119. }
  120. /********************* misc tools ****************d*g**/
  121. /**
  122. * Displays complete result set as HTML table for debug purposes.
  123. * @return void
  124. */
  125. public function dump()
  126. {
  127. Helpers::dumpResult($this);
  128. }
  129. /********************* Nette\Object behaviour ****************d*g**/
  130. /**
  131. * @return Nette\Reflection\ClassType
  132. */
  133. public /**/static/**/ function getReflection()
  134. {
  135. return new Nette\Reflection\ClassType(/*5.2*$this*//**/get_called_class()/**/);
  136. }
  137. public function __call($name, $args)
  138. {
  139. return ObjectMixin::call($this, $name, $args);
  140. }
  141. public function &__get($name)
  142. {
  143. return ObjectMixin::get($this, $name);
  144. }
  145. public function __set($name, $value)
  146. {
  147. return ObjectMixin::set($this, $name, $value);
  148. }
  149. public function __isset($name)
  150. {
  151. return ObjectMixin::has($this, $name);
  152. }
  153. public function __unset($name)
  154. {
  155. ObjectMixin::remove($this, $name);
  156. }
  157. }