PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/cacti-0.8.8a/lib/database.php

#
PHP | 358 lines | 296 code | 20 blank | 42 comment | 30 complexity | 4d6aac645c655fb0316dcb9b49841556 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. +-------------------------------------------------------------------------+
  4. | Copyright (C) 2004-2012 The Cacti Group |
  5. | |
  6. | This program is free software; you can redistribute it and/or |
  7. | modify it under the terms of the GNU General Public License |
  8. | as published by the Free Software Foundation; either version 2 |
  9. | of the License, or (at your option) any later version. |
  10. | |
  11. | This program is distributed in the hope that it will be useful, |
  12. | but WITHOUT ANY WARRANTY; without even the implied warranty of |
  13. | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
  14. | GNU General Public License for more details. |
  15. +-------------------------------------------------------------------------+
  16. | Cacti: The Complete RRDTool-based Graphing Solution |
  17. +-------------------------------------------------------------------------+
  18. | This code is designed, written, and maintained by the Cacti Group. See |
  19. | about.php and/or the AUTHORS file for specific developer information. |
  20. +-------------------------------------------------------------------------+
  21. | http://www.cacti.net/ |
  22. +-------------------------------------------------------------------------+
  23. */
  24. /* db_connect_real - makes a connection to the database server
  25. @arg $host - the hostname of the database server, 'localhost' if the database server is running
  26. on this machine
  27. @arg $user - the username to connect to the database server as
  28. @arg $pass - the password to connect to the database server with
  29. @arg $db_name - the name of the database to connect to
  30. @arg $db_type - the type of database server to connect to, only 'mysql' is currently supported
  31. @arg $retries - the number a time the server should attempt to connect before failing
  32. @returns - (bool) '1' for success, '0' for error */
  33. function db_connect_real($host, $user, $pass, $db_name, $db_type, $port = "3306", $db_ssl = false, $retries = 20) {
  34. global $cnn_id;
  35. $i = 0;
  36. $dsn = "$db_type://" . rawurlencode($user) . ":" . rawurlencode($pass) . "@" . rawurlencode($host) . "/" . rawurlencode($db_name) . "?persist";
  37. if ($db_ssl && $db_type == "mysql") {
  38. $dsn .= "&clientflags=" . MYSQL_CLIENT_SSL;
  39. }elseif ($db_ssl && $db_type == "mysqli") {
  40. $dsn .= "&clientflags=" . MYSQLI_CLIENT_SSL;
  41. }
  42. if ($port != "3306") {
  43. $dsn .= "&port=" . $port;
  44. }
  45. while ($i <= $retries) {
  46. $cnn_id = ADONewConnection($dsn);
  47. if ($cnn_id) {
  48. return($cnn_id);
  49. }
  50. $i++;
  51. usleep(40000);
  52. }
  53. die("FATAL: Cannot connect to MySQL server on '$host'. Please make sure you have specified a valid MySQL database name in 'include/config.php'\n");
  54. return(0);
  55. }
  56. /* db_close - closes the open connection
  57. @returns - the result of the close command */
  58. function db_close($db_conn = FALSE) {
  59. global $cnn_id;
  60. if (!$db_conn) {
  61. return $cnn_id->Close();
  62. }else{
  63. return $db_conn->Close();
  64. }
  65. }
  66. /* db_execute - run an sql query and do not return any output
  67. @arg $sql - the sql query to execute
  68. @arg $log - whether to log error messages, defaults to true
  69. @returns - '1' for success, '0' for error */
  70. function db_execute($sql, $log = TRUE, $db_conn = FALSE) {
  71. global $cnn_id;
  72. /* check for a connection being passed, if not use legacy behavior */
  73. if (!$db_conn) {
  74. $db_conn = $cnn_id;
  75. }
  76. $sql = str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql)));
  77. if (read_config_option("log_verbosity") == POLLER_VERBOSITY_DEVDBG) {
  78. cacti_log("DEVEL: SQL Exec: \"" . $sql . "\"", FALSE);
  79. }
  80. $errors = 0;
  81. while (1) {
  82. $query = $db_conn->Execute($sql);
  83. if (($db_conn->ErrorNo() == 0) || ($db_conn->ErrorNo() == 1032)) {
  84. return(1);
  85. }else if (($db_conn->ErrorNo() == 1049) || ($db_conn->ErrorNo() == 1051)) {
  86. printf("FATAL: Database or Table does not exist");
  87. exit;
  88. }else if (($log) || (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)) {
  89. if ((substr_count($db_conn->ErrorMsg(), "Deadlock")) || ($db_conn->ErrorNo() == 1213) || ($db_conn->ErrorNo() == 1205)) {
  90. $errors++;
  91. if ($errors > 30) {
  92. cacti_log("ERROR: Too many Lock/Deadlock errors occurred! SQL:'" . str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql))) ."'", TRUE);
  93. return(0);
  94. }else{
  95. usleep(500000);
  96. continue;
  97. }
  98. }else{
  99. cacti_log("ERROR: A DB Exec Failed!, Error:'" . $db_conn->ErrorNo() . "', SQL:\"" . str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql))) . "'", FALSE);
  100. return(0);
  101. }
  102. }
  103. }
  104. }
  105. /* db_fetch_cell - run a 'select' sql query and return the first column of the
  106. first row found
  107. @arg $sql - the sql query to execute
  108. @arg $col_name - use this column name instead of the first one
  109. @arg $log - whether to log error messages, defaults to true
  110. @returns - (bool) the output of the sql query as a single variable */
  111. function db_fetch_cell($sql, $col_name = '', $log = TRUE, $db_conn = FALSE) {
  112. global $cnn_id;
  113. /* check for a connection being passed, if not use legacy behavior */
  114. if (!$db_conn) {
  115. $db_conn = $cnn_id;
  116. }
  117. $sql = str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql)));
  118. if (read_config_option("log_verbosity") == POLLER_VERBOSITY_DEVDBG) {
  119. cacti_log("DEVEL: SQL Cell: \"" . $sql . "\"", FALSE);
  120. }
  121. if ($col_name != '') {
  122. $db_conn->SetFetchMode(ADODB_FETCH_ASSOC);
  123. }else{
  124. $db_conn->SetFetchMode(ADODB_FETCH_NUM);
  125. }
  126. $query = $db_conn->Execute($sql);
  127. if (($db_conn->ErrorNo() == 0) || ($db_conn->ErrorNo() == 1032)) {
  128. if (!$query->EOF) {
  129. if ($col_name != '') {
  130. $column = $query->fields[$col_name];
  131. }else{
  132. $column = $query->fields[0];
  133. }
  134. $query->close();
  135. return($column);
  136. }
  137. }else if (($db_conn->ErrorNo() == 1049) || ($db_conn->ErrorNo() == 1051)) {
  138. printf("FATAL: Database or Table does not exist");
  139. exit;
  140. }else if (($log) || (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)) {
  141. cacti_log("ERROR: SQL Cell Failed!, Error:'" . $db_conn->ErrorNo() . "', SQL:\"" . str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql))) . "\"", FALSE);
  142. }
  143. }
  144. /* db_fetch_row - run a 'select' sql query and return the first row found
  145. @arg $sql - the sql query to execute
  146. @arg $log - whether to log error messages, defaults to true
  147. @returns - the first row of the result as a hash */
  148. function db_fetch_row($sql, $log = TRUE, $db_conn = FALSE) {
  149. global $cnn_id;
  150. /* check for a connection being passed, if not use legacy behavior */
  151. if (!$db_conn) {
  152. $db_conn = $cnn_id;
  153. }
  154. $sql = str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql)));
  155. if (($log) && (read_config_option("log_verbosity") == POLLER_VERBOSITY_DEVDBG)) {
  156. cacti_log("DEVEL: SQL Row: \"" . $sql . "\"", FALSE);
  157. }
  158. $db_conn->SetFetchMode(ADODB_FETCH_ASSOC);
  159. $query = $db_conn->Execute($sql);
  160. if (($db_conn->ErrorNo() == 0) || ($db_conn->ErrorNo() == 1032)) {
  161. if (!$query->EOF) {
  162. $fields = $query->fields;
  163. $query->close();
  164. return($fields);
  165. }
  166. }else if (($db_conn->ErrorNo() == 1049) || ($db_conn->ErrorNo() == 1051)) {
  167. printf("FATAL: Database or Table does not exist");
  168. exit;
  169. }else if (($log) || (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)) {
  170. cacti_log("ERROR: SQL Row Failed!, Error:'" . $db_conn->ErrorNo() . "', SQL:\"" . str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql))) . "\"", FALSE);
  171. }
  172. }
  173. /* db_fetch_assoc - run a 'select' sql query and return all rows found
  174. @arg $sql - the sql query to execute
  175. @arg $log - whether to log error messages, defaults to true
  176. @returns - the entire result set as a multi-dimensional hash */
  177. function db_fetch_assoc($sql, $log = TRUE, $db_conn = FALSE) {
  178. global $cnn_id;
  179. /* check for a connection being passed, if not use legacy behavior */
  180. if (!$db_conn) {
  181. $db_conn = $cnn_id;
  182. }
  183. $sql = str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql)));
  184. if (read_config_option("log_verbosity") == POLLER_VERBOSITY_DEVDBG) {
  185. cacti_log("DEVEL: SQL Assoc: \"" . $sql . "\"", FALSE);
  186. }
  187. $data = array();
  188. $db_conn->SetFetchMode(ADODB_FETCH_ASSOC);
  189. $query = $db_conn->Execute($sql);
  190. if (($db_conn->ErrorNo() == 0) || ($db_conn->ErrorNo() == 1032)) {
  191. while ((!$query->EOF) && ($query)) {
  192. $data{sizeof($data)} = $query->fields;
  193. $query->MoveNext();
  194. }
  195. $query->close();
  196. return($data);
  197. }else if (($db_conn->ErrorNo() == 1049) || ($db_conn->ErrorNo() == 1051)) {
  198. printf("FATAL: Database or Table does not exist");
  199. exit;
  200. }else if (($log) || (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)) {
  201. cacti_log("ERROR: SQL Assoc Failed!, Error:'" . $db_conn->ErrorNo() . "', SQL:\"" . str_replace("\n", "", str_replace("\r", "", str_replace("\t", " ", $sql))) . "\"");
  202. }
  203. }
  204. /* db_fetch_insert_id - get the last insert_id or auto incriment
  205. @returns - the id of the last auto incriment row that was created */
  206. function db_fetch_insert_id($db_conn = FALSE) {
  207. global $cnn_id;
  208. /* check for a connection being passed, if not use legacy behavior */
  209. if (!$db_conn) {
  210. $db_conn = $cnn_id;
  211. }
  212. return $db_conn->Insert_ID();
  213. }
  214. /* array_to_sql_or - loops through a single dimensional array and creates an sql like
  215. * (sql_column in (value1, value2, value3, ...))
  216. @arg $array - the array to convert
  217. @arg $sql_column - the column to set each item in the array equal to
  218. @returns - a string that can be placed in a SQL OR statement */
  219. function array_to_sql_or($array, $sql_column) {
  220. /* if the last item is null; pop it off */
  221. if ((empty($array{count($array)-1})) && (sizeof($array) > 1)) {
  222. array_pop($array);
  223. }
  224. if (count($array) > 0) {
  225. $sql_or = "($sql_column IN(";
  226. for ($i=0;($i<count($array));$i++) {
  227. if (is_array($array[$i]) && array_key_exists($sql_column, $array[$i])) {
  228. $sql_or .= (($i == 0) ? "'":",'") . $array[$i][$sql_column] . "'";
  229. } else {
  230. $sql_or .= (($i == 0) ? "'":",'") . $array[$i] . "'";
  231. }
  232. }
  233. $sql_or .= "))";
  234. return $sql_or;
  235. }
  236. }
  237. /* db_replace - replaces the data contained in a particular row
  238. @arg $table_name - the name of the table to make the replacement in
  239. @arg $array_items - an array containing each column -> value mapping in the row
  240. @arg $keyCols - the name of the column containing the primary key
  241. @arg $autoQuote - whether to use intelligent quoting or not
  242. @returns - the auto incriment id column (if applicable) */
  243. function db_replace($table_name, $array_items, $keyCols, $db_conn = FALSE) {
  244. global $cnn_id;
  245. /* check for a connection being passed, if not use legacy behavior */
  246. if (!$db_conn) {
  247. $db_conn = $cnn_id;
  248. }
  249. $db_conn->Replace($table_name, $array_items, $keyCols);
  250. return $db_conn->Insert_ID();
  251. }
  252. /* sql_save - saves data to an sql table
  253. @arg $array_items - an array containing each column -> value mapping in the row
  254. @arg $table_name - the name of the table to make the replacement in
  255. @arg $key_cols - the primary key(s)
  256. @returns - the auto incriment id column (if applicable) */
  257. function sql_save($array_items, $table_name, $key_cols = "id", $autoinc = TRUE, $db_conn = FALSE) {
  258. global $cnn_id;
  259. if (read_config_option("log_verbosity") == POLLER_VERBOSITY_DEVDBG) {
  260. cacti_log("DEVEL: SQL Save on table '$table_name': \"" . serialize($array_items) . "\"", FALSE);
  261. }
  262. /* check for a connection being passed, if not use legacy behavior */
  263. if (!$db_conn) {
  264. $db_conn = $cnn_id;
  265. }
  266. while (list($key, $value) = each($array_items)) {
  267. $array_items[$key] = "\"" . sql_sanitize($value) . "\"";
  268. }
  269. $replace_result = $db_conn->Replace($table_name, $array_items, $key_cols, FALSE, $autoinc);
  270. if ($replace_result == 0) {
  271. cacti_log("ERROR: SQL Save Command Failed for Table '$table_name'. Error was '" . $cnn_id->ErrorMsg() . "'", false);
  272. return 0;
  273. }
  274. /* get the last AUTO_ID and return it */
  275. if (($db_conn->Insert_ID() == "0") || ($replace_result == 1)) {
  276. if (!is_array($key_cols)) {
  277. if (isset($array_items[$key_cols])) {
  278. return str_replace("\"", "", $array_items[$key_cols]);
  279. }
  280. }
  281. return 0;
  282. }else{
  283. return $db_conn->Insert_ID();
  284. }
  285. }
  286. /* sql_sanitize - removes and quotes unwanted chars in values passed for use in SQL statements
  287. @arg $value - value to sanitize
  288. @return - fixed value */
  289. function sql_sanitize($value) {
  290. //$value = str_replace("'", "''", $value);
  291. $value = str_replace(";", "\;", $value);
  292. return $value;
  293. }
  294. ?>