0) {
include 'general/mysqlerr.php';
return false;
}
db_change_cache_id($db, $host);
if (isset($charset)) {
mysqli_set_charset($connect_id, $charset);
}
mysqli_select_db($connect_id, $db);
} else {
$connect_id = mysqli_init();
mysqli_ssl_set($connect_id, null, null, $ssl, null, null);
if ($verify === 'verified') {
mysqli_real_connect($connect_id, $host, $user, $pass, $db, $port, null, MYSQLI_CLIENT_SSL);
} else {
mysqli_real_connect($connect_id, $host, $user, $pass, $db, $port, null, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
}
if (mysqli_connect_errno() > 0) {
include 'general/mysqlerr.php';
return false;
}
}
} else {
$connect_id = @mysql_connect($host.':'.$port, $user, $pass, true);
if (!$connect_id) {
return false;
}
db_change_cache_id($db, $host);
if (isset($charset)) {
@mysql_set_charset($connect_id, $charset);
}
mysql_select_db($db, $connect_id);
}
return $connect_id;
}
function mysql_db_get_all_rows_sql($sql, $search_history_db=false, $cache=true, $dbconnection=false)
{
global $config;
$history = [];
if ($dbconnection === false) {
$dbconnection = $config['dbconnection'];
}
// To disable globally SQL cache depending on global variable.
// Used in several critical places like Metaconsole trans-server queries
if (isset($config['dbcache'])) {
$cache = $config['dbcache'];
}
// Read from the history DB if necessary
if ($search_history_db && $config['history_db_enabled'] == 1) {
$cache = false;
$history = false;
// Connect to the history DB
if (!isset($config['history_db_connection']) || $config['history_db_connection'] === false) {
$config['history_db_connection'] = db_connect($config['history_db_host'], $config['history_db_name'], $config['history_db_user'], io_output_password($config['history_db_pass']), $config['history_db_port'], false);
}
if ($config['history_db_connection'] !== false) {
$history = mysql_db_process_sql($sql, 'affected_rows', $config['history_db_connection'], false);
}
if ($history === false) {
$history = [];
}
}
$return = mysql_db_process_sql(
$sql,
'affected_rows',
$dbconnection,
$cache
);
if ($return === false) {
$return = [];
}
// Append result to the history DB data
if (!empty($return)) {
foreach ($return as $row) {
array_push($history, $row);
}
}
if (!empty($history)) {
return $history;
}
// Return false, check with === or !==
return false;
}
/**
* Get the first value of the first row of a table in the database.
*
* @param string $field Field name to get.
* @param string $table Table to retrieve the data.
* @param string $field_search Field to filter elements.
* @param string $condition Condition the field must have.
* @param boolean $search_history_db Search in historical db.
* @param boolean $cache Enable cache or not.
*
* @return mixed Value of first column of the first row. False if there were no row.
*/
function mysql_db_get_value(
$field,
$table,
$field_search=1,
$condition=1,
$search_history_db=false,
$cache=true
) {
if (is_int($condition)) {
$sql = sprintf(
'SELECT %s FROM %s WHERE %s = %d LIMIT 1',
$field,
$table,
$field_search,
$condition
);
} else if (is_float($condition) || is_double($condition)) {
$sql = sprintf(
'SELECT %s FROM %s WHERE %s = %f LIMIT 1',
$field,
$table,
$field_search,
$condition
);
} else {
$sql = sprintf(
"SELECT %s FROM %s WHERE %s = '%s' LIMIT 1",
$field,
$table,
$field_search,
$condition
);
}
$result = db_get_all_rows_sql($sql, $search_history_db, $cache);
if ($result === false) {
return false;
}
$row = array_shift($result);
$value = array_shift($row);
if ($value === null) {
return false;
}
return $value;
}
/**
* Get the first row of a database query into a table.
*
* The SQL statement executed would be something like:
* "SELECT (*||$fields) FROM $table WHERE $field_search = $condition"
*
* @param string Table to get the row
* @param string Field to filter elements
* @param string Condition the field must have.
* @param mixed Fields to select (array or string or false/empty for *)
*
* @return mixed The first row of a database query or false.
*/
function mysql_db_get_row($table, $field_search, $condition, $fields=false, $cache=true)
{
if (empty($fields)) {
$fields = '*';
} else {
if (is_array($fields)) {
$fields = implode(',', $fields);
} else if (!is_string($fields)) {
return false;
}
}
if (is_int($condition)) {
$sql = sprintf(
'SELECT %s FROM `%s` WHERE `%s` = %d LIMIT 1',
$fields,
$table,
$field_search,
$condition
);
} else if (is_float($condition) || is_double($condition)) {
$sql = sprintf(
'SELECT %s FROM `%s` WHERE `%s` = %f LIMIT 1',
$fields,
$table,
$field_search,
$condition
);
} else {
$sql = sprintf(
"SELECT %s FROM `%s` WHERE `%s` = '%s' LIMIT 1",
$fields,
$table,
$field_search,
$condition
);
}
$result = db_get_all_rows_sql($sql, false, $cache);
if ($result === false) {
return false;
}
return $result[0];
}
/**
* Get all the rows in a table of the database.
*
* @param string Database table name.
* @param string Field to order by.
* @param string $order The type of order, by default 'ASC'.
*
* @return mixed A matrix with all the values in the table
*/
function mysql_db_get_all_rows_in_table($table, $order_field='', $order='ASC')
{
$sql = '
SELECT *
FROM `'.$table.'`';
if (!empty($order_field)) {
if (is_array($order_field)) {
foreach ($order_field as $i => $o) {
$order_field[$i] = $o.' '.$order;
}
$sql .= '
ORDER BY '.implode(',', $order_field);
} else {
$sql .= '
ORDER BY '.$order_field.' '.$order;
}
}
return db_get_all_rows_sql($sql);
}
/**
* Inserts strings into database
*
* The number of values should be the same or a positive integer multiple as the number of rows
* If you have an associate array (eg. array ("row1" => "value1")) you can use this function with ($table, array_keys ($array), $array) in it's options
* All arrays and values should have been cleaned before passing. It's not neccessary to add quotes.
*
* @param string Table to insert into
* @param mixed A single value or array of values to insert (can be a multiple amount of rows)
*
* @return mixed False in case of error or invalid values passed. Affected rows otherwise
*/
function mysql_db_process_sql_insert($table, $values)
{
// Empty rows or values not processed
if (empty($values)) {
return false;
}
$values = (array) $values;
$query = sprintf('INSERT INTO `%s` ', $table);
$fields = [];
$values_str = '';
$i = 1;
$max = count($values);
foreach ($values as $field => $value) {
// Add the correct escaping to values
if ($field[0] != '`') {
$field = '`'.$field.'`';
}
array_push($fields, $field);
if (is_null($value)) {
$values_str .= 'NULL';
} else if (is_int($value) || is_bool($value)) {
$values_str .= sprintf('%d', $value);
} else if (is_float($value) || is_double($value)) {
$values_str .= sprintf('%f', $value);
} else {
$values_str .= sprintf("'%s'", $value);
}
if ($i < $max) {
$values_str .= ',';
}
$i++;
}
$query .= '('.implode(', ', $fields).')';
$query .= ' VALUES ('.$values_str.')';
return db_process_sql($query, 'insert_id');
}
/**
* This function comes back with an array in case of SELECT
* in case of UPDATE, DELETE etc. with affected rows
* an empty array in case of SELECT without results
* Queries that return data will be cached so queries don't get repeated
*
* @param string SQL statement to execute
*
* @param string What type of info to return in case of INSERT/UPDATE.
* 'affected_rows' will return mysql_affected_rows (default value)
* 'insert_id' will return the ID of an autoincrement value
* 'info' will return the full (debug) information of a query
*
* @return mixed An array with the rows, columns and values in a multidimensional array or false in error
*/
function mysql_db_process_sql($sql, $rettype='affected_rows', $dbconnection='', $cache=true)
{
global $config;
global $sql_cache;
$retval = [];
if ($sql == '') {
return false;
}
if (isset($config['dbcache']) === true) {
$cache = $config['dbcache'];
}
if ($cache && !empty($sql_cache[$sql_cache['id']][$sql])) {
$retval = $sql_cache[$sql_cache['id']][$sql];
$sql_cache['saved'][$sql_cache['id']]++;
db_add_database_debug_trace($sql);
} else {
$start = microtime(true);
if ($dbconnection == '') {
$dbconnection = $config['dbconnection'];
}
if ($config['mysqli'] === true) {
$result = mysqli_query($dbconnection, $sql);
} else {
$result = mysql_query($sql, $dbconnection);
}
$time = (microtime(true) - $start);
if ($result === false) {
$backtrace = debug_backtrace();
if ($config['mysqli'] === true) {
$error = sprintf(
'%s (\'%s\') in %s on line %d',
mysqli_error($dbconnection),
$sql,
$backtrace[0]['file'],
$backtrace[0]['line']
);
db_add_database_debug_trace($sql, mysqli_error($dbconnection));
} else {
$error = sprintf(
'%s (\'%s\') in %s on line %d',
mysql_error(),
$sql,
$backtrace[0]['file'],
$backtrace[0]['line']
);
db_add_database_debug_trace($sql, mysql_error($dbconnection));
}
set_error_handler('db_sql_error_handler');
trigger_error($error);
restore_error_handler();
return false;
} else if ($result === true) {
if ($config['mysqli'] === true) {
if ($rettype == 'insert_id') {
$result = mysqli_insert_id($dbconnection);
} else if ($rettype == 'info') {
$result = mysqli_info($dbconnection);
} else {
$result = mysqli_affected_rows($dbconnection);
}
db_add_database_debug_trace(
$sql,
$result,
mysqli_affected_rows($dbconnection),
['time' => $time]
);
} else {
if ($rettype == 'insert_id') {
$result = mysql_insert_id($dbconnection);
} else if ($rettype == 'info') {
$result = mysql_info($dbconnection);
} else {
$result = mysql_affected_rows($dbconnection);
}
db_add_database_debug_trace(
$sql,
$result,
mysql_affected_rows($dbconnection),
['time' => $time]
);
}
return $result;
} else {
if ($config['mysqli'] === true) {
db_add_database_debug_trace(
$sql,
0,
mysqli_affected_rows($dbconnection),
['time' => $time]
);
while ($row = mysqli_fetch_assoc($result)) {
array_push($retval, $row);
}
if ($cache === true) {
$sql_cache[$sql_cache['id']][$sql] = $retval;
}
mysqli_free_result($result);
} else {
db_add_database_debug_trace(
$sql,
0,
mysql_affected_rows($dbconnection),
['time' => $time]
);
while ($row = mysql_fetch_assoc($result)) {
array_push($retval, $row);
}
if ($cache === true) {
$sql_cache[$sql_cache['id']][$sql] = $retval;
}
mysql_free_result($result);
}
}
}
if (!empty($retval)) {
return $retval;
}
// Return false, check with === or !==
return false;
}
/**
* Escape string to set it properly to use in sql queries
*
* @param string String to be cleaned.
*
* @return string String cleaned.
*/
function mysql_escape_string_sql($string)
{
global $config;
$dbconnection = $config['dbconnection'];
if ($dbconnection == null) {
$dbconnection = mysql_connect_db();
}
if ($config['mysqli'] === true) {
$str = mysqli_real_escape_string($dbconnection, $string);
} else {
$str = mysql_real_escape_string($string);
}
return $str;
}
function mysql_encapsule_fields_with_same_name_to_instructions($field)
{
$return = $field;
if (is_string($return)) {
if ($return[0] !== '`') {
$return = '`'.$return.'`';
}
}
return $return;
}
/**
* Get the first value of the first row of a table in the database from an
* array with filter conditions.
*
* Example:
db_get_value_filter ('name', 'talert_templates',
array ('value' => 2, 'type' => 'equal'));
// Equivalent to:
// SELECT name FROM talert_templates WHERE value = 2 AND type = 'equal' LIMIT 1
db_get_value_filter ('description', 'talert_templates',
array ('name' => 'My alert', 'type' => 'regex'), 'OR');
// Equivalent to:
// SELECT description FROM talert_templates WHERE name = 'My alert' OR type = 'equal' LIMIT 1
*
* @param string Field name to get
* @param string Table to retrieve the data
* @param array Conditions to filter the element. See db_format_array_where_clause_sql()
* for the format
* @param string Join operator for the elements in the filter.
*
* @return mixed Value of first column of the first row. False if there were no row.
*/
function mysql_db_get_value_filter($field, $table, $filter, $where_join='AND', $search_history_db=false)
{
if (!is_array($filter) || empty($filter)) {
return false;
}
// Avoid limit and offset if given
unset($filter['limit']);
unset($filter['offset']);
$sql = sprintf(
'SELECT %s FROM %s WHERE %s LIMIT 1',
$field,
$table,
db_format_array_where_clause_sql($filter, $where_join)
);
$result = db_get_all_rows_sql($sql, $search_history_db);
if ($result === false) {
return false;
}
$row = array_shift($result);
$value = array_shift($row);
if ($value === null) {
return false;
}
return $value;
}
/**
* Formats an array of values into a SQL where clause string.
*
* This function is useful to generate a WHERE clause for a SQL sentence from
* a list of values. Example code:
$values = array ();
$values['name'] = "Name";
$values['description'] = "Long description";
$values['limit'] = $config['block_size']; // Assume it's 20
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values);
echo $sql;
* Will return:
*
* SELECT * FROM table WHERE `name` = "Name" AND `description` = "Long description" LIMIT 20
*
*
* @param array Values to be formatted in an array indexed by the field name.
* There are special parameters such as 'limit' and 'offset' that will be used
* as ORDER, LIMIT and OFFSET clauses respectively. Since LIMIT and OFFSET are
* numerics, ORDER can receive a field name or a SQL function and a the ASC or
* DESC clause. Examples:
$values = array ();
$values['value'] = 10;
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values);
// SELECT * FROM table WHERE VALUE = 10
$values = array ();
$values['value'] = 10;
$values['order'] = 'name DESC';
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values);
// SELECT * FROM table WHERE VALUE = 10 ORDER BY name DESC
* @param string Join operator. AND by default.
* @param string A prefix to be added to the string. It's useful when limit and
* offset could be given to avoid this cases:
$values = array ();
$values['limit'] = 10;
$values['offset'] = 20;
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values);
// Wrong SQL: SELECT * FROM table WHERE LIMIT 10 OFFSET 20
$values = array ();
$values['limit'] = 10;
$values['offset'] = 20;
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values, 'AND', 'WHERE');
// Good SQL: SELECT * FROM table LIMIT 10 OFFSET 20
$values = array ();
$values['value'] = 5;
$values['limit'] = 10;
$values['offset'] = 20;
$sql = 'SELECT * FROM table WHERE '.db_format_array_where_clause_sql ($values, 'AND', 'WHERE');
// Good SQL: SELECT * FROM table WHERE value = 5 LIMIT 10 OFFSET 20
*
* @return string Values joined into an SQL string that can fits into the WHERE
* clause of an SQL sentence.
*/
function mysql_db_format_array_where_clause_sql($values, $join='AND', $prefix=false)
{
$fields = [];
if (!is_array($values)) {
return '';
}
$query = '';
$limit = '';
$offset = '';
$order = '';
$group = '';
if (isset($values['limit'])) {
$limit = sprintf(' LIMIT %d', $values['limit']);
unset($values['limit']);
}
if (isset($values['offset'])) {
$offset = sprintf(' OFFSET %d', $values['offset']);
unset($values['offset']);
}
if (isset($values['order'])) {
if (is_array($values['order'])) {
if (!isset($values['order']['order'])) {
$orderTexts = [];
foreach ($values['order'] as $orderItem) {
$orderTexts[] = $orderItem['field'].' '.$orderItem['order'];
}
$order = ' ORDER BY '.implode(', ', $orderTexts);
} else {
$order = sprintf(' ORDER BY %s %s', $values['order']['field'], $values['order']['order']);
}
} else {
$order = sprintf(' ORDER BY %s', $values['order']);
}
unset($values['order']);
}
if (isset($values['group'])) {
$group = sprintf(' GROUP BY %s', $values['group']);
unset($values['group']);
}
$i = 1;
$max = count($values);
foreach ($values as $field => $value) {
$negative = false;
if (is_numeric($field)) {
// User provide the exact operation to do
$query .= $value;
if ($i < $max) {
$query .= ' '.$join.' ';
}
$i++;
continue;
}
if ($field[0] == '!') {
$negative = true;
$field = substr($field, 1);
}
if ($field[0] != '`') {
// If the field is as