Files
cacti/lib/database.php
T
cigamit 4b11861226 Beef up validation logging
Make html validation logging similar to SQL logging.
2015-08-02 14:02:32 -05:00

947 lines
33 KiB
PHP

<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2015 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
/* db_connect_real - makes a connection to the database server
@param $device - the hostname of the database server, 'localhost' if the database server is running
on this machine
@param $user - the username to connect to the database server as
@param $pass - the password to connect to the database server with
@param $db_name - the name of the database to connect to
@param $db_type - the type of database server to connect to, only 'mysql' is currently supported
@param $retries - the number a time the server should attempt to connect before failing
@returns - (bool) '1' for success, '0' for error */
function db_connect_real($device, $user, $pass, $db_name, $db_type = 'mysql', $port = '3306', $db_ssl = false, $retries = 20) {
global $database_sessions;
$i = 0;
$error = '';
if (isset($database_sessions["$device:$port:$db_name"])) {
return $database_sessions["$device:$port:$db_name"];
}
$flags = array();
if ($db_type == 'mysql') {
// Using 'localhost' will force unix sockets mode, which breaks when attempting to use mysql on a different port
if ($device == 'localhost' && $port != '3306') {
$device = '127.0.0.1';
}
$flags[PDO::ATTR_PERSISTENT] = true;
$flags[PDO::MYSQL_ATTR_FOUND_ROWS] = true;
if ($db_ssl) {
// PDO requires paths to certificates for SSL support, will have to figure out the best way to handle this
// I believe they can instead setup these parameters in their mysql config file in [client]
//$flags[PDO::MYSQL_ATTR_SSL_KEY] = '/path/to/client-key.pem';
//$flags[PDO::MYSQL_ATTR_SSL_CERT] = '/path/to/client-cert.pem';
//$flags[PDO::MYSQL_ATTR_SSL_CA] = '/path/to/ca-cert.pem';
}
}
while ($i <= $retries) {
try {
$cnn_id = new PDO("$db_type:host=$device;port=$port;dbname=$db_name;charset=utf8", $user, $pass, $flags);
$cnn_id->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
$database_sessions["$device:$port:$db_name"] = $cnn_id;
return $cnn_id;
} catch (PDOException $e) {
// Must catch this exception or else PDO will display an error with our username/password
//print $e->getMessage();
//exit;
}
$i++;
usleep(40000);
}
return FALSE;
}
/* db_close - closes the open connection
@returns - the result of the close command */
function db_close($db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$db_conn = null;
$database_sessions["$database_hostname:$database_port:$database_default"] = null;
return TRUE;
}
/* db_execute - run an sql query and do not return any output
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - '1' for success, '0' for error */
function db_execute($sql, $log = TRUE, $db_conn = FALSE) {
return db_execute_prepared($sql, array(), $log, $db_conn);
}
/* db_execute_prepared - run an sql query and do not return any output
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - '1' for success, '0' for error */
function db_execute_prepared($sql, $parms = array(), $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $config, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$sql = trim(str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))), ';');
if (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG) {
cacti_log('DEVEL: SQL Exec: "' . $sql . '"', FALSE);
}
$errors = 0;
$db_conn->affected_rows = 0;
while (1) {
$query = $db_conn->prepare($sql);
$query->execute($parms);
if ($query->errorCode()) {
$errorinfo = $query->errorInfo();
$en = $errorinfo[1];
}elseif ($db_conn->errorCode()) {
$errorinfo = $db_conn->errorInfo();
$en = $errorinfo[1];
}else{
$en = '';
}
if ($en == '') {
// With PDO, we have to free this up
$db_conn->affected_rows = $query->rowCount();
$query->closeCursor();
unset($query);
return TRUE;
} else if (($log) || (read_config_option('log_verbosity') >= POLLER_VERBOSITY_DEBUG)) {
if ($en == 1213 || $en == 1205) { //substr_count(mysql_error($db_conn), 'Deadlock')
$errors++;
if ($errors > 30) {
cacti_log("ERROR: Too many Lock/Deadlock errors occurred! SQL:'" . str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))) . "'", TRUE);
return FALSE;
} else {
usleep(500000);
continue;
}
} else {
cacti_log("ERROR: A DB Exec Failed!, Error:$en, SQL:\"" . str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))) . "'", FALSE);
cacti_log('ERROR: A DB Exec Failed!, Error: ' . $errorinfo[2]);
cacti_debug_backtrace('SQL');
return FALSE;
}
}
}
unset($query);
return FALSE;
}
/* db_fetch_cell - run a 'select' sql query and return the first column of the
first row found
@param $sql - the sql query to execute
@param $col_name - use this column name instead of the first one
@param $log - whether to log error messages, defaults to true
@returns - (bool) the output of the sql query as a single variable */
function db_fetch_cell($sql, $col_name = '', $log = TRUE, $db_conn = FALSE) {
return db_fetch_cell_prepared($sql, array(), $col_name, $log, $db_conn);
}
/* db_fetch_cell_prepared - run a 'select' sql query and return the first column of the
first row found
@param $sql - the sql query to execute
@param $col_name - use this column name instead of the first one
@param $log - whether to log error messages, defaults to true
@returns - (bool) the output of the sql query as a single variable */
function db_fetch_cell_prepared($sql, $parms = array(), $col_name = '', $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $config, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$sql = str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql)));
if (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG) {
cacti_log('DEVEL: SQL Cell: "' . $sql . '"', FALSE);
}
$db_conn->affected_rows = 0;
$query = $db_conn->prepare($sql);
$query->execute($parms);
$errorinfo = $query->errorInfo();
$en = $errorinfo[1];
if ($en == '') {
$db_conn->affected_rows = $query->rowCount();
$q = $query->fetchAll(PDO::FETCH_BOTH);
$query->closeCursor();
unset($query);
if (isset($q[0]) && is_array($q[0])) {
if ($col_name != '') {
return $q[0][$col_name];
} else {
return reset($q[0]);
}
}
return FALSE;
}else if (($log) || (read_config_option('log_verbosity') >= POLLER_VERBOSITY_DEBUG)) {
cacti_log("ERROR: SQL Cell Failed!, Error:$en, SQL:\"" . str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))) . '"', FALSE);
cacti_log('ERROR: SQL Cell Failed!, Error: ' . $errorinfo[2]);
cacti_debug_backtrace('SQL');
}
if (isset($query)) unset($query);
return FALSE;
}
/* db_fetch_row - run a 'select' sql query and return the first row found
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - the first row of the result as a hash */
function db_fetch_row($sql, $log = TRUE, $db_conn = FALSE) {
return db_fetch_row_prepared($sql, array(), $log, $db_conn);
}
/* db_fetch_row_prepared - run a 'select' sql query and return the first row found
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - the first row of the result as a hash */
function db_fetch_row_prepared($sql, $parms = array(), $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $config, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$sql = str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql)));
if (($log) && (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG)) {
cacti_log('DEVEL: SQL Row: "' . $sql . '"', FALSE);
}
$db_conn->affected_rows = 0;
$query = $db_conn->prepare($sql);
$query->execute($parms);
$errorinfo = $query->errorInfo();
$en = $errorinfo[1];
if ($en == '') {
$db_conn->affected_rows = $query->rowCount();
$q = $query->fetchAll(PDO::FETCH_ASSOC);
$query->closeCursor();
unset($query);
if (isset($q[0])) {
return $q[0];
} else {
return array();
}
}else if (($log) || (read_config_option('log_verbosity') >= POLLER_VERBOSITY_DEBUG)) {
cacti_log("ERROR: SQL Row Failed!, Error:$en, SQL:\"" . str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))) . '"', FALSE);
cacti_log('ERROR: SQL Row Failed!, Error: ' . $errorinfo[2]);
cacti_debug_backtrace('SQL');
}
if (isset($query)) unset($query);
return array();
}
/* db_fetch_assoc - run a 'select' sql query and return all rows found
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - the entire result set as a multi-dimensional hash */
function db_fetch_assoc($sql, $log = TRUE, $db_conn = FALSE) {
return db_fetch_assoc_prepared($sql, array(), $log, $db_conn);
}
/* db_fetch_assoc_prepared - run a 'select' sql query and return all rows found
@param $sql - the sql query to execute
@param $log - whether to log error messages, defaults to true
@returns - the entire result set as a multi-dimensional hash */
function db_fetch_assoc_prepared($sql, $parms = array(), $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $config, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$sql = str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql)));
if (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG) {
cacti_log('DEVEL: SQL Assoc: "' . $sql . '"', FALSE);
}
$db_conn->affected_rows = 0;
$query = $db_conn->prepare($sql);
$query->execute($parms);
$errorinfo = $query->errorInfo();
$en = $errorinfo[1];
if ($en == '') {
$db_conn->affected_rows = $query->rowCount();
$a = $query->fetchAll(PDO::FETCH_ASSOC);
$query->closeCursor();
unset($query);
if (!is_array($a)) {
$a = array();
}
return $a;
}else if (($log) || (read_config_option('log_verbosity') >= POLLER_VERBOSITY_DEBUG)) {
cacti_log("ERROR: SQL Assoc Failed!, Error:$en, SQL:\"" . str_replace("\n", '', str_replace("\r", '', str_replace("\t", ' ', $sql))) . '"');
cacti_log('ERROR: SQL Assoc Failed!, Error: ' . $errorinfo[2]);
cacti_debug_backtrace('SQL');
}
if (isset($query)) unset($query);
return array();
}
/* db_fetch_insert_id - get the last insert_id or auto incriment
@returns - the id of the last auto incriment row that was created */
function db_fetch_insert_id($db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if ($db_conn) {
return $db_conn->lastInsertId();
}
return FALSE;
}
/* db_affected_rows - return the number of rows affected by the last transaction
* @returns - the number of rows affected by the last transaction */
function db_affected_rows($db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
return $db_conn->affected_rows;
}
/* db_add_column - add a column to table
@param $table - the name of the table
@param $column - array of column data ex: array('name' => 'test' . rand(1, 200), 'type' => 'varchar (255)', 'NULL' => false)
@param $log - whether to log error messages, defaults to true
@returns - '1' for success, '0' for error */
function db_add_column ($table, $column, $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
$columns = array();
foreach($result as $arr) {
$columns[] = $arr['Field'];
}
if (isset($column['name']) && !in_array($column['name'], $columns)) {
$sql = 'ALTER TABLE `' . $table . '` ADD `' . $column['name'] . '`';
if (isset($column['type']))
$sql .= ' ' . $column['type'];
if (isset($column['unsigned']))
$sql .= ' unsigned';
if (isset($column['NULL']) && $column['NULL'] == false)
$sql .= ' NOT NULL';
if (isset($column['NULL']) && $column['NULL'] == true && !isset($column['default']))
$sql .= ' default NULL';
if (isset($column['default']))
$sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
if (isset($column['auto_increment']))
$sql .= ' auto_increment';
if (isset($column['after']))
$sql .= ' AFTER ' . $column['after'];
return db_execute($sql, $log, $db_conn);
}
return true;
}
/* db_remove_column - remove a column to table
@param $table - the name of the table
@param $column - column name
@param $log - whether to log error messages, defaults to true
@returns - '1' for success, '0' for error */
function db_remove_column ($table, $column, $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
$result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
$columns = array();
foreach($result as $arr) {
$columns[] = $arr['Field'];
}
if (isset($column) && in_array($column, $columns)) {
$sql = 'ALTER TABLE `' . $table . '` DROP `' . $column . '`';
return db_execute($sql, $log, $db_conn);
}
return true;
}
/* db_table_exists - checks whether a table exists
@param $table - the name of the table
@param $log - whether to log error messages, defaults to true
@returns - (bool) the output of the sql query as a single variable */
function db_table_exists($table, $log = TRUE, $db_conn = FALSE) {
return (db_fetch_cell("SHOW TABLES LIKE '$table'", '', $log, $db_conn) ? true : false);
}
/* db_column_exists - checks whether a column exists
@param $table - the name of the table
@param $log - whether to log error messages, defaults to true
@returns - (bool) the output of the sql query as a single variable */
function db_column_exists($table, $column, $log = TRUE, $db_conn = FALSE) {
return (db_fetch_cell("SHOW columns FROM `$table` LIKE '$column'", '', $log, $db_conn) ? true : false);
}
function db_update_table ($table, $data, $removecolumns = FALSE, $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
if (!db_table_exists($table, $log, $db_conn)) {
return db_table_create ($table, $data, $log, $db_conn);
}
$allcolumns = array();
foreach ($data['columns'] as $column) {
$allcolumns[] = $column['name'];
if (!db_column_exists($table, $column['name'], $log, $db_conn)) {
db_add_column ($table, $column, $log, $db_conn);
} else {
// Check that column is correct and fix it
// FIXME: Need to still check default value
$arr = db_fetch_row("SHOW columns FROM `$table` LIKE '" . $column['name'] . "'", $log, $db_conn);
if ($column['type'] != $arr['Type'] || (isset($column['NULL']) && ($column['NULL'] ? 'YES' : 'NO') != $arr['Null'])
|| (isset($column['auto_increment']) && ($column['auto_increment'] ? 'auto_increment' : '') != $arr['Extra'])) {
$sql = 'ALTER TABLE `' . $table . '` CHANGE `' . $column['name'] . '` `' . $column['name'] . '`';
if (isset($column['type']))
$sql .= ' ' . $column['type'];
if (isset($column['unsigned']))
$sql .= ' unsigned';
if (isset($column['NULL']) && $column['NULL'] == false)
$sql .= ' NOT NULL';
if (isset($column['NULL']) && $column['NULL'] == true && !isset($column['default']))
$sql .= ' default NULL';
if (isset($column['default']))
$sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
if (isset($column['auto_increment']))
$sql .= ' auto_increment';
db_execute($sql, $log, $db_conn);
}
}
}
if ($removecolumns) {
$result = db_fetch_assoc('SHOW columns FROM `' . $table . '`', $log, $db_conn);
foreach($result as $arr) {
if (!in_array($arr['Field'], $allcolumns)) {
db_remove_column ($table, $arr['Field'], $log, $db_conn);
}
}
}
$info = db_fetch_row("SELECT ENGINE, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_NAME = '$table'");
if (isset($info['TABLE_COMMENT']) && str_replace("'", '', $info['TABLE_COMMENT']) != str_replace("'", '', $data['comment'])) {
db_execute("ALTER TABLE `$table` COMMENT '" . str_replace("'", '', $data['comment']) . "'");
}
if (isset($info['ENGINE']) && strtolower($info['ENGINE']) != strtolower($data['type'])) {
db_execute("ALTER TABLE `$table` ENGINE = " . $data['type']);
}
// Correct any indexes
$indexes = db_fetch_assoc("SHOW INDEX FROM `$table`");
$allindexes = array();
foreach ($indexes as $index) {
$allindexes[$index['Key_name']][$index['Seq_in_index']-1] = $index['Column_name'];
}
foreach ($allindexes as $n => $index) {
if ($n != 'PRIMARY' && isset($data['keys'])) {
$removeindex = TRUE;
foreach ($data['keys'] as $k) {
if ($k['name'] == $n) {
$removeindex = FALSE;
$add = array_diff($k['columns'], $index);
$del = array_diff($index, $k['columns']);
if (!empty($add) || !empty($del)) {
db_execute("ALTER TABLE `$table` DROP INDEX `$n`", $log, $db_conn);
db_execute("ALTER TABLE `$table` ADD INDEX `$n` (`" . (is_array($k['columns']) ? implode('`,`', $k['columns']) : $k['columns']) . '`)', $log, $db_conn);
}
break;
}
}
if ($removeindex) {
db_execute("ALTER TABLE `$table` DROP INDEX `$n`", $log, $db_conn);
}
}
}
// Add any indexes
if (isset($data['keys'])) {
foreach ($data['keys'] as $k) {
if (!isset($allindexes[$k['name']])) {
db_execute("ALTER TABLE `$table` ADD INDEX `" . $k['name'] . '` (`' . (is_array($k['columns']) ? implode('`,`', $k['columns']) : $k['columns']) . '`)', $log, $db_conn);
}
}
}
// FIXME: It won't allow us to drop a primary key that is set to auto_increment
// Check Primary Key
if (!isset($data['primary']) && isset($allindexes['PRIMARY'])) {
db_execute("ALTER TABLE `$table` DROP PRIMARY KEY", $log, $db_conn);
unset($allindexes['PRIMARY']);
}
if (isset($data['primary'])) {
if (!isset($allindexes['PRIMARY'])) {
// No current primary key, so add it
db_execute("ALTER TABLE `$table` ADD PRIMARY KEY(" . $data['primary'] . ")", $log, $db_conn);
} else {
$add = array_diff($data['primary'], $allindexes['PRIMARY']);
$del = array_diff($allindexes['PRIMARY'], $data['primary']);
if (!empty($add) || !empty($del)) {
db_execute("ALTER TABLE `$table` DROP PRIMARY KEY", $log, $db_conn);
db_execute("ALTER TABLE `$table` ADD PRIMARY KEY(`" . (is_array($data['primary']) ? implode('`,`', $data['primary']) : $data['primary']) . "`)", $log, $db_conn);
}
}
}
return TRUE;
}
/* db_table_create - checks whether a table exists
@param $table - the name of the table
@param $data - data array
@param $log - whether to log error messages, defaults to true
@returns - (bool) the output of the sql query as a single variable */
function db_table_create ($table, $data, $log = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (!$db_conn) return FALSE;
if (!db_table_exists($table, $log, $db_conn)) {
$c = 0;
$sql = 'CREATE TABLE `' . $table . "` (\n";
foreach ($data['columns'] as $column) {
if (isset($column['name'])) {
if ($c > 0)
$sql .= ",\n";
$sql .= '`' . $column['name'] . '`';
if (isset($column['type']))
$sql .= ' ' . $column['type'];
if (isset($column['unsigned']))
$sql .= ' unsigned';
if (isset($column['NULL']) && $column['NULL'] == false)
$sql .= ' NOT NULL';
if (isset($column['NULL']) && $column['NULL'] == true && !isset($column['default']))
$sql .= ' default NULL';
if (isset($column['default']))
$sql .= ' default ' . (is_numeric($column['default']) ? $column['default'] : "'" . $column['default'] . "'");
if (isset($column['auto_increment']))
$sql .= ' auto_increment';
$c++;
}
}
if (isset($data['primary'])) {
if (is_array($data['primary'])) {
$sql .= ",\n PRIMARY KEY (`" . implode('`,`'. $data['primary']) . '`)';
} else {
$sql .= ",\n PRIMARY KEY (`" . $data['primary'] . '`)';
}
}
if (isset($data['keys']) && sizeof($data['keys'])) {
foreach ($data['keys'] as $key) {
if (isset($key['name'])) {
if (is_array($key['columns'])) {
$sql .= ",\n KEY `" . $key['name'] . '` (`' . implode('`,`', $key['columns']) . '`)';
} else {
$sql .= ",\n KEY `" . $key['name'] . '` (`' . $key['columns'] . '`)';
}
}
}
}
$sql .= ') ENGINE = ' . $data['type'];
if (isset($data['comment'])) {
$sql .= " COMMENT = '" . $data['comment'] . "'";
}
if (db_execute($sql, $log, $db_conn)) {
return true;
}
return false;
}
}
/* array_to_sql_or - loops through a single dimentional array and converts each
item to a string that can be used in the OR portion of an sql query in the
following form:
column=item1 OR column=item2 OR column=item2 ...
@param $array - the array to convert
@param $sql_column - the column to set each item in the array equal to
@returns - a string that can be placed in a SQL OR statement */
function array_to_sql_or($array, $sql_column) {
/* if the last item is null; pop it off */
if (end($array) === NULL) {
array_pop($array);
}
if (sizeof($array)) {
$sql_or = "($sql_column IN('" . implode("','", $array) . "'))";
return $sql_or;
}
}
/* db_replace - replaces the data contained in a particular row
@param $table_name - the name of the table to make the replacement in
@param $array_items - an array containing each column -> value mapping in the row
@param $keyCols - a string or array of primary keys
@param $autoQuote - whether to use intelligent quoting or not
@returns - the auto incriment id column (if applicable) */
function db_replace($table_name, $array_items, $keyCols, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG) {
cacti_log("DEVEL: SQL Replace on table '$table_name': \"" . serialize($array_items) . '"', FALSE);
}
_db_replace($db_conn, $table_name, $array_items, $keyCols);
return db_fetch_insert_id($db_conn);
}
// FIXME: Need to Rename and cleanup a bit
function _db_replace($db_conn, $table, $fieldArray, $keyCols, $has_autoinc) {
if (!is_array($keyCols)) {
$keyCols = array($keyCols);
}
$sql = "INSERT INTO `$table` (";
$sql2 = '';
$sql3 = '';
$first = true;
$first3 = true;
foreach($fieldArray as $k => $v) {
if (!$first) {
$sql .= ', ';
$sql2 .= ', ';
}
$sql .= "`$k`";
$sql2 .= $v;
$first = false;
if (in_array($k, $keyCols)) continue; // skip UPDATE if is key
if (!$first3) {
$sql3 .= ', ';
}
$sql3 .= "`$k`=VALUES(`$k`)";
$first3 = false;
}
$sql .= ") VALUES ($sql2)" . ($sql3 != '' ? " ON DUPLICATE KEY UPDATE $sql3" : '');
@db_execute($sql);
return db_fetch_insert_id();
}
/* sql_save - saves data to an sql table
@param $array_items - an array containing each column -> value mapping in the row
@param $table_name - the name of the table to make the replacement in
@param $key_cols - the primary key(s)
@returns - the auto incriment id column (if applicable) */
function sql_save($array_items, $table_name, $key_cols = 'id', $autoinc = TRUE, $db_conn = FALSE) {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
if (read_config_option('log_verbosity') == POLLER_VERBOSITY_DEVDBG) {
cacti_log("DEVEL: SQL Save on table '$table_name': \"" . serialize($array_items) . '"', FALSE);
}
while (list($key, $value) = each($array_items)) {
$array_items[$key] = '"' . sql_sanitize($value) . '"';
}
$replace_result = _db_replace($db_conn, $table_name, $array_items, $key_cols, $autoinc);
if ($replace_result === false) {
cacti_log("ERROR: SQL Save Command Failed for Table '$table_name'. Error was '" . mysql_error($db_conn) . "'", false);
return FALSE;
}
/* get the last AUTO_ID and return it */
if (!$replace_result || db_fetch_insert_id($db_conn) == '0') {
if (!is_array($key_cols)) {
if (isset($array_items[$key_cols])) {
return str_replace('"', '', $array_items[$key_cols]);
}
}
return FALSE;
} else {
return $replace_result;
}
}
/* sql_sanitize - removes and quotes unwanted chars in values passed for use in SQL statements
@param $value - value to sanitize
@return - fixed value */
function sql_sanitize($value) {
//$value = str_replace("'", "''", $value);
$value = str_replace(';', "\;", $value);
return $value;
}
/* sql_column_exists - checks if a named column exists in the table specified
@param $table_name - table to check
@param $column_name - column name
@return true or false; */
function sql_column_exists($table_name, $column_name, $db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
$columns = db_fetch_assoc("SHOW COLUMNS FROM `$table_name`", false);
foreach ($columns as $column) {
if ($column_name === $column['name']) {
return true;
}
}
return false;
}
/* sql_function_timestamp - abstracts timestamp function across databases
@return - fixed value */
function sql_function_timestamp($db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
return 'NOW()';
//if (isset($db_conn->sysTimeStamp)) {
// return $db_conn->sysTimeStamp;
//}
//return "'".date('Y-m-d H:i:s')."'";
}
/* sql_function_substr - abstracts substring function across databases
@return - fixed value */
function sql_function_substr($db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
return 'substring';
// if (isset($db_conn->substr)) {
// return $db_conn->substr;
// }
// switch($db_conn->databaseType) {
// case 'oci805':
// case 'oci8':
// case 'oci8po':
// case 'oracle':
// return 'substr';
// break;
// case 'postgres64':
// case 'postgres7':
// case 'postgres':
// return 'substr';
// break;
// case 'db2':
// case 'fbsql':
// case 'firebird':
// case 'ibase':
// default:
// return 'substr';
// }
}
/* sql_function_concat - abstracts concatenation function across databases
@return - fixed value */
function sql_function_concat($db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
//if (method_exists($db_conn, 'Concat')) {
// $args = func_get_args();
// return call_user_func_array(array(&$db_conn, 'Concat'), $args);
//}
return "concat('".implode("','", func_get_args())."')";
}
/* sql_function_replace - abstracts replace function across databases
@return - fixed value */
function sql_function_replace($db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
return 'replace';
// switch($db_conn->databaseType) {
// case 'mssql':
// case 'mssqlpo':
// return 'replace';
// break;
// case 'mysql':
// case 'mysqli':
// case 'mysqlt':
// return 'replace';
// break;
// case 'oci805':
// case 'oci8':
// case 'oci8po':
// case 'oracle':
// return 'replace';
// break;
// case 'postgres64':
// case 'postgres7':
// case 'postgres':
// return 'replace';
// break;
// case 'db2':
// case 'firebird':
// case 'ibase':
// default:
// return 'replace';
// }
}
/* sql_function_dateformat - abstracts dateformat function across databases
@return - fixed value */
function sql_function_dateformat($fmt, $col = false, $db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
return 'date_format';
// if (method_exists($db_conn, 'SQLDate')) {
// return call_user_func_array(array(&$db_conn, 'SQLDate'), array($fmt,$col));
// }
//
// switch($db_conn->databaseType) {
// default:
// return 'date_format';
// }
}
function db_qstr($s, $db_conn = '') {
global $database_sessions, $database_default, $database_hostname, $database_port;
/* check for a connection being passed, if not use legacy behavior */
if (!$db_conn) {
$db_conn = $database_sessions["$database_hostname:$database_port:$database_default"];
}
$replaceQuote = "\\'";
if (is_null($s)) return 'NULL';
if (is_resource($db_conn))
return $db_conn->quote($s);
if ($replaceQuote == '\\') {
$s = str_replace(array('\\', "\0"), array('\\\\', "\\\0"), $s);
}
return "'" . str_replace("'",$replaceQuote, $s) . "'";
}