PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/www/includes/mysql.php

https://github.com/openaustralia/twfy
PHP | 364 lines | 166 code | 73 blank | 125 comment | 27 complexity | 2f4b1ff33a47b25fc317aec2bcd2541d MD5 | raw file
  1. <?php
  2. /* MYSQL class
  3. Depends on having the debug() and getmicrotime() functions available elsewhere to output debugging info.
  4. Somewhere (probably in includes/easyparliament/init.php) there should be something like:
  5. Class ParlDB extends MySQL {
  6. function ParlDB () {
  7. $this->init (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
  8. }
  9. }
  10. Then, when you need to do queries, you do:
  11. $db = new ParlDB;
  12. $q = $db->query("SELECT haddock FROM fish");
  13. $q is then a MySQLQuery object.
  14. If other databases are needed, we just need to create a class for each, each one
  15. extending MySQL.
  16. Call $db->display_total_duration() at the end of a page to send total query time to debug().
  17. (n is 0-based below...)
  18. After a SELECT
  19. ==============
  20. If successful:
  21. $q->success() returns true.
  22. $q->rows() returns the number of rows selected
  23. $q->row(n) returns an array of the nth row, with the keys being column names.
  24. $q->field(n,col) returns the contents of the "col" column in the nth row.
  25. $q->insert_id() returns NULL.
  26. $q->affected_rows() returns NULL.
  27. If 0 rows selected:
  28. $q->success() returns true.
  29. $q->rows() returns 0.
  30. $q->row(n) returns an empty array.
  31. $q->field(n,col) returns "".
  32. $q->insert_id() returns NULL.
  33. $q->affected_rows() returns NULL.
  34. After an INSERT
  35. ===============
  36. If successful:
  37. $q->success() returns true.
  38. $q->rows() returns NULL.
  39. $q->row(n) returns an empty array.
  40. $q->field(n,col) returns "".
  41. $q->insert_id() returns the last_insert_id (if there's AUTO_INCREMENT on a column).
  42. $q->affected_rows() returns 1.
  43. After an UPDATE
  44. ===============
  45. If rows have been changed:
  46. $q->success() returns true.
  47. $q->rows() returns NULL.
  48. $q->row(n) returns an empty array.
  49. $q->field(n,col) returns "".
  50. $q->insert_id() returns 0.
  51. $q->affected_rows() returns the number of rows changed.
  52. After a DELETE
  53. ==============
  54. If rows have been deleted:
  55. $q->success() returns true.
  56. $q->rows() returns NULL.
  57. $q->row(n) returns an empty array.
  58. $q->field(n,col) returns "".
  59. $q->insert_id() returns 0.
  60. $q->affected_rows() returns the number of rows changed.
  61. If no rows are deleted:
  62. $q->success() returns true.
  63. $q->rows() returns NULL.
  64. $q->row(n) returns an empty array.
  65. $q->field(n,col) returns "".
  66. $q->insert_id() returns 0.
  67. $q->affected_rows() returns 0.
  68. If there's an error for any of the above actions:
  69. $q->success() returns false.
  70. $q->rows() returns NULL.
  71. $q->row(n) returns an empty array.
  72. $q->field(n,col) returns "".
  73. $q->insert_id() returns NULL.
  74. $q->affected_rows() returns NULL.
  75. Versions
  76. ========
  77. v1.2 2003-11-25
  78. Changed to using named constants, rather than global variables.
  79. */
  80. // We'll add up the times of each query so we can output the page total at the end.
  81. global $mysqltotalduration;
  82. $mysqltotalduration = 0.0;
  83. Class MySQLQuery {
  84. var $fieldnames_byid = array();
  85. var $fieldnames_byname = array();
  86. var $success = true;
  87. var $rows = NULL;
  88. var $fields = 0;
  89. var $data = array();
  90. var $insert_id = NULL;
  91. var $affected_rows = NULL;
  92. function MySQLQuery ($conn) {
  93. $this->conn = $conn;
  94. }
  95. function query ($sql="") {
  96. if (empty($sql)) {
  97. $this->success = false;
  98. return;
  99. }
  100. if (empty($this->conn)) {
  101. $this->success = false;
  102. return;
  103. }
  104. twfy_debug ("SQL", $sql);
  105. $q = mysql_query($sql,$this->conn) or $this->error(mysql_errno().": ".mysql_error());
  106. if ($this->success) {
  107. if ( (!$q) or (empty($q)) ) {
  108. // A failed query.
  109. $this->success = false;
  110. return;
  111. } elseif (is_bool($q)) {
  112. // A successful query of a type *other* than
  113. // SELECT, SHOW, EXPLAIN or DESCRIBE
  114. // For INSERTs that have generated an id from an AUTO_INCREMENT column.
  115. $this->insert_id = mysql_insert_id();
  116. $this->affected_rows = mysql_affected_rows();
  117. $this->success = true;
  118. return;
  119. } else {
  120. // A successful SELECT, SHOW, EXPLAIN or DESCRIBE query.
  121. $this->success = true;
  122. $result = array();
  123. for ($i = 0; $i < mysql_num_fields($q); $i++) {
  124. $fieldnames_byid[$i] = mysql_field_name($q, $i);
  125. $fieldnames_byname[mysql_field_name($q, $i)] = $i;
  126. }
  127. for ($row = 0; $row < mysql_num_rows($q); $row++) {
  128. $result[$row] = mysql_fetch_row($q);
  129. }
  130. if (sizeof($result) > 0) {
  131. $this->rows = sizeof($result);
  132. } else {
  133. $this->rows = 0;
  134. }
  135. $this->fieldnames_byid = $fieldnames_byid;
  136. $this->fieldnames_byname = $fieldnames_byname;
  137. $this->fields = sizeof($fieldnames_byid);
  138. $this->data = $result;
  139. twfy_debug ("SQLRESULT", $this->_display_result());
  140. mysql_free_result($q);
  141. return;
  142. }
  143. } else {
  144. // There was an SQL error.
  145. return;
  146. }
  147. }
  148. function success() {
  149. return $this->success;
  150. }
  151. // After INSERTS.
  152. function insert_id() {
  153. return $this->insert_id;
  154. }
  155. // After INSERT, UPDATE, DELETE.
  156. function affected_rows() {
  157. return $this->affected_rows;
  158. }
  159. // After SELECT.
  160. function field($row_index, $column_name) {
  161. if ($this->rows > 0) {
  162. # Old slow version
  163. # $result = $this->_row_array($row_index);
  164. # return $result[$column_name];
  165. # New faster version
  166. $result = $this->data[$row_index][$this->fieldnames_byname[$column_name]];
  167. return $result;
  168. } else {
  169. return "";
  170. }
  171. }
  172. // After SELECT.
  173. function rows() {
  174. return $this->rows;
  175. }
  176. // After SELECT.
  177. function row($row_index) {
  178. if ($this->success) {
  179. $result = $this->_row_array($row_index);
  180. return $result;
  181. } else {
  182. return array();
  183. }
  184. }
  185. function _row_array($row_index) {
  186. $result = array();
  187. if ($this->rows > 0) {
  188. $fields = $this->data[$row_index];
  189. foreach ($fields as $index => $data) {
  190. $fieldname = $this->fieldnames_byid[$index];
  191. $result[$fieldname] = $data;
  192. }
  193. }
  194. return $result;
  195. }
  196. function _display_result() {
  197. $html = "";
  198. if (count($this->fieldnames_byid) > 0) {
  199. $html .= "<table border=\"1\">\n<tr>\n";
  200. foreach ($this->fieldnames_byid as $index => $fieldname) {
  201. $html .= "<th>".htmlentities($fieldname)."</th>";
  202. }
  203. $html .= "</tr>\n";
  204. foreach ($this->data as $index => $row) {
  205. $html .= "<tr>";
  206. foreach ($row as $n => $field) {
  207. if ($this->fieldnames_byid[$n] == "email" || $this->fieldnames_byid[$n] == "password" || $this->fieldnames_byid[$n] == "postcode") {
  208. // Don't want to risk this data being displayed on any page.
  209. $html .= "<td>**MASKED**</td>";
  210. } else {
  211. $html .= "<td>".htmlentities($field)."</td>";
  212. }
  213. }
  214. $html .= "</tr>\n";
  215. }
  216. $html .= "</table>\n";
  217. }
  218. return $html;
  219. }
  220. function error($errormsg) {
  221. // When a query goes wrong...
  222. $this->success = false;
  223. trigger_error($errormsg, E_USER_ERROR);
  224. return;
  225. }
  226. // End MySQLQuery class
  227. }
  228. $global_connection = null;
  229. Class MySQL {
  230. function init ($db_host, $db_user, $db_pass, $db_name) {
  231. global $global_connection;
  232. // These vars come from config.php.
  233. if (!$global_connection) {
  234. $conn = mysql_connect($db_host, $db_user, $db_pass);
  235. if(!$conn) {
  236. print ("<p>DB connection attempt failed.</p>");
  237. exit;
  238. }
  239. if(!mysql_select_db($db_name, $conn)) {
  240. print ("<p>DB select failed</p>");
  241. exit;
  242. }
  243. $global_connection = $conn;
  244. }
  245. $this->conn = $global_connection;
  246. // Select default character set
  247. $q = new MySQLQuery($this->conn);
  248. return true;
  249. }
  250. function query ($sql) {
  251. // Pass it an SQL query and if the query was successful
  252. // it returns a MySQLQuery object which you can get results from.
  253. $start = getmicrotime();
  254. $q = new MySQLQuery($this->conn);
  255. $q->query($sql);
  256. $duration = getmicrotime() - $start;
  257. global $mysqltotalduration;
  258. $mysqltotalduration += $duration;
  259. twfy_debug ("SQL", "Complete after $duration seconds.");
  260. // We could also output $q->mysql_info() here, but that's for
  261. // PHP >= 4.3.0.
  262. return $q;
  263. }
  264. // Call at the end of a page.
  265. function display_total_duration () {
  266. global $mysqltotalduration;
  267. twfy_debug ("TIME", "Total time for MySQL queries on this page: " . $mysqltotalduration . " seconds.");
  268. }
  269. // End MySQL class
  270. }
  271. ?>