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

https://bitbucket.org/gencer/zf2 · PHP · 364 lines · 182 code · 39 blank · 143 comment · 17 complexity · 22b8d7c7f93bc8c14e80716291ffd4e9 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-2014 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\Sqlsrv;
  10. use Zend\Db\Adapter\Driver\ConnectionInterface;
  11. use Zend\Db\Adapter\Driver\Sqlsrv\Exception\ErrorException;
  12. use Zend\Db\Adapter\Exception;
  13. use Zend\Db\Adapter\Profiler;
  14. class Connection implements ConnectionInterface, Profiler\ProfilerAwareInterface
  15. {
  16. /**
  17. * @var Sqlsrv
  18. */
  19. protected $driver = null;
  20. /**
  21. * @var Profiler\ProfilerInterface
  22. */
  23. protected $profiler = null;
  24. /**
  25. * @var array
  26. */
  27. protected $connectionParameters = array();
  28. /**
  29. * @var resource
  30. */
  31. protected $resource = null;
  32. /**
  33. * @var bool
  34. */
  35. protected $inTransaction = false;
  36. /**
  37. * Constructor
  38. *
  39. * @param array|resource $connectionInfo
  40. * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
  41. */
  42. public function __construct($connectionInfo)
  43. {
  44. if (is_array($connectionInfo)) {
  45. $this->setConnectionParameters($connectionInfo);
  46. } elseif (is_resource($connectionInfo)) {
  47. $this->setResource($connectionInfo);
  48. } else {
  49. throw new Exception\InvalidArgumentException('$connection must be an array of parameters or a resource');
  50. }
  51. }
  52. /**
  53. * Set driver
  54. *
  55. * @param Sqlsrv $driver
  56. * @return Connection
  57. */
  58. public function setDriver(Sqlsrv $driver)
  59. {
  60. $this->driver = $driver;
  61. return $this;
  62. }
  63. /**
  64. * @param Profiler\ProfilerInterface $profiler
  65. * @return Connection
  66. */
  67. public function setProfiler(Profiler\ProfilerInterface $profiler)
  68. {
  69. $this->profiler = $profiler;
  70. return $this;
  71. }
  72. /**
  73. * @return null|Profiler\ProfilerInterface
  74. */
  75. public function getProfiler()
  76. {
  77. return $this->profiler;
  78. }
  79. /**
  80. * Set connection parameters
  81. *
  82. * @param array $connectionParameters
  83. * @return Connection
  84. */
  85. public function setConnectionParameters(array $connectionParameters)
  86. {
  87. $this->connectionParameters = $connectionParameters;
  88. return $this;
  89. }
  90. /**
  91. * Get connection parameters
  92. *
  93. * @return array
  94. */
  95. public function getConnectionParameters()
  96. {
  97. return $this->connectionParameters;
  98. }
  99. /**
  100. * Get current schema
  101. *
  102. * @return string
  103. */
  104. public function getCurrentSchema()
  105. {
  106. if (!$this->isConnected()) {
  107. $this->connect();
  108. }
  109. $result = sqlsrv_query($this->resource, 'SELECT SCHEMA_NAME()');
  110. $r = sqlsrv_fetch_array($result);
  111. return $r[0];
  112. }
  113. /**
  114. * Set resource
  115. *
  116. * @param resource $resource
  117. * @throws Exception\InvalidArgumentException
  118. * @return Connection
  119. */
  120. public function setResource($resource)
  121. {
  122. if (get_resource_type($resource) !== 'SQL Server Connection') {
  123. throw new Exception\InvalidArgumentException('Resource provided was not of type SQL Server Connection');
  124. }
  125. $this->resource = $resource;
  126. return $this;
  127. }
  128. /**
  129. * @return resource
  130. */
  131. public function getResource()
  132. {
  133. if (!$this->isConnected()) {
  134. $this->connect();
  135. }
  136. return $this->resource;
  137. }
  138. /**
  139. * Connect
  140. *
  141. * @throws Exception\RuntimeException
  142. * @return Connection
  143. */
  144. public function connect()
  145. {
  146. if ($this->resource) {
  147. return $this;
  148. }
  149. $serverName = '.';
  150. $params = array(
  151. 'ReturnDatesAsStrings' => true
  152. );
  153. foreach ($this->connectionParameters as $key => $value) {
  154. switch (strtolower($key)) {
  155. case 'hostname':
  156. case 'servername':
  157. $serverName = (string) $value;
  158. break;
  159. case 'username':
  160. case 'uid':
  161. $params['UID'] = (string) $value;
  162. break;
  163. case 'password':
  164. case 'pwd':
  165. $params['PWD'] = (string) $value;
  166. break;
  167. case 'database':
  168. case 'dbname':
  169. $params['Database'] = (string) $value;
  170. break;
  171. case 'driver_options':
  172. case 'options':
  173. $params = array_merge($params, (array) $value);
  174. break;
  175. }
  176. }
  177. $this->resource = sqlsrv_connect($serverName, $params);
  178. if (!$this->resource) {
  179. throw new Exception\RuntimeException(
  180. 'Connect Error',
  181. null,
  182. new ErrorException(sqlsrv_errors())
  183. );
  184. }
  185. return $this;
  186. }
  187. /**
  188. * Is connected
  189. * @return bool
  190. */
  191. public function isConnected()
  192. {
  193. return (is_resource($this->resource));
  194. }
  195. /**
  196. * Disconnect
  197. */
  198. public function disconnect()
  199. {
  200. sqlsrv_close($this->resource);
  201. $this->resource = null;
  202. }
  203. /**
  204. * Begin transaction
  205. */
  206. public function beginTransaction()
  207. {
  208. // http://msdn.microsoft.com/en-us/library/cc296151.aspx
  209. /*
  210. $this->resource->autocommit(false);
  211. $this->inTransaction = true;
  212. */
  213. }
  214. /**
  215. * In transaction
  216. *
  217. * @return bool
  218. */
  219. public function inTransaction()
  220. {
  221. return $this->inTransaction;
  222. }
  223. /**
  224. * Commit
  225. */
  226. public function commit()
  227. {
  228. // http://msdn.microsoft.com/en-us/library/cc296194.aspx
  229. /*
  230. if (!$this->resource) {
  231. $this->connect();
  232. }
  233. $this->resource->commit();
  234. $this->inTransaction = false;
  235. */
  236. }
  237. /**
  238. * Rollback
  239. */
  240. public function rollback()
  241. {
  242. // http://msdn.microsoft.com/en-us/library/cc296176.aspx
  243. /*
  244. if (!$this->resource) {
  245. throw new \Exception('Must be connected before you can rollback.');
  246. }
  247. if (!$this->_inCommit) {
  248. throw new \Exception('Must call commit() before you can rollback.');
  249. }
  250. $this->resource->rollback();
  251. return $this;
  252. */
  253. }
  254. /**
  255. * Execute
  256. *
  257. * @param string $sql
  258. * @throws Exception\RuntimeException
  259. * @return mixed
  260. */
  261. public function execute($sql)
  262. {
  263. if (!$this->isConnected()) {
  264. $this->connect();
  265. }
  266. if (!$this->driver instanceof Sqlsrv) {
  267. throw new Exception\RuntimeException('Connection is missing an instance of Sqlsrv');
  268. }
  269. if ($this->profiler) {
  270. $this->profiler->profilerStart($sql);
  271. }
  272. $returnValue = sqlsrv_query($this->resource, $sql);
  273. if ($this->profiler) {
  274. $this->profiler->profilerFinish($sql);
  275. }
  276. // if the returnValue is something other than a Sqlsrv_result, bypass wrapping it
  277. if ($returnValue === false) {
  278. $errors = sqlsrv_errors();
  279. // ignore general warnings
  280. if ($errors[0]['SQLSTATE'] != '01000') {
  281. throw new Exception\RuntimeException(
  282. 'An exception occurred while trying to execute the provided $sql',
  283. null,
  284. new ErrorException($errors)
  285. );
  286. }
  287. }
  288. $result = $this->driver->createResult($returnValue);
  289. return $result;
  290. }
  291. /**
  292. * Prepare
  293. *
  294. * @param string $sql
  295. * @return string
  296. */
  297. public function prepare($sql)
  298. {
  299. if (!$this->isConnected()) {
  300. $this->connect();
  301. }
  302. $statement = $this->driver->createStatement($sql);
  303. return $statement;
  304. }
  305. /**
  306. * Get last generated id
  307. *
  308. * @param string $name
  309. * @return mixed
  310. */
  311. public function getLastGeneratedValue($name = null)
  312. {
  313. if (!$this->resource) {
  314. $this->connect();
  315. }
  316. $sql = 'SELECT @@IDENTITY as Current_Identity';
  317. $result = sqlsrv_query($this->resource, $sql);
  318. $row = sqlsrv_fetch_array($result);
  319. return $row['Current_Identity'];
  320. }
  321. }