PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Mysqli/Result.php

https://bitbucket.org/juan_sanchez/aiyellow
PHP | 342 lines | 171 code | 40 blank | 131 comment | 30 complexity | b7b385adc6edfe38553e0329a4138998 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-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Db\Adapter\Driver\Mysqli;
  10. use Iterator;
  11. use Zend\Db\Adapter\Driver\ResultInterface;
  12. use Zend\Db\Adapter\Exception;
  13. class Result implements
  14. Iterator,
  15. ResultInterface
  16. {
  17. /**
  18. * @var \mysqli|\mysqli_result|\mysqli_stmt
  19. */
  20. protected $resource = null;
  21. /**
  22. * @var bool
  23. */
  24. protected $isBuffered = null;
  25. /**
  26. * Cursor position
  27. * @var int
  28. */
  29. protected $position = 0;
  30. /**
  31. * Number of known rows
  32. * @var int
  33. */
  34. protected $numberOfRows = -1;
  35. /**
  36. * Is the current() operation already complete for this pointer position?
  37. * @var bool
  38. */
  39. protected $currentComplete = false;
  40. /**
  41. * @var bool
  42. */
  43. protected $nextComplete = false;
  44. /**
  45. * @var bool
  46. */
  47. protected $currentData = false;
  48. /**
  49. *
  50. * @var array
  51. */
  52. protected $statementBindValues = array('keys' => null, 'values' => array());
  53. /**
  54. * @var mixed
  55. */
  56. protected $generatedValue = null;
  57. /**
  58. * Initialize
  59. *
  60. * @param mixed $resource
  61. * @param mixed $generatedValue
  62. * @param bool|null $isBuffered
  63. * @throws Exception\InvalidArgumentException
  64. * @return Result
  65. */
  66. public function initialize($resource, $generatedValue, $isBuffered = null)
  67. {
  68. if (!$resource instanceof \mysqli && !$resource instanceof \mysqli_result && !$resource instanceof \mysqli_stmt) {
  69. throw new Exception\InvalidArgumentException('Invalid resource provided.');
  70. }
  71. if ($isBuffered !== null) {
  72. $this->isBuffered = $isBuffered;
  73. } else {
  74. if ($resource instanceof \mysqli || $resource instanceof \mysqli_result
  75. || $resource instanceof \mysqli_stmt && $resource->num_rows != 0) {
  76. $this->isBuffered = true;
  77. }
  78. }
  79. $this->resource = $resource;
  80. $this->generatedValue = $generatedValue;
  81. return $this;
  82. }
  83. /**
  84. * Force buffering
  85. *
  86. * @throws Exception\RuntimeException
  87. */
  88. public function buffer()
  89. {
  90. if ($this->resource instanceof \mysqli_stmt && $this->isBuffered !== true) {
  91. if ($this->position > 0) {
  92. throw new Exception\RuntimeException('Cannot buffer a result set that has started iteration.');
  93. }
  94. $this->resource->store_result();
  95. $this->isBuffered = true;
  96. }
  97. }
  98. /**
  99. * Check if is buffered
  100. *
  101. * @return bool|null
  102. */
  103. public function isBuffered()
  104. {
  105. return $this->isBuffered;
  106. }
  107. /**
  108. * Return the resource
  109. *
  110. * @return mixed
  111. */
  112. public function getResource()
  113. {
  114. return $this->resource;
  115. }
  116. /**
  117. * Is query result?
  118. *
  119. * @return bool
  120. */
  121. public function isQueryResult()
  122. {
  123. return ($this->resource->field_count > 0);
  124. }
  125. /**
  126. * Get affected rows
  127. *
  128. * @return integer
  129. */
  130. public function getAffectedRows()
  131. {
  132. if ($this->resource instanceof \mysqli || $this->resource instanceof \mysqli_stmt) {
  133. return $this->resource->affected_rows;
  134. }
  135. return $this->resource->num_rows;
  136. }
  137. /**
  138. * Current
  139. *
  140. * @return mixed
  141. */
  142. public function current()
  143. {
  144. if ($this->currentComplete) {
  145. return $this->currentData;
  146. }
  147. if ($this->resource instanceof \mysqli_stmt) {
  148. $this->loadDataFromMysqliStatement();
  149. return $this->currentData;
  150. } else {
  151. $this->loadFromMysqliResult();
  152. return $this->currentData;
  153. }
  154. }
  155. /**
  156. * Mysqli's binding and returning of statement values
  157. *
  158. * Mysqli requires you to bind variables to the extension in order to
  159. * get data out. These values have to be references:
  160. * @see http://php.net/manual/en/mysqli-stmt.bind-result.php
  161. *
  162. * @throws Exception\RuntimeException
  163. * @return bool
  164. */
  165. protected function loadDataFromMysqliStatement()
  166. {
  167. $data = null;
  168. // build the default reference based bind structure, if it does not already exist
  169. if ($this->statementBindValues['keys'] === null) {
  170. $this->statementBindValues['keys'] = array();
  171. $resultResource = $this->resource->result_metadata();
  172. foreach ($resultResource->fetch_fields() as $col) {
  173. $this->statementBindValues['keys'][] = $col->name;
  174. }
  175. $this->statementBindValues['values'] = array_fill(0, count($this->statementBindValues['keys']), null);
  176. $refs = array();
  177. foreach ($this->statementBindValues['values'] as $i => &$f) {
  178. $refs[$i] = &$f;
  179. }
  180. call_user_func_array(array($this->resource, 'bind_result'), $this->statementBindValues['values']);
  181. }
  182. if (($r = $this->resource->fetch()) === null) {
  183. if (!$this->isBuffered) {
  184. $this->resource->close();
  185. }
  186. return false;
  187. } elseif ($r === false) {
  188. throw new Exception\RuntimeException($this->resource->error);
  189. }
  190. // dereference
  191. for ($i = 0, $count = count($this->statementBindValues['keys']); $i < $count; $i++) {
  192. $this->currentData[$this->statementBindValues['keys'][$i]] = $this->statementBindValues['values'][$i];
  193. }
  194. $this->currentComplete = true;
  195. $this->nextComplete = true;
  196. $this->position++;
  197. return true;
  198. }
  199. /**
  200. * Load from mysqli result
  201. *
  202. * @return bool
  203. */
  204. protected function loadFromMysqliResult()
  205. {
  206. $this->currentData = null;
  207. if (($data = $this->resource->fetch_assoc()) === null) {
  208. return false;
  209. }
  210. $this->position++;
  211. $this->currentData = $data;
  212. $this->currentComplete = true;
  213. $this->nextComplete = true;
  214. $this->position++;
  215. return true;
  216. }
  217. /**
  218. * Next
  219. *
  220. * @return void
  221. */
  222. public function next()
  223. {
  224. $this->currentComplete = false;
  225. if ($this->nextComplete == false) {
  226. $this->position++;
  227. }
  228. $this->nextComplete = false;
  229. }
  230. /**
  231. * Key
  232. *
  233. * @return mixed
  234. */
  235. public function key()
  236. {
  237. return $this->position;
  238. }
  239. /**
  240. * Rewind
  241. *
  242. * @throws Exception\RuntimeException
  243. * @return void
  244. */
  245. public function rewind()
  246. {
  247. if ($this->position !== 0) {
  248. if ($this->isBuffered === false) {
  249. throw new Exception\RuntimeException('Unbuffered results cannot be rewound for multiple iterations');
  250. }
  251. }
  252. $this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt
  253. $this->currentComplete = false;
  254. $this->position = 0;
  255. }
  256. /**
  257. * Valid
  258. *
  259. * @return bool
  260. */
  261. public function valid()
  262. {
  263. if ($this->currentComplete) {
  264. return true;
  265. }
  266. if ($this->resource instanceof \mysqli_stmt) {
  267. return $this->loadDataFromMysqliStatement();
  268. }
  269. return $this->loadFromMysqliResult();
  270. }
  271. /**
  272. * Count
  273. *
  274. * @throws Exception\RuntimeException
  275. * @return integer
  276. */
  277. public function count()
  278. {
  279. if ($this->isBuffered === false) {
  280. throw new Exception\RuntimeException('Row count is not available in unbuffered result sets.');
  281. }
  282. return $this->resource->num_rows;
  283. }
  284. /**
  285. * Get field count
  286. *
  287. * @return integer
  288. */
  289. public function getFieldCount()
  290. {
  291. return $this->resource->field_count;
  292. }
  293. /**
  294. * Get generated value
  295. *
  296. * @return mixed|null
  297. */
  298. public function getGeneratedValue()
  299. {
  300. return $this->generatedValue;
  301. }
  302. }