PageRenderTime 38ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/www/libs/dibi/drivers/mssql2005.php

https://github.com/bazo/Mokuji
PHP | 403 lines | 271 code | 48 blank | 84 comment | 8 complexity | 72723be37763e3b4938c364b76ddca5f MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * dibi - tiny'n'smart database abstraction layer
  4. * ----------------------------------------------
  5. *
  6. * @copyright Copyright (c) 2005, 2010 David Grudl
  7. * @license http://dibiphp.com/license dibi license
  8. * @link http://dibiphp.com
  9. * @package dibi\drivers
  10. */
  11. /**
  12. * The dibi driver for MS SQL Driver 2005 database.
  13. *
  14. * Connection options:
  15. * - 'host' - the MS SQL server host name. It can also include a port number (hostname:port)
  16. * - 'options' - connection info array {@link http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx}
  17. * - 'lazy' - if TRUE, connection will be established only when required
  18. * - 'charset' - character encoding to set (default is UTF-8)
  19. * - 'resource' - connection resource (optional)
  20. *
  21. * @copyright Copyright (c) 2005, 2010 David Grudl
  22. * @package dibi\drivers
  23. */
  24. class DibiMsSql2005Driver extends DibiObject implements IDibiDriver
  25. {
  26. /** @var resource Connection resource */
  27. private $connection;
  28. /** @var resource Resultset resource */
  29. private $resultSet;
  30. /**
  31. * @throws DibiException
  32. */
  33. public function __construct()
  34. {
  35. if (!extension_loaded('sqlsrv')) {
  36. throw new DibiDriverException("PHP extension 'sqlsrv' is not loaded.");
  37. }
  38. }
  39. /**
  40. * Connects to a database.
  41. * @return void
  42. * @throws DibiException
  43. */
  44. public function connect(array &$config)
  45. {
  46. if (isset($config['resource'])) {
  47. $this->connection = $config['resource'];
  48. } elseif (isset($config['options'])) {
  49. $this->connection = sqlsrv_connect($config['host'], (array) $config['options']);
  50. } else {
  51. $this->connection = sqlsrv_connect($config['host']);
  52. }
  53. if (!is_resource($this->connection)) {
  54. $info = sqlsrv_errors();
  55. throw new DibiDriverException($info[0]['message'], $info[0]['code']);
  56. }
  57. }
  58. /**
  59. * Disconnects from a database.
  60. * @return void
  61. */
  62. public function disconnect()
  63. {
  64. sqlsrv_close($this->connection);
  65. }
  66. /**
  67. * Executes the SQL query.
  68. * @param string SQL statement.
  69. * @return IDibiDriver|NULL
  70. * @throws DibiDriverException
  71. */
  72. public function query($sql)
  73. {
  74. $this->resultSet = sqlsrv_query($this->connection, $sql);
  75. if ($this->resultSet === FALSE) {
  76. $info = sqlsrv_errors();
  77. throw new DibiDriverException($info[0]['message'], $info[0]['code'], $sql);
  78. }
  79. return is_resource($this->resultSet) ? clone $this : NULL;
  80. }
  81. /**
  82. * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query.
  83. * @return int|FALSE number of rows or FALSE on error
  84. */
  85. public function getAffectedRows()
  86. {
  87. return sqlsrv_rows_affected($this->resultSet);
  88. }
  89. /**
  90. * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
  91. * @return int|FALSE int on success or FALSE on failure
  92. */
  93. public function getInsertId($sequence)
  94. {
  95. $res = sqlsrv_query($this->connection, 'SELECT @@IDENTITY');
  96. if (is_resource($res)) {
  97. $row = sqlsrv_fetch_array($res, SQLSRV_FETCH_NUMERIC);
  98. return $row[0];
  99. }
  100. return FALSE;
  101. }
  102. /**
  103. * Begins a transaction (if supported).
  104. * @param string optional savepoint name
  105. * @return void
  106. * @throws DibiDriverException
  107. */
  108. public function begin($savepoint = NULL)
  109. {
  110. $this->query('BEGIN TRANSACTION');
  111. }
  112. /**
  113. * Commits statements in a transaction.
  114. * @param string optional savepoint name
  115. * @return void
  116. * @throws DibiDriverException
  117. */
  118. public function commit($savepoint = NULL)
  119. {
  120. $this->query('COMMIT');
  121. }
  122. /**
  123. * Rollback changes in a transaction.
  124. * @param string optional savepoint name
  125. * @return void
  126. * @throws DibiDriverException
  127. */
  128. public function rollback($savepoint = NULL)
  129. {
  130. $this->query('ROLLBACK');
  131. }
  132. /**
  133. * Is in transaction?
  134. * @return bool
  135. */
  136. public function inTransaction()
  137. {
  138. throw new NotSupportedException('MSSQL 2005 driver does not support transaction testing.');
  139. }
  140. /**
  141. * Returns the connection resource.
  142. * @return mixed
  143. */
  144. public function getResource()
  145. {
  146. return $this->connection;
  147. }
  148. /********************* SQL ****************d*g**/
  149. /**
  150. * Encodes data for use in a SQL statement.
  151. * @param mixed value
  152. * @param string type (dibi::TEXT, dibi::BOOL, ...)
  153. * @return string encoded value
  154. * @throws InvalidArgumentException
  155. */
  156. public function escape($value, $type)
  157. {
  158. switch ($type) {
  159. case dibi::TEXT:
  160. case dibi::BINARY:
  161. return "'" . str_replace("'", "''", $value) . "'";
  162. case dibi::IDENTIFIER:
  163. // @see http://msdn.microsoft.com/en-us/library/ms176027.aspx
  164. $value = str_replace(array('[', ']'), array('[[', ']]'), $value);
  165. return '[' . str_replace('.', '].[', $value) . ']';
  166. case dibi::BOOL:
  167. return $value ? 1 : 0;
  168. case dibi::DATE:
  169. return $value instanceof DateTime ? $value->format("'Y-m-d'") : date("'Y-m-d'", $value);
  170. case dibi::DATETIME:
  171. return $value instanceof DateTime ? $value->format("'Y-m-d H:i:s'") : date("'Y-m-d H:i:s'", $value);
  172. default:
  173. throw new InvalidArgumentException('Unsupported type.');
  174. }
  175. }
  176. /**
  177. * Decodes data from result set.
  178. * @param string value
  179. * @param string type (dibi::BINARY)
  180. * @return string decoded value
  181. * @throws InvalidArgumentException
  182. */
  183. public function unescape($value, $type)
  184. {
  185. if ($type === dibi::BINARY) {
  186. return $value;
  187. }
  188. throw new InvalidArgumentException('Unsupported type.');
  189. }
  190. /**
  191. * Injects LIMIT/OFFSET to the SQL query.
  192. * @param string &$sql The SQL query that will be modified.
  193. * @param int $limit
  194. * @param int $offset
  195. * @return void
  196. */
  197. public function applyLimit(&$sql, $limit, $offset)
  198. {
  199. // offset support is missing
  200. if ($limit >= 0) {
  201. $sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ')';
  202. }
  203. if ($offset) {
  204. throw new NotImplementedException('Offset is not implemented.');
  205. }
  206. }
  207. /********************* result set ****************d*g**/
  208. /**
  209. * Returns the number of rows in a result set.
  210. * @return int
  211. */
  212. public function getRowCount()
  213. {
  214. throw new NotSupportedException('Row count is not available for unbuffered queries.');
  215. }
  216. /**
  217. * Fetches the row at current position and moves the internal cursor to the next position.
  218. * @param bool TRUE for associative array, FALSE for numeric
  219. * @return array array on success, nonarray if no next record
  220. * @internal
  221. */
  222. public function fetch($assoc)
  223. {
  224. return sqlsrv_fetch_array($this->resultSet, $assoc ? SQLSRV_FETCH_ASSOC : SQLSRV_FETCH_NUMERIC);
  225. }
  226. /**
  227. * Moves cursor position without fetching row.
  228. * @param int the 0-based cursor pos to seek to
  229. * @return boolean TRUE on success, FALSE if unable to seek to specified record
  230. */
  231. public function seek($row)
  232. {
  233. throw new NotSupportedException('Cannot seek an unbuffered result set.');
  234. }
  235. /**
  236. * Frees the resources allocated for this result set.
  237. * @return void
  238. */
  239. public function free()
  240. {
  241. sqlsrv_free_stmt($this->resultSet);
  242. $this->resultSet = NULL;
  243. }
  244. /**
  245. * Returns metadata for all columns in a result set.
  246. * @return array
  247. */
  248. public function getColumnsMeta()
  249. {
  250. $count = sqlsrv_num_fields($this->resultSet);
  251. $res = array();
  252. for ($i = 0; $i < $count; $i++) {
  253. $row = (array) sqlsrv_field_metadata($this->resultSet, $i);
  254. $res[] = array(
  255. 'name' => $row['Name'],
  256. 'fullname' => $row['Name'],
  257. 'nativetype' => $row['Type'],
  258. );
  259. }
  260. return $res;
  261. }
  262. /**
  263. * Returns the result set resource.
  264. * @return mixed
  265. */
  266. public function getResultResource()
  267. {
  268. return $this->resultSet;
  269. }
  270. /********************* reflection ****************d*g**/
  271. /**
  272. * Returns list of tables.
  273. * @return array
  274. */
  275. public function getTables()
  276. {
  277. throw new NotImplementedException;
  278. }
  279. /**
  280. * Returns metadata for all columns in a table.
  281. * @param string
  282. * @return array
  283. */
  284. public function getColumns($table)
  285. {
  286. throw new NotImplementedException;
  287. }
  288. /**
  289. * Returns metadata for all indexes in a table.
  290. * @param string
  291. * @return array
  292. */
  293. public function getIndexes($table)
  294. {
  295. throw new NotImplementedException;
  296. }
  297. /**
  298. * Returns metadata for all foreign keys in a table.
  299. * @param string
  300. * @return array
  301. */
  302. public function getForeignKeys($table)
  303. {
  304. throw new NotImplementedException;
  305. }
  306. }