PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/theme/templates/ezSQL/shared/ez_sql_core.php

https://bitbucket.org/dpxlogistic/digitalefs
PHP | 639 lines | 381 code | 123 blank | 135 comment | 54 complexity | 7e48fa6a36696a95e890964b20e7d0d8 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, MPL-2.0-no-copyleft-exception, CC-BY-3.0, GPL-2.0, GPL-3.0, Apache-2.0, LGPL-2.1, 0BSD
  1. <?php
  2. /**********************************************************************
  3. * Author: Justin Vincent (jv@vip.ie)
  4. * Web...: http://justinvincent.com
  5. * Name..: ezSQL
  6. * Desc..: ezSQL Core module - database abstraction library to make
  7. * it very easy to deal with databases. ezSQLcore can not be used by
  8. * itself (it is designed for use by database specific modules).
  9. *
  10. */
  11. /**********************************************************************
  12. * ezSQL Constants
  13. */
  14. define('EZSQL_VERSION', '2.17');
  15. define('OBJECT', 'OBJECT');
  16. define('ARRAY_A', 'ARRAY_A');
  17. define('ARRAY_N', 'ARRAY_N');
  18. /**********************************************************************
  19. * Core class containg common functions to manipulate query result
  20. * sets once returned
  21. */
  22. class ezSQLcore
  23. {
  24. var $trace = false; // same as $debug_all
  25. var $debug_all = false; // same as $trace
  26. var $debug_called = false;
  27. var $vardump_called = false;
  28. var $show_errors = true;
  29. var $num_queries = 0;
  30. var $conn_queries = 0;
  31. var $last_query = null;
  32. var $last_error = null;
  33. var $col_info = null;
  34. var $captured_errors = array();
  35. var $cache_dir = false;
  36. var $cache_queries = false;
  37. var $cache_inserts = false;
  38. var $use_disk_cache = false;
  39. var $cache_timeout = 24; // hours
  40. var $timers = array();
  41. var $total_query_time = 0;
  42. var $db_connect_time = 0;
  43. var $trace_log = array();
  44. var $use_trace_log = false;
  45. var $sql_log_file = false;
  46. var $do_profile = false;
  47. var $profile_times = array();
  48. // == TJH == default now needed for echo of debug function
  49. var $debug_echo_is_on = true;
  50. /**********************************************************************
  51. * Constructor
  52. */
  53. function ezSQLcore()
  54. {
  55. }
  56. /**********************************************************************
  57. * Get host and port from an "host:port" notation.
  58. * Returns array of host and port. If port is omitted, returns $default
  59. */
  60. function get_host_port( $host, $default = false )
  61. {
  62. $port = $default;
  63. if ( false !== strpos( $host, ':' ) ) {
  64. list( $host, $port ) = explode( ':', $host );
  65. $port = (int) $port;
  66. }
  67. return array( $host, $port );
  68. }
  69. /**********************************************************************
  70. * Print SQL/DB error - over-ridden by specific DB class
  71. */
  72. function register_error($err_str)
  73. {
  74. // Keep track of last error
  75. $this->last_error = $err_str;
  76. // Capture all errors to an error array no matter what happens
  77. $this->captured_errors[] = array
  78. (
  79. 'error_str' => $err_str,
  80. 'query' => $this->last_query
  81. );
  82. }
  83. /**********************************************************************
  84. * Turn error handling on or off..
  85. */
  86. function show_errors()
  87. {
  88. $this->show_errors = true;
  89. }
  90. function hide_errors()
  91. {
  92. $this->show_errors = false;
  93. }
  94. /**********************************************************************
  95. * Kill cached query results
  96. */
  97. function flush()
  98. {
  99. // Get rid of these
  100. $this->last_result = null;
  101. $this->col_info = null;
  102. $this->last_query = null;
  103. $this->from_disk_cache = false;
  104. }
  105. /**********************************************************************
  106. * Get one variable from the DB - see docs for more detail
  107. */
  108. function get_var($query=null,$x=0,$y=0)
  109. {
  110. // Log how the function was called
  111. $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
  112. // If there is a query then perform it if not then use cached results..
  113. if ( $query )
  114. {
  115. $this->query($query);
  116. }
  117. // Extract var out of cached results based x,y vals
  118. if ( $this->last_result[$y] )
  119. {
  120. $values = array_values(get_object_vars($this->last_result[$y]));
  121. }
  122. // If there is a value return it else return null
  123. return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null;
  124. }
  125. /**********************************************************************
  126. * Get one row from the DB - see docs for more detail
  127. */
  128. function get_row($query=null,$output=OBJECT,$y=0)
  129. {
  130. // Log how the function was called
  131. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  132. // If there is a query then perform it if not then use cached results..
  133. if ( $query )
  134. {
  135. $this->query($query);
  136. }
  137. // If the output is an object then return object using the row offset..
  138. if ( $output == OBJECT )
  139. {
  140. return $this->last_result[$y]?$this->last_result[$y]:null;
  141. }
  142. // If the output is an associative array then return row as such..
  143. elseif ( $output == ARRAY_A )
  144. {
  145. return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null;
  146. }
  147. // If the output is an numerical array then return row as such..
  148. elseif ( $output == ARRAY_N )
  149. {
  150. return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null;
  151. }
  152. // If invalid output type was specified..
  153. else
  154. {
  155. $this->show_errors ? trigger_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N",E_USER_WARNING) : null;
  156. }
  157. }
  158. /**********************************************************************
  159. * Function to get 1 column from the cached result set based in X index
  160. * see docs for usage and info
  161. */
  162. function get_col($query=null,$x=0)
  163. {
  164. $new_array = array();
  165. // If there is a query then perform it if not then use cached results..
  166. if ( $query )
  167. {
  168. $this->query($query);
  169. }
  170. // Extract the column values
  171. $j = count($this->last_result);
  172. for ( $i=0; $i < $j; $i++ )
  173. {
  174. $new_array[$i] = $this->get_var(null,$x,$i);
  175. }
  176. return $new_array;
  177. }
  178. /**********************************************************************
  179. * Return the the query as a result set - see docs for more details
  180. */
  181. function get_results($query=null, $output = OBJECT)
  182. {
  183. // Log how the function was called
  184. $this->func_call = "\$db->get_results(\"$query\", $output)";
  185. // If there is a query then perform it if not then use cached results..
  186. if ( $query )
  187. {
  188. $this->query($query);
  189. }
  190. // Send back array of objects. Each row is an object
  191. if ( $output == OBJECT )
  192. {
  193. return $this->last_result;
  194. }
  195. elseif ( $output == ARRAY_A || $output == ARRAY_N )
  196. {
  197. if ( $this->last_result )
  198. {
  199. $i=0;
  200. foreach( $this->last_result as $row )
  201. {
  202. $new_array[$i] = get_object_vars($row);
  203. if ( $output == ARRAY_N )
  204. {
  205. $new_array[$i] = array_values($new_array[$i]);
  206. }
  207. $i++;
  208. }
  209. return $new_array;
  210. }
  211. else
  212. {
  213. return array();
  214. }
  215. }
  216. }
  217. /**********************************************************************
  218. * Function to get column meta data info pertaining to the last query
  219. * see docs for more info and usage
  220. */
  221. function get_col_info($info_type="name",$col_offset=-1)
  222. {
  223. if ( $this->col_info )
  224. {
  225. if ( $col_offset == -1 )
  226. {
  227. $i=0;
  228. foreach($this->col_info as $col )
  229. {
  230. $new_array[$i] = $col->{$info_type};
  231. $i++;
  232. }
  233. return $new_array;
  234. }
  235. else
  236. {
  237. return $this->col_info[$col_offset]->{$info_type};
  238. }
  239. }
  240. }
  241. /**********************************************************************
  242. * store_cache
  243. */
  244. function store_cache($query,$is_insert)
  245. {
  246. // The would be cache file for this query
  247. $cache_file = $this->cache_dir.'/'.md5($query);
  248. // disk caching of queries
  249. if ( $this->use_disk_cache && ( $this->cache_queries && ! $is_insert ) || ( $this->cache_inserts && $is_insert ))
  250. {
  251. if ( ! is_dir($this->cache_dir) )
  252. {
  253. $this->register_error("Could not open cache dir: $this->cache_dir");
  254. $this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir",E_USER_WARNING) : null;
  255. }
  256. else
  257. {
  258. // Cache all result values
  259. $result_cache = array
  260. (
  261. 'col_info' => $this->col_info,
  262. 'last_result' => $this->last_result,
  263. 'num_rows' => $this->num_rows,
  264. 'return_value' => $this->num_rows,
  265. );
  266. file_put_contents($cache_file, serialize($result_cache));
  267. if( file_exists($cache_file . ".updating") )
  268. unlink($cache_file . ".updating");
  269. }
  270. }
  271. }
  272. /**********************************************************************
  273. * get_cache
  274. */
  275. function get_cache($query)
  276. {
  277. // The would be cache file for this query
  278. $cache_file = $this->cache_dir.'/'.md5($query);
  279. // Try to get previously cached version
  280. if ( $this->use_disk_cache && file_exists($cache_file) )
  281. {
  282. // Only use this cache file if less than 'cache_timeout' (hours)
  283. if ( (time() - filemtime($cache_file)) > ($this->cache_timeout*3600) &&
  284. !(file_exists($cache_file . ".updating") && (time() - filemtime($cache_file . ".updating") < 60)) )
  285. {
  286. touch($cache_file . ".updating"); // Show that we in the process of updating the cache
  287. }
  288. else
  289. {
  290. $result_cache = unserialize(file_get_contents($cache_file));
  291. $this->col_info = $result_cache['col_info'];
  292. $this->last_result = $result_cache['last_result'];
  293. $this->num_rows = $result_cache['num_rows'];
  294. $this->from_disk_cache = true;
  295. // If debug ALL queries
  296. $this->trace || $this->debug_all ? $this->debug() : null ;
  297. return $result_cache['return_value'];
  298. }
  299. }
  300. }
  301. /**********************************************************************
  302. * Dumps the contents of any input variable to screen in a nicely
  303. * formatted and easy to understand way - any type: Object, Var or Array
  304. */
  305. function vardump($mixed='')
  306. {
  307. // Start outup buffering
  308. ob_start();
  309. echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>";
  310. echo "<pre><font face=arial>";
  311. if ( ! $this->vardump_called )
  312. {
  313. echo "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font>\n\n";
  314. }
  315. $var_type = gettype ($mixed);
  316. print_r(($mixed?$mixed:"<font color=red>No Value / False</font>"));
  317. echo "\n\n<b>Type:</b> " . ucfirst($var_type) . "\n";
  318. echo "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")."\n";
  319. echo "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")."\n";
  320. echo "<b>Last Rows Returned:</b> ".count($this->last_result)."\n";
  321. echo "</font></pre></font></blockquote></td></tr></table>".$this->donation();
  322. echo "\n<hr size=1 noshade color=dddddd>";
  323. // Stop output buffering and capture debug HTML
  324. $html = ob_get_contents();
  325. ob_end_clean();
  326. // Only echo output if it is turned on
  327. if ( $this->debug_echo_is_on )
  328. {
  329. echo $html;
  330. }
  331. $this->vardump_called = true;
  332. return $html;
  333. }
  334. /**********************************************************************
  335. * Alias for the above function
  336. */
  337. function dumpvar($mixed)
  338. {
  339. $this->vardump($mixed);
  340. }
  341. /**********************************************************************
  342. * Displays the last query string that was sent to the database & a
  343. * table listing results (if there were any).
  344. * (abstracted into a seperate file to save server overhead).
  345. */
  346. function debug($print_to_screen=true)
  347. {
  348. // Start outup buffering
  349. ob_start();
  350. echo "<blockquote>";
  351. // Only show ezSQL credits once..
  352. if ( ! $this->debug_called )
  353. {
  354. echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p>\n";
  355. }
  356. if ( $this->last_error )
  357. {
  358. echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>";
  359. }
  360. if ( $this->from_disk_cache )
  361. {
  362. echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>";
  363. }
  364. echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> ";
  365. echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>";
  366. echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>";
  367. echo "<blockquote>";
  368. if ( $this->col_info )
  369. {
  370. // =====================================================
  371. // Results top rows
  372. echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>";
  373. echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>";
  374. for ( $i=0, $j=count($this->col_info); $i < $j; $i++ )
  375. {
  376. /* when selecting count(*) the maxlengh is not set, size is set instead. */
  377. echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type}";
  378. if (!isset($this->col_info[$i]->max_length))
  379. {
  380. echo "{$this->col_info[$i]->size}";
  381. } else {
  382. echo "{$this->col_info[$i]->max_length}";
  383. }
  384. echo "</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>";
  385. }
  386. echo "</tr>";
  387. // ======================================================
  388. // print main results
  389. if ( $this->last_result )
  390. {
  391. $i=0;
  392. foreach ( $this->get_results(null,ARRAY_N) as $one_row )
  393. {
  394. $i++;
  395. echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>";
  396. foreach ( $one_row as $item )
  397. {
  398. echo "<td nowrap><font face=arial size=2>$item</font></td>";
  399. }
  400. echo "</tr>";
  401. }
  402. } // if last result
  403. else
  404. {
  405. echo "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>";
  406. }
  407. echo "</table>";
  408. } // if col_info
  409. else
  410. {
  411. echo "<font face=arial size=2>No Results</font>";
  412. }
  413. echo "</blockquote></blockquote>".$this->donation()."<hr noshade color=dddddd size=1>";
  414. // Stop output buffering and capture debug HTML
  415. $html = ob_get_contents();
  416. ob_end_clean();
  417. // Only echo output if it is turned on
  418. if ( $this->debug_echo_is_on && $print_to_screen)
  419. {
  420. echo $html;
  421. }
  422. $this->debug_called = true;
  423. return $html;
  424. }
  425. /**********************************************************************
  426. * Naughty little function to ask for some remuniration!
  427. */
  428. function donation()
  429. {
  430. return "<font size=1 face=arial color=000000>If ezSQL has helped <a href=\"https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0\" style=\"color: 0000CC;\">make a donation!?</a> &nbsp;&nbsp;<!--[ go on! you know you want to! ]--></font>";
  431. }
  432. /**********************************************************************
  433. * Timer related functions
  434. */
  435. function timer_get_cur()
  436. {
  437. list($usec, $sec) = explode(" ",microtime());
  438. return ((float)$usec + (float)$sec);
  439. }
  440. function timer_start($timer_name)
  441. {
  442. $this->timers[$timer_name] = $this->timer_get_cur();
  443. }
  444. function timer_elapsed($timer_name)
  445. {
  446. return round($this->timer_get_cur() - $this->timers[$timer_name],2);
  447. }
  448. function timer_update_global($timer_name)
  449. {
  450. if ( $this->do_profile )
  451. {
  452. $this->profile_times[] = array
  453. (
  454. 'query' => $this->last_query,
  455. 'time' => $this->timer_elapsed($timer_name)
  456. );
  457. }
  458. $this->total_query_time += $this->timer_elapsed($timer_name);
  459. }
  460. /**********************************************************************
  461. * Creates a SET nvp sql string from an associative array (and escapes all values)
  462. *
  463. * Usage:
  464. *
  465. * $db_data = array('login'=>'jv','email'=>'jv@vip.ie', 'user_id' => 1, 'created' => 'NOW()');
  466. *
  467. * $db->query("INSERT INTO users SET ".$db->get_set($db_data));
  468. *
  469. * ...OR...
  470. *
  471. * $db->query("UPDATE users SET ".$db->get_set($db_data)." WHERE user_id = 1");
  472. *
  473. * Output:
  474. *
  475. * login = 'jv', email = 'jv@vip.ie', user_id = 1, created = NOW()
  476. */
  477. function get_set($params)
  478. {
  479. if( !is_array( $params ) )
  480. {
  481. $this->register_error( 'get_set() parameter invalid. Expected array in '.__FILE__.' on line '.__LINE__);
  482. return;
  483. }
  484. $sql = array();
  485. foreach ( $params as $field => $val )
  486. {
  487. if ( $val === 'true' || $val === true )
  488. $val = 1;
  489. if ( $val === 'false' || $val === false )
  490. $val = 0;
  491. switch( $val ){
  492. case 'NOW()' :
  493. case 'NULL' :
  494. $sql[] = "$field = $val";
  495. break;
  496. default :
  497. $sql[] = "$field = '".$this->escape( $val )."'";
  498. }
  499. }
  500. return implode( ', ' , $sql );
  501. }
  502. /**
  503. * Function for operating query count
  504. *
  505. * @param bool $all Set to false for function to return queries only during this connection
  506. * @param bool $increase Set to true to increase query count (internal usage)
  507. * @return int Returns query count base on $all
  508. */
  509. function count ($all = true, $increase = false) {
  510. if ($increase) {
  511. $this->num_queries++;
  512. $this->conn_queries++;
  513. }
  514. return ($all) ? $this->num_queries : $this->conn_queries;
  515. }
  516. }