PageRenderTime 48ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/class.dbconnection.php

http://pork-dbobject.googlecode.com/
PHP | 668 lines | 309 code | 68 blank | 291 comment | 47 complexity | c974e40a6b080a62e4b271336eab0fba MD5 | raw file
  1. <?php
  2. /**
  3. *
  4. * By Jelle Ursem
  5. *
  6. * Ultra-simple database abstraction class.
  7. * Reads settings from a properties file and takes care of executing queries.
  8. * You can easily extend this class to add new database types.
  9. * see http://code.google.com/p/pork-dbobject/ for more info
  10. *
  11. * @package Pork
  12. */
  13. /**
  14. * dbConnection class
  15. * Handles database connections and querying/inserting/removal of rows.
  16. *
  17. * @package Pork
  18. * @author Jelle Ursem
  19. * @copyright Jelle Ursem 2009
  20. * @version 2.0
  21. * @access public
  22. */
  23. class dbConnection
  24. {
  25. public $adapter, $insertID, $log, $debug;
  26. /**
  27. * dbConnection::__construct()
  28. * Reads settings from the default settings file and creates the connection.
  29. * @param String $useAlternative Alternative settings file
  30. */
  31. function __construct($instanceName='Database')
  32. {
  33. $this->adapter = $this->getAdapter(Settings::Load()->Get($instanceName));
  34. $this->debug = Settings::Load()->Get($instanceName, 'debug') === '1';
  35. }
  36. /**
  37. * dbConnection::getInstance()
  38. * Singleton functionality.
  39. * Creates a static instance.
  40. * Usage: DbConnection::getInstance($name)->fetchAll("show tables");
  41. * @return DbConnection instance
  42. */
  43. public static function getInstance($instanceName='Database')
  44. {
  45. static $instances = array();
  46. if (!array_key_exists($instanceName, $instances))
  47. {
  48. $instances[$instanceName] = new dbConnection($instanceName);
  49. }
  50. return $instances[$instanceName];
  51. }
  52. /**
  53. * dbConnection::getAdapter()
  54. *
  55. * Returns the correct adapter class for the current database type.
  56. *
  57. */
  58. private function getAdapter($connectInfo)
  59. {
  60. if(class_exists($connectInfo['dbtype']."Adapter"))
  61. {
  62. $adapterclass = "{$connectInfo['dbtype']}Adapter";
  63. $adapter = new $adapterclass($connectInfo);
  64. }
  65. else
  66. {
  67. die("Adapter not found for database connection {$connectInfo->dbtype}");
  68. }
  69. return($adapter);
  70. }
  71. /**
  72. * dbConnection::connect()
  73. * Creates the actual connection
  74. * @return bool did the connection succeed
  75. */
  76. function connect()
  77. {
  78. $this->connection = $this->adapter->connect();
  79. if ($this->connection)
  80. {
  81. return true;
  82. }
  83. else
  84. {
  85. logger::getInstance()->LogEmail(get_class($this->adapter).' : could not connect');
  86. }
  87. return false;
  88. }
  89. function escapeValue($value)
  90. {
  91. return($this->adapter->escapeValue($value));
  92. }
  93. /**
  94. * dbConnection::numrows()
  95. * Find out the number of rows returned
  96. * @return int Number of rows
  97. */
  98. function numrows()
  99. {
  100. return($this->adapter->numRows($this->result));
  101. }
  102. /**
  103. * dbConnection::query()
  104. * Execute the passed query on the database and determine if insert_id or affected_rows or numrows has to be called.
  105. * @param String $query Query to be executed.
  106. * @returns mixed ID if inserted row, false on error
  107. */
  108. function query($query)
  109. {
  110. if($this->adapter->connection == false) {
  111. logger::getInstance()->LogEmail('Not connected');
  112. return false;
  113. }
  114. if($this->debug) Logger::getInstance()->log[]= "executing: {$query}";
  115. $result = $this->adapter->query($query);
  116. if(!$result)
  117. {
  118. $error = $this->adapter->getError();
  119. if($error != '' && $this->adapter->connection != false) Logger::Warn("Error '{$error}' during execution of query {$query}");
  120. return false;
  121. }
  122. $query = trim(strtolower($query));
  123. $firstpart = substr($query, 0, 6);
  124. $this->insertID = false;
  125. $this->affected = false;
  126. $this->numrows = false;
  127. switch($firstpart)
  128. {
  129. case 'insert':
  130. $this->insertID = $this->adapter->getInsertID();
  131. break;
  132. case 'delete':
  133. case 'replac':
  134. case 'update':
  135. $this->affected = $this->adapter->numAffected();
  136. break;
  137. case 'select':
  138. $this->numrows = $this->adapter->numRows();
  139. break;
  140. }
  141. if ($this->insertID != false) { return ($this->insertID); }
  142. return true;
  143. }
  144. /**
  145. * dbConnection::fetchOne()
  146. * Execute the query and return result # 0.
  147. * If no query is passed it will use the previous result.
  148. * @param $query optional query to execute.
  149. * @returns String $output
  150. */
  151. function fetchOne($query)
  152. {
  153. return ($this->adapter->fetchOne($query));
  154. }
  155. /**
  156. * dbConnection::fetchAll()
  157. * Execute the passed query and fetch a multi-dimensional array of results using $func
  158. * If no query is passed it will use the previous result.
  159. * @param $query optional query to execute.
  160. * @param $func function to use. Can use mysql_fetch_array or mysql_fetch_object or mysql_fetch_assoc at will.
  161. * @returns Array|Object $output multi dimensional array of output.
  162. */
  163. function fetchAll($query=false, $type='assoc')
  164. {
  165. return($this->adapter->fetchAll($query, $type));
  166. }
  167. /**
  168. * dbConnection::fetchRow()
  169. * Execute the passed query and fetch only one row of results using $func
  170. * If no query is passed it will use the previous result.
  171. * @param $query optional query to execute.
  172. * @param $func function to use. Can use array or object or assoc at will.
  173. * @returns Array|Object $output multi dimensional array of output.
  174. */
  175. function fetchRow($query=false, $type='assoc')
  176. {
  177. return ($this->adapter->fetchRow($query, $type));
  178. }
  179. /**
  180. * dbConnection::setDatabase()
  181. *
  182. * @param mixed $val
  183. * @return
  184. */
  185. function setDatabase($val)
  186. {
  187. $this->adapter->setDatabase($val);
  188. }
  189. /**
  190. * dbConnection::getError()
  191. * Returns the last error from the database connection.
  192. * @return string error
  193. */
  194. function getError()
  195. {
  196. return($this->adapter->getError());
  197. }
  198. /**
  199. * dbConnection::getQueries()
  200. * Returns an array with executed SQL queries.
  201. * @return array $queries
  202. */
  203. function getQueries()
  204. {
  205. return($this->adapter->queries);
  206. }
  207. /**
  208. * dbConnection::tableExists()
  209. * @param string $table talble to check if exists
  210. * @return boolean exists
  211. */
  212. function tableExists($table)
  213. {
  214. return($this->adapter->tableExists($table));
  215. }
  216. }
  217. /**
  218. * dbConnectionAdapter interface.
  219. *
  220. * Defines all the functions a database adapter should have to be working with Pork.dbObject
  221. *
  222. * @package Pork
  223. * @author Jelle Ursem
  224. * @copyright Jelle Ursem 2009
  225. * @version 1.0
  226. * @access public
  227. */
  228. interface dbConnectionAdapter
  229. {
  230. public function __construct($info);
  231. public function connect($host, $username,$password);
  232. public function escapeValue($value);
  233. public function fetchOne($query=false);
  234. public function fetchRow($query=false, $type='assoc');
  235. public function fetchAll($query=false, $type='assoc');
  236. public function getError();
  237. public function getInsertID();
  238. public function numRows();
  239. public function numAffected();
  240. public function query($query);
  241. public function selectDatabase($db);
  242. public function tableExists($table);
  243. }
  244. /**
  245. * MySQLAdapter
  246. *
  247. * @package Pork
  248. * @author Jelle Ursem
  249. * @copyright Jelle Ursem 2009
  250. * @version 1.0
  251. * @access public
  252. */
  253. class MySQLAdapter implements dbConnectionAdapter
  254. {
  255. public $connection;
  256. public $result;
  257. public $database;
  258. public $queries;
  259. /**
  260. * MySQLAdapter::__construct()
  261. *
  262. * @param mixed $info
  263. * @return void
  264. */
  265. public function __construct($info)
  266. {
  267. $this->database = $info['database'];
  268. $this->connection = $this->connect($info['host'], $info['username'], $info['password']);
  269. $this->queries = array();
  270. }
  271. /**
  272. * MySQLAdapter::escapeValue()
  273. *
  274. * @param mixed $value
  275. * @return
  276. */
  277. public function escapeValue($value)
  278. {
  279. return mysql_real_escape_string($value);
  280. }
  281. /**
  282. * MySQLAdapter::connect()
  283. *
  284. * @param mixed $host
  285. * @param mixed $username
  286. * @param mixed $password
  287. * @return
  288. */
  289. public function connect($host, $username, $password)
  290. {
  291. return mysql_connect($host, $username, $password);
  292. }
  293. /**
  294. * MySQLAdapter::query()
  295. *
  296. * @param mixed $query
  297. * @return
  298. */
  299. public function query($query)
  300. {
  301. $this->queries[] = $query;
  302. if(!$this->selectDatabase($this->database)) return false;
  303. $this->result = mysql_query($query, $this->connection);
  304. return($this->result);
  305. }
  306. /**
  307. * MySQLAdapter::fetchOne()
  308. *
  309. * @param bool $query
  310. * @return
  311. */
  312. public function fetchOne($query=false)
  313. {
  314. if($query != false) $this->query($query);
  315. if($this->result != false && mysql_num_rows($this->result) > 0 && mysql_num_fields($this->result) > 0)
  316. {
  317. return( mysql_result($this->result,0) );
  318. }
  319. return false;
  320. }
  321. /**
  322. * MySQLAdapter::fetchRow()
  323. *
  324. * @param bool $query
  325. * @param string $type
  326. * @return
  327. */
  328. /**
  329. * MySQLAdapter::fetchRow()
  330. *
  331. * @param bool $query
  332. * @param string $type
  333. * @return
  334. */
  335. public function fetchRow($query=false, $type='assoc')
  336. {
  337. if($query != false) $this->query($query);
  338. if($this->result != false)
  339. {
  340. $func = "mysql_fetch_{$type}";
  341. return($func($this->result));
  342. }
  343. return false;
  344. }
  345. /**
  346. * MySQLAdapter::fetchAll()
  347. *
  348. * @param bool $query
  349. * @param string $type
  350. * @return
  351. */
  352. public function fetchAll($query=false, $type='assoc')
  353. {
  354. if($query != false) $this->query($query);
  355. if($this->result !== false)
  356. {
  357. $func = "mysql_fetch_{$type}";
  358. $output = array();
  359. while ($row = $func($this->result))
  360. {
  361. $output[] = $row;
  362. }
  363. return $output;
  364. }
  365. return false;
  366. }
  367. /**
  368. * MySQLAdapter::getInsertID()
  369. *
  370. * @return
  371. */
  372. public function getInsertID()
  373. {
  374. return mysql_insert_id($this->connection);
  375. }
  376. /**
  377. * MySQLAdapter::numRows()
  378. *
  379. * @return
  380. */
  381. public function numRows()
  382. {
  383. return ($this->result) ? mysql_num_rows($this->result) : 0;
  384. }
  385. /**
  386. * MySQLAdapter::numAffected()
  387. *
  388. * @return
  389. */
  390. public function numAffected()
  391. {
  392. return ($this->result) ? @mysql_affected_rows($this->result) : 0;
  393. }
  394. /**
  395. * MySQLAdapter::selectDatabase()
  396. *
  397. * @param mixed $db
  398. * @return
  399. */
  400. public function selectDatabase($db)
  401. {
  402. return mysql_select_db($db, $this->connection);
  403. }
  404. /**
  405. * MySQLAdapter::tableExists()
  406. *
  407. * @param mixed $table
  408. * @return
  409. */
  410. public function tableExists($table)
  411. {
  412. $input = $this->fetchOne("SHOW TABLES FROM {$this->database} LIKE '{$table}'");
  413. return($input != false);
  414. }
  415. /**
  416. * MySQLAdapter::getError()
  417. *
  418. * @return
  419. */
  420. public function getError()
  421. {
  422. return mysql_error($this->connection);
  423. }
  424. }
  425. /**
  426. * SQLiteAdapter
  427. *
  428. * @package Pork
  429. * @author Jelle Ursem
  430. * @copyright Jelle Ursem 2009
  431. * @version 1.0
  432. * @access public
  433. */
  434. class SQLiteAdapter implements dbConnectionAdapter
  435. {
  436. public $connection, $result,$database,$queries;
  437. /**
  438. * SQLiteAdapter::__construct()
  439. *
  440. * @param mixed $info
  441. * @return void
  442. */
  443. public function __construct($info)
  444. {
  445. $error = false;
  446. $this->database = $info['database'];
  447. $this->connection = $this->connect($info['database'], $info['mode'],$error);
  448. if($error != false)
  449. {
  450. echo print_array($error, 'SQLITE connection error');
  451. }
  452. }
  453. /**
  454. * SQLiteAdapter::escapeValue()
  455. *
  456. * @param mixed $value
  457. * @return
  458. */
  459. public function escapeValue($value)
  460. {
  461. return sqlite_escape_string($value);
  462. }
  463. /**
  464. * SQLiteAdapter::connect()
  465. *
  466. * @param mixed $host
  467. * @param mixed $username
  468. * @param mixed $password
  469. * @return
  470. */
  471. public function connect($host, $username, $password)
  472. {
  473. return sqlite_open($host, $username, $password);
  474. }
  475. /**
  476. * SQLiteAdapter::query()
  477. *
  478. * @param mixed $query
  479. * @return
  480. */
  481. public function query($query)
  482. {
  483. $this->result = sqlite_query($query, $this->connection);
  484. return($this->result);
  485. }
  486. /**
  487. * SQLiteAdapter::fetchOne()
  488. *
  489. * @param bool $query
  490. * @return
  491. */
  492. public function fetchOne($query=false)
  493. {
  494. if ($query != false) $this->query($query);
  495. if($this->result !== false)
  496. {
  497. return( sqlite_fetch_single($this->result) );
  498. }
  499. return false;
  500. }
  501. /**
  502. * SQLiteAdapter::fetchRow()
  503. *
  504. * @param bool $query
  505. * @param string $type
  506. * @return
  507. */
  508. public function fetchRow($query=false, $type='assoc')
  509. {
  510. if ($query != false) $this->query($query);
  511. if($this->result !== false)
  512. {
  513. $func = "sqlite_fetch_{$type}";
  514. return( $func($this->result, 0));
  515. }
  516. return false;
  517. }
  518. /**
  519. * SQLiteAdapter::fetchAll()
  520. *
  521. * @param bool $query
  522. * @param string $type
  523. * @return
  524. */
  525. public function fetchAll($query=false, $type='assoc')
  526. {
  527. if ($query != false) $this->query($query);
  528. if($this->result !== false)
  529. {
  530. if($type == 'assoc') return(sqlite_fetch_all($this->result, SQLITE_ASSOC));
  531. if($type == 'object')
  532. {
  533. $output = array();
  534. while ($row = sqlite_fetch_object($this->result))
  535. {
  536. $output[] = $row;
  537. }
  538. }
  539. return $output;
  540. }
  541. return false;
  542. }
  543. /**
  544. * SQLiteAdapter::getInsertID()
  545. *
  546. * @return
  547. */
  548. public function getInsertID()
  549. {
  550. return sqlite_last_insert_rowid($this->connection);
  551. }
  552. /**
  553. * SQLiteAdapter::numRows()
  554. *
  555. * @return
  556. */
  557. public function numRows()
  558. {
  559. return ($this->result) ? mysql_num_rows($this->result) : 0;
  560. }
  561. /**
  562. * SQLiteAdapter::numAffected()
  563. *
  564. * @return
  565. */
  566. public function numAffected()
  567. {
  568. return ($this->result) ? @mysql_affected_rows($this->result) : 0;
  569. }
  570. /**
  571. * SQLiteAdapter::selectDatabase()
  572. *
  573. * @param mixed $db
  574. * @return
  575. */
  576. public function selectDatabase($db)
  577. {
  578. return $this->connect($db);
  579. }
  580. /**
  581. * SQLiteAdapter::getError()
  582. *
  583. * @return
  584. */
  585. public function getError()
  586. {
  587. return sqlite_error_string(sqlite_last_error($this->connection));
  588. }
  589. /**
  590. * SQLiteAdapter::tableExists()
  591. *
  592. * @param mixed $table
  593. * @return
  594. */
  595. public function tableExists($table)
  596. {
  597. $input = $this->fetchOne("SELECT count(name) FROM sqlite_master WHERE type='table' and name='{$table}'");
  598. return($input == 1);
  599. }
  600. }