PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php

https://gitlab.com/techniconline/kmc
PHP | 370 lines | 211 code | 54 blank | 105 comment | 32 complexity | 7f83b25bc50f6ec3b4be5852b2d34965 MD5 | raw file
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\DBAL\Driver\Mysqli;
  20. use Doctrine\DBAL\Driver\Statement;
  21. use PDO;
  22. /**
  23. * @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
  24. */
  25. class MysqliStatement implements \IteratorAggregate, Statement
  26. {
  27. /**
  28. * @var array
  29. */
  30. protected static $_paramTypeMap = array(
  31. PDO::PARAM_STR => 's',
  32. PDO::PARAM_BOOL => 'i',
  33. PDO::PARAM_NULL => 's',
  34. PDO::PARAM_INT => 'i',
  35. PDO::PARAM_LOB => 's' // TODO Support LOB bigger then max package size.
  36. );
  37. /**
  38. * @var \mysqli
  39. */
  40. protected $_conn;
  41. /**
  42. * @var \mysqli_stmt
  43. */
  44. protected $_stmt;
  45. /**
  46. * @var null|boolean|array
  47. */
  48. protected $_columnNames;
  49. /**
  50. * @var null|array
  51. */
  52. protected $_rowBindedValues;
  53. /**
  54. * @var array
  55. */
  56. protected $_bindedValues;
  57. /**
  58. * Contains ref values for bindValue().
  59. *
  60. * @var array
  61. */
  62. protected $_values = array();
  63. /**
  64. * @var integer
  65. */
  66. protected $_defaultFetchMode = PDO::FETCH_BOTH;
  67. /**
  68. * @param \mysqli $conn
  69. * @param string $prepareString
  70. *
  71. * @throws \Doctrine\DBAL\Driver\Mysqli\MysqliException
  72. */
  73. public function __construct(\mysqli $conn, $prepareString)
  74. {
  75. $this->_conn = $conn;
  76. $this->_stmt = $conn->prepare($prepareString);
  77. if (false === $this->_stmt) {
  78. throw new MysqliException($this->_conn->error, $this->_conn->errno);
  79. }
  80. $paramCount = $this->_stmt->param_count;
  81. if (0 < $paramCount) {
  82. // Index 0 is types
  83. // Need to init the string else php think we are trying to access it as a array.
  84. $bindedValues = array(0 => str_repeat('s', $paramCount));
  85. $null = null;
  86. for ($i = 1; $i < $paramCount; $i++) {
  87. $bindedValues[] =& $null;
  88. }
  89. $this->_bindedValues = $bindedValues;
  90. }
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function bindParam($column, &$variable, $type = null, $length = null)
  96. {
  97. if (null === $type) {
  98. $type = 's';
  99. } else {
  100. if (isset(self::$_paramTypeMap[$type])) {
  101. $type = self::$_paramTypeMap[$type];
  102. } else {
  103. throw new MysqliException("Unknown type: '{$type}'");
  104. }
  105. }
  106. $this->_bindedValues[$column] =& $variable;
  107. $this->_bindedValues[0][$column - 1] = $type;
  108. return true;
  109. }
  110. /**
  111. * {@inheritdoc}
  112. */
  113. public function bindValue($param, $value, $type = null)
  114. {
  115. if (null === $type) {
  116. $type = 's';
  117. } else {
  118. if (isset(self::$_paramTypeMap[$type])) {
  119. $type = self::$_paramTypeMap[$type];
  120. } else {
  121. throw new MysqliException("Unknown type: '{$type}'");
  122. }
  123. }
  124. $this->_values[$param] = $value;
  125. $this->_bindedValues[$param] =& $this->_values[$param];
  126. $this->_bindedValues[0][$param - 1] = $type;
  127. return true;
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function execute($params = null)
  133. {
  134. if (null !== $this->_bindedValues) {
  135. if (null !== $params) {
  136. if (!$this->_bindValues($params)) {
  137. throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
  138. }
  139. } else {
  140. if (!call_user_func_array(array($this->_stmt, 'bind_param'), $this->_bindedValues)) {
  141. throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
  142. }
  143. }
  144. }
  145. if (!$this->_stmt->execute()) {
  146. throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
  147. }
  148. if (null === $this->_columnNames) {
  149. $meta = $this->_stmt->result_metadata();
  150. if (false !== $meta) {
  151. // We have a result.
  152. $this->_stmt->store_result();
  153. $columnNames = array();
  154. foreach ($meta->fetch_fields() as $col) {
  155. $columnNames[] = $col->name;
  156. }
  157. $meta->free();
  158. $this->_columnNames = $columnNames;
  159. $this->_rowBindedValues = array_fill(0, count($columnNames), NULL);
  160. $refs = array();
  161. foreach ($this->_rowBindedValues as $key => &$value) {
  162. $refs[$key] =& $value;
  163. }
  164. if (!call_user_func_array(array($this->_stmt, 'bind_result'), $refs)) {
  165. throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
  166. }
  167. } else {
  168. $this->_columnNames = false;
  169. }
  170. }
  171. return true;
  172. }
  173. /**
  174. * Binds a array of values to bound parameters.
  175. *
  176. * @param array $values
  177. *
  178. * @return boolean
  179. */
  180. private function _bindValues($values)
  181. {
  182. $params = array();
  183. $types = str_repeat('s', count($values));
  184. $params[0] = $types;
  185. foreach ($values as &$v) {
  186. $params[] =& $v;
  187. }
  188. return call_user_func_array(array($this->_stmt, 'bind_param'), $params);
  189. }
  190. /**
  191. * @return boolean|array
  192. */
  193. private function _fetch()
  194. {
  195. $ret = $this->_stmt->fetch();
  196. if (true === $ret) {
  197. $values = array();
  198. foreach ($this->_rowBindedValues as $v) {
  199. // Mysqli converts them to a scalar type it can fit in.
  200. $values[] = null === $v ? null : (string)$v;
  201. }
  202. return $values;
  203. }
  204. return $ret;
  205. }
  206. /**
  207. * {@inheritdoc}
  208. */
  209. public function fetch($fetchMode = null)
  210. {
  211. $values = $this->_fetch();
  212. if (null === $values) {
  213. return null;
  214. }
  215. if (false === $values) {
  216. throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
  217. }
  218. $fetchMode = $fetchMode ?: $this->_defaultFetchMode;
  219. switch ($fetchMode) {
  220. case PDO::FETCH_NUM:
  221. return $values;
  222. case PDO::FETCH_ASSOC:
  223. return array_combine($this->_columnNames, $values);
  224. case PDO::FETCH_BOTH:
  225. $ret = array_combine($this->_columnNames, $values);
  226. $ret += $values;
  227. return $ret;
  228. default:
  229. throw new MysqliException("Unknown fetch type '{$fetchMode}'");
  230. }
  231. }
  232. /**
  233. * {@inheritdoc}
  234. */
  235. public function fetchAll($fetchMode = null)
  236. {
  237. $fetchMode = $fetchMode ?: $this->_defaultFetchMode;
  238. $rows = array();
  239. if (PDO::FETCH_COLUMN == $fetchMode) {
  240. while (($row = $this->fetchColumn()) !== false) {
  241. $rows[] = $row;
  242. }
  243. } else {
  244. while (($row = $this->fetch($fetchMode)) !== null) {
  245. $rows[] = $row;
  246. }
  247. }
  248. return $rows;
  249. }
  250. /**
  251. * {@inheritdoc}
  252. */
  253. public function fetchColumn($columnIndex = 0)
  254. {
  255. $row = $this->fetch(PDO::FETCH_NUM);
  256. if (null === $row) {
  257. return false;
  258. }
  259. return $row[$columnIndex];
  260. }
  261. /**
  262. * {@inheritdoc}
  263. */
  264. public function errorCode()
  265. {
  266. return $this->_stmt->errno;
  267. }
  268. /**
  269. * {@inheritdoc}
  270. */
  271. public function errorInfo()
  272. {
  273. return $this->_stmt->error;
  274. }
  275. /**
  276. * {@inheritdoc}
  277. */
  278. public function closeCursor()
  279. {
  280. $this->_stmt->free_result();
  281. return true;
  282. }
  283. /**
  284. * {@inheritdoc}
  285. */
  286. public function rowCount()
  287. {
  288. if (false === $this->_columnNames) {
  289. return $this->_stmt->affected_rows;
  290. }
  291. return $this->_stmt->num_rows;
  292. }
  293. /**
  294. * {@inheritdoc}
  295. */
  296. public function columnCount()
  297. {
  298. return $this->_stmt->field_count;
  299. }
  300. /**
  301. * {@inheritdoc}
  302. */
  303. public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
  304. {
  305. $this->_defaultFetchMode = $fetchMode;
  306. return true;
  307. }
  308. /**
  309. * {@inheritdoc}
  310. */
  311. public function getIterator()
  312. {
  313. $data = $this->fetchAll();
  314. return new \ArrayIterator($data);
  315. }
  316. }