/environment/library/database/DB.class.php

https://github.com/cj/Project-Pier · PHP · 328 lines · 107 code · 38 blank · 183 comment · 11 complexity · c23caba387cf3ea89b4998bae629a289 MD5 · raw file

  1. <?php
  2. /**
  3. * This function holds open database connections and provides interface to them. It is also used
  4. * for SQL logging
  5. *
  6. * @version 1.0
  7. * @http://www.projectpier.org/
  8. */
  9. final class DB {
  10. /** ID of primary connection **/
  11. const PRIMARY_CONNECTION_ID = 'PRIMARY';
  12. /**
  13. * Collection of connections
  14. *
  15. * @var array
  16. */
  17. static private $connections = array();
  18. /**
  19. * ID of primary connection. This connection will be used if connection name is not suplied
  20. *
  21. * @var string
  22. */
  23. static private $primary_connection = self::PRIMARY_CONNECTION_ID;
  24. /**
  25. * SQL log
  26. *
  27. * @var array
  28. */
  29. static private $sql_log = array();
  30. /**
  31. * This function will return specific connection. If $connection_name is NULL primary connection will be used
  32. *
  33. * @access public
  34. * @param string $connection_name Connection name, if NULL primary connection will be used
  35. * @return AbstractDBAdapter
  36. */
  37. static function connection($connection_name = null) {
  38. if (is_null($connection_name)) {
  39. $connection_name = self::getPrimaryConnection();
  40. } // if
  41. return array_var(self::$connections, $connection_name);
  42. } // connection
  43. /**
  44. * Create new database connection
  45. *
  46. * @access public
  47. * @param string $adapter Adapter name (currently only mysql adapter is implemeted)
  48. * @param array $params Connection params
  49. * @param string $connection_name Name of the connection, if NULL default connection ID will be used
  50. * @return boolean
  51. * @throws FileDnxError
  52. * @throws DBAdapterDnx
  53. */
  54. static function connect($adapter, $params, $connection_name = null) {
  55. $connection_name = is_null($connection_name) || trim($connection_name) == '' ?
  56. self::PRIMARY_CONNECTION_ID :
  57. trim($connection_name);
  58. $adapter = self::connectAdapter($adapter, $params);
  59. if (($adapter instanceof AbstractDBAdapter) && $adapter->isConnected()) {
  60. self::$connections[$connection_name] = $adapter;
  61. return $adapter;
  62. } else {
  63. return null;
  64. } // if
  65. } // connect
  66. /**
  67. * This function will include adapter and try to connect. In case of error DBConnectError will be thrown
  68. *
  69. * @access public
  70. * @param string $adapter_name
  71. * @param array $params
  72. * @return AbstractDBAdapter
  73. * @throws DBAdapterDnx
  74. * @throws DBConnectError
  75. */
  76. private function connectAdapter($adapter_name, $params) {
  77. self::useAdapter($adapter_name);
  78. $adapter_class = self::getAdapterClass($adapter_name);
  79. if (!class_exists($adapter_class)) {
  80. throw new DBAdapterDnx($adapter_name, $adapter_class);
  81. } // if
  82. return new $adapter_class($params);
  83. } // connectAdapter
  84. /**
  85. * Figure out adapter location and include it
  86. *
  87. * @access public
  88. * @param string $adapter_class
  89. * @return void
  90. */
  91. private function useAdapter($adapter_name) {
  92. $adapter_class = self::getAdapterClass($adapter_name);
  93. $path = dirname(__FILE__) . "/adapters/$adapter_class.class.php";
  94. if (!is_readable($path)) {
  95. throw new FileDnxError($path);
  96. } // if
  97. include_once $path;
  98. } // useAdapter
  99. /**
  100. * Return class based on adapter name
  101. *
  102. * @access public
  103. * @param string $adapter_name
  104. * @return string
  105. */
  106. private function getAdapterClass($adapter_name) {
  107. return Inflector::camelize($adapter_name) . 'DBAdapter';
  108. } // getAdapterClass
  109. // ---------------------------------------------------
  110. // Interface to primary adapter
  111. // ---------------------------------------------------
  112. /**
  113. * Execute query and return result
  114. *
  115. * @access public
  116. * @param string $sql
  117. * @return DBResult
  118. * @throws DBQueryError
  119. */
  120. static function execute($sql) {
  121. $arguments = func_get_args();
  122. array_shift($arguments);
  123. $arguments = count($arguments) ? array_flat($arguments) : null;
  124. return self::connection()->execute($sql, $arguments);
  125. } // execute
  126. /**
  127. * Execute query and return first row from result
  128. *
  129. * @access public
  130. * @param string $sql
  131. * @return array
  132. * @throws DBQueryError
  133. */
  134. static function executeOne($sql) {
  135. $arguments = func_get_args();
  136. array_shift($arguments);
  137. $arguments = count($arguments) ? array_flat($arguments) : null;
  138. return self::connection()->executeOne($sql, $arguments);
  139. } // executeOne
  140. /**
  141. * Execute query and return all rows
  142. *
  143. * @access public
  144. * @param string $sql
  145. * @return array
  146. * @throws DBQueryError
  147. */
  148. static function executeAll($sql) {
  149. $arguments = func_get_args();
  150. array_shift($arguments);
  151. $arguments = count($arguments) ? array_flat($arguments) : null;
  152. return self::connection()->executeAll($sql, $arguments);
  153. } // executeAll
  154. /**
  155. * Start transaction
  156. *
  157. * @access public
  158. * @param void
  159. * @return boolean
  160. * @throws DBQueryError
  161. */
  162. static function beginWork() {
  163. return self::connection()->beginWork();
  164. } // beginWork
  165. /**
  166. * Commit transaction
  167. *
  168. * @access public
  169. * @param void
  170. * @return boolean
  171. * @throws DBQueryError
  172. */
  173. static function commit() {
  174. return self::connection()->commit();
  175. } // commit
  176. /**
  177. * Rollback transaction
  178. *
  179. * @access public
  180. * @param void
  181. * @return boolean
  182. * @throws DBQueryError
  183. */
  184. static function rollback() {
  185. return self::connection()->rollback();
  186. } // rollback
  187. /**
  188. * Return insert ID
  189. *
  190. * @access public
  191. * @param void
  192. * @return integer
  193. */
  194. static function lastInsertId() {
  195. return self::connection()->lastInsertId();
  196. } // lastInsertId
  197. /**
  198. * Return number of affected rows
  199. *
  200. * @access public
  201. * @param void
  202. * @return integer
  203. */
  204. static function affectedRows() {
  205. return self::connection()->affectedRows();
  206. } // affectedRows
  207. /**
  208. * Escape value
  209. *
  210. * @access public
  211. * @param mixed $value
  212. * @return string
  213. */
  214. static function escape($value) {
  215. return self::connection()->escapeValue($value);
  216. } // escape
  217. /**
  218. * Escape field / table name
  219. *
  220. * @access public
  221. * @param string $field
  222. * @return string
  223. */
  224. static function escapeField($field) {
  225. return self::connection()->escapeField($field);
  226. } // escapeField
  227. /**
  228. * Prepare string. Replace every '?' with matching escaped value
  229. *
  230. * @param string $sql
  231. * @param array $arguments Array of arguments
  232. * @return string
  233. */
  234. static function prepareString($sql, $arguments = null) {
  235. if (is_array($arguments) && count($arguments)) {
  236. foreach ($arguments as $argument) {
  237. $sql = str_replace_first('?', DB::escape($argument), $sql);
  238. } // foreach
  239. } // if
  240. return $sql;
  241. } // prepareString
  242. // ---------------------------------------------------
  243. // Getters and setters
  244. // ---------------------------------------------------
  245. /**
  246. * Get primary_connection
  247. *
  248. * @access public
  249. * @param null
  250. * @return string
  251. */
  252. static function getPrimaryConnection() {
  253. return self::$primary_connection;
  254. } // getPrimaryConnection
  255. /**
  256. * Set primary_connection value
  257. *
  258. * @access public
  259. * @param string $value
  260. * @return null
  261. * @throws Error if connection does not exists
  262. */
  263. static function setPrimaryConnection($value) {
  264. if (!isset(self::$connections[$value])) {
  265. throw new Error("Connection '$value' does not exists");
  266. } // if
  267. self::$primary_connection = $value;
  268. } // setPrimaryConnection
  269. /**
  270. * Add query to SQL log
  271. *
  272. * @access public
  273. * @param string $sql
  274. * @return void
  275. */
  276. function addToSQLLog($sql) {
  277. self::$sql_log[] = $sql;
  278. } // addToSQLLog
  279. /**
  280. * Return SQL log
  281. *
  282. * @access public
  283. * @param void
  284. * @return array
  285. */
  286. function getSQLLog() {
  287. return self::$sql_log;
  288. } // getSQLLog
  289. } // DB
  290. ?>