PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Db/Statement/Sqlsrv.php

https://github.com/tanduy/zf
PHP | 411 lines | 208 code | 61 blank | 142 comment | 32 complexity | 938b3e02c03c59dbf76583cfa5aa3a68 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Db
  17. * @subpackage Statement
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_Db_Statement
  24. */
  25. require_once 'Zend/Db/Statement.php';
  26. /**
  27. * Extends for Microsoft SQL Server Driver for PHP
  28. *
  29. * @category Zend
  30. * @package Zend_Db
  31. * @subpackage Statement
  32. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  33. * @license http://framework.zend.com/license/new-bsd New BSD License
  34. */
  35. class Zend_Db_Statement_Sqlsrv extends Zend_Db_Statement
  36. {
  37. /**
  38. * The connection_stmt object original string.
  39. */
  40. protected $_originalSQL;
  41. /**
  42. * Column names.
  43. */
  44. protected $_keys;
  45. /**
  46. * Query executed
  47. */
  48. protected $_executed = false;
  49. /**
  50. * Prepares statement handle
  51. *
  52. * @param string $sql
  53. * @return void
  54. * @throws Zend_Db_Statement_Sqlsrv_Exception
  55. */
  56. protected function _prepare($sql)
  57. {
  58. $connection = $this->_adapter->getConnection();
  59. $this->_stmt = sqlsrv_prepare($connection, $sql);
  60. if (!$this->_stmt) {
  61. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  62. throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
  63. }
  64. $this->_originalSQL = $sql;
  65. }
  66. /**
  67. * Binds a parameter to the specified variable name.
  68. *
  69. * @param mixed $parameter Name the parameter, either integer or string.
  70. * @param mixed $variable Reference to PHP variable containing the value.
  71. * @param mixed $type OPTIONAL Datatype of SQL parameter.
  72. * @param mixed $length OPTIONAL Length of SQL parameter.
  73. * @param mixed $options OPTIONAL Other options.
  74. * @return bool
  75. * @throws Zend_Db_Statement_Exception
  76. */
  77. protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
  78. {
  79. //Sql server doesn't support bind by name
  80. return true;
  81. }
  82. /**
  83. * Closes the cursor, allowing the statement to be executed again.
  84. *
  85. * @return bool
  86. */
  87. public function closeCursor()
  88. {
  89. if (!$this->_stmt) {
  90. return false;
  91. }
  92. sqlsrv_free_stmt($this->_stmt);
  93. $this->_stmt = false;
  94. return true;
  95. }
  96. /**
  97. * Returns the number of columns in the result set.
  98. * Returns null if the statement has no result set metadata.
  99. *
  100. * @return int The number of columns.
  101. */
  102. public function columnCount()
  103. {
  104. if ($this->_stmt && $this->_executed) {
  105. return sqlsrv_num_fields($this->_stmt);
  106. }
  107. return 0;
  108. }
  109. /**
  110. * Retrieves the error code, if any, associated with the last operation on
  111. * the statement handle.
  112. *
  113. * @return string error code.
  114. */
  115. public function errorCode()
  116. {
  117. if (!$this->_stmt) {
  118. return false;
  119. }
  120. $error = sqlsrv_errors();
  121. if (!$error) {
  122. return false;
  123. }
  124. return $error[0]['code'];
  125. }
  126. /**
  127. * Retrieves an array of error information, if any, associated with the
  128. * last operation on the statement handle.
  129. *
  130. * @return array
  131. */
  132. public function errorInfo()
  133. {
  134. if (!$this->_stmt) {
  135. return false;
  136. }
  137. $error = sqlsrv_errors();
  138. if (!$error) {
  139. return false;
  140. }
  141. return array(
  142. $error[0]['code'],
  143. $error[0]['message'],
  144. );
  145. }
  146. /**
  147. * Executes a prepared statement.
  148. *
  149. * @param array $params OPTIONAL Values to bind to parameter placeholders.
  150. * @return bool
  151. * @throws Zend_Db_Statement_Exception
  152. */
  153. public function _execute(array $params = null)
  154. {
  155. $connection = $this->_adapter->getConnection();
  156. if (!$this->_stmt) {
  157. return false;
  158. }
  159. if ($params !== null) {
  160. if (!is_array($params)) {
  161. $params = array($params);
  162. }
  163. $error = false;
  164. // make all params passed by reference
  165. $params_ = array();
  166. $temp = array();
  167. $i = 1;
  168. foreach ($params as $param) {
  169. $temp[$i] = $param;
  170. $params_[] = &$temp[$i];
  171. $i++;
  172. }
  173. $params = $params_;
  174. }
  175. $this->_stmt = sqlsrv_query($connection, $this->_originalSQL, $params);
  176. if (!$this->_stmt) {
  177. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  178. throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
  179. }
  180. $this->_executed = true;
  181. return (!$this->_stmt);
  182. }
  183. /**
  184. * Fetches a row from the result set.
  185. *
  186. * @param int $style OPTIONAL Fetch mode for this fetch operation.
  187. * @param int $cursor OPTIONAL Absolute, relative, or other.
  188. * @param int $offset OPTIONAL Number for absolute or relative cursors.
  189. * @return mixed Array, object, or scalar depending on fetch mode.
  190. * @throws Zend_Db_Statement_Exception
  191. */
  192. public function fetch($style = null, $cursor = null, $offset = null)
  193. {
  194. if (!$this->_stmt) {
  195. return false;
  196. }
  197. if (null === $style) {
  198. $style = $this->_fetchMode;
  199. }
  200. $values = sqlsrv_fetch_array($this->_stmt, SQLSRV_FETCH_ASSOC);
  201. if (!$values && (null !== $error = sqlsrv_errors())) {
  202. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  203. throw new Zend_Db_Statement_Sqlsrv_Exception($error);
  204. }
  205. if (null === $values) {
  206. return null;
  207. }
  208. if (!$this->_keys) {
  209. foreach ($values as $key => $value) {
  210. $this->_keys[] = $this->_adapter->foldCase($key);
  211. }
  212. }
  213. $values = array_values($values);
  214. $row = false;
  215. switch ($style) {
  216. case Zend_Db::FETCH_NUM:
  217. $row = $values;
  218. break;
  219. case Zend_Db::FETCH_ASSOC:
  220. $row = array_combine($this->_keys, $values);
  221. break;
  222. case Zend_Db::FETCH_BOTH:
  223. $assoc = array_combine($this->_keys, $values);
  224. $row = array_merge($values, $assoc);
  225. break;
  226. case Zend_Db::FETCH_OBJ:
  227. $row = (object) array_combine($this->_keys, $values);
  228. break;
  229. case Zend_Db::FETCH_BOUND:
  230. $assoc = array_combine($this->_keys, $values);
  231. $row = array_merge($values, $assoc);
  232. $row = $this->_fetchBound($row);
  233. break;
  234. default:
  235. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  236. throw new Zend_Db_Statement_Sqlsrv_Exception("Invalid fetch mode '$style' specified");
  237. break;
  238. }
  239. return $row;
  240. }
  241. /**
  242. * Returns a single column from the next row of a result set.
  243. *
  244. * @param int $col OPTIONAL Position of the column to fetch.
  245. * @return string
  246. * @throws Zend_Db_Statement_Exception
  247. */
  248. public function fetchColumn($col = 0)
  249. {
  250. if (!$this->_stmt) {
  251. return false;
  252. }
  253. if (!sqlsrv_fetch($this->_stmt)) {
  254. if (null !== $error = sqlsrv_errors()) {
  255. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  256. throw new Zend_Db_Statement_Sqlsrv_Exception($error);
  257. }
  258. // If no error, there is simply no record
  259. return false;
  260. }
  261. $data = sqlsrv_get_field($this->_stmt, $col); //0-based
  262. if ($data === false) {
  263. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  264. throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
  265. }
  266. return $data;
  267. }
  268. /**
  269. * Fetches the next row and returns it as an object.
  270. *
  271. * @param string $class OPTIONAL Name of the class to create.
  272. * @param array $config OPTIONAL Constructor arguments for the class.
  273. * @return mixed One object instance of the specified class.
  274. * @throws Zend_Db_Statement_Exception
  275. */
  276. public function fetchObject($class = 'stdClass', array $config = array())
  277. {
  278. if (!$this->_stmt) {
  279. return false;
  280. }
  281. $obj = sqlsrv_fetch_object($this->_stmt);
  282. if ($error = sqlsrv_errors()) {
  283. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  284. throw new Zend_Db_Statement_Sqlsrv_Exception($error);
  285. }
  286. /* @todo XXX handle parameters */
  287. if (null === $obj) {
  288. return false;
  289. }
  290. return $obj;
  291. }
  292. /**
  293. * Returns metadata for a column in a result set.
  294. *
  295. * @param int $column
  296. * @return mixed
  297. * @throws Zend_Db_Statement_Sqlsrv_Exception
  298. */
  299. public function getColumnMeta($column)
  300. {
  301. $fields = sqlsrv_field_metadata($this->_stmt);
  302. if (!$fields) {
  303. throw new Zend_Db_Statement_Sqlsrv_Exception('Column metadata can not be fetched');
  304. }
  305. if (!isset($fields[$column])) {
  306. throw new Zend_Db_Statement_Sqlsrv_Exception('Column index does not exist in statement');
  307. }
  308. return $fields[$column];
  309. }
  310. /**
  311. * Retrieves the next rowset (result set) for a SQL statement that has
  312. * multiple result sets. An example is a stored procedure that returns
  313. * the results of multiple queries.
  314. *
  315. * @return bool
  316. * @throws Zend_Db_Statement_Exception
  317. */
  318. public function nextRowset()
  319. {
  320. if (sqlsrv_next_result($this->_stmt) === false) {
  321. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  322. throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
  323. }
  324. //else - moved to next (or there are no more rows)
  325. }
  326. /**
  327. * Returns the number of rows affected by the execution of the
  328. * last INSERT, DELETE, or UPDATE statement executed by this
  329. * statement object.
  330. *
  331. * @return int The number of rows affected.
  332. * @throws Zend_Db_Statement_Exception
  333. */
  334. public function rowCount()
  335. {
  336. if (!$this->_stmt) {
  337. return false;
  338. }
  339. if (!$this->_executed) {
  340. return 0;
  341. }
  342. $num_rows = sqlsrv_rows_affected($this->_stmt);
  343. // Strict check is necessary; 0 is a valid return value
  344. if ($num_rows === false) {
  345. require_once 'Zend/Db/Statement/Sqlsrv/Exception.php';
  346. throw new Zend_Db_Statement_Sqlsrv_Exception(sqlsrv_errors());
  347. }
  348. return $num_rows;
  349. }
  350. }