diff --git a/includes/common.php b/includes/common.php
index d5ba05fb02..c4788d064a 100644
--- a/includes/common.php
+++ b/includes/common.php
@@ -319,7 +319,13 @@ function truncate($substring, $max = 50, $rep = '...') {
function mres($string) {
// short function wrapper because the real one is stupidly long and ugly. aesthetics.
- return mysql_real_escape_string($string);
+ global $config, $database_link;
+ if ($config['db']['extension'] == 'mysqli') {
+ return mysqli_real_escape_string($database_link,$string);
+ }
+ else {
+ return mysql_real_escape_string($string);
+ }
}
function getifhost($id) {
diff --git a/includes/dbFacile.mysql.php b/includes/dbFacile.mysql.php
new file mode 100644
index 0000000000..0d1d7150ce
--- /dev/null
+++ b/includes/dbFacile.mysql.php
@@ -0,0 +1,554 @@
+convert("\nSQL[%y".$fullSql.'%n] ');
+ }
+ else {
+ $sql_debug[] = $fullSql;
+ }
+ }
+
+ /*
+ if($this->logFile)
+ $time_start = microtime(true);
+ */
+
+ $result = mysql_query($fullSql);
+ // sets $this->result
+ /*
+ if($this->logFile) {
+ $time_end = microtime(true);
+ fwrite($this->logFile, date('Y-m-d H:i:s') . "\n" . $fullSql . "\n" . number_format($time_end - $time_start, 8) . " seconds\n\n");
+ }
+ */
+
+ if ($result === false && (error_reporting() & 1)) {
+ // aye. this gets triggers on duplicate Contact insert
+ // trigger_error('QDB - Error in query: ' . $fullSql . ' : ' . mysql_error(), E_USER_WARNING);
+ }
+
+ return $result;
+
+}//end dbQuery()
+
+
+/*
+ * Passed an array and a table name, it attempts to insert the data into the table.
+ * Check for boolean false to determine whether insert failed
+ * */
+
+
+function dbInsert($data, $table) {
+ global $fullSql;
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // insert into the TABLE this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ // trigger_error('QDB - Parameters passed to insert() were in reverse order, but it has been allowed', E_USER_NOTICE);
+ }
+
+ $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data)).'`) VALUES ('.implode(',', dbPlaceHolders($data)).')';
+
+ $time_start = microtime(true);
+ dbBeginTransaction();
+ $result = dbQuery($sql, $data);
+ if ($result) {
+ $id = mysql_insert_id();
+ dbCommitTransaction();
+ // return $id;
+ }
+ else {
+ if ($table != 'Contact') {
+ trigger_error('QDB - Insert failed.', E_USER_WARNING);
+ }
+
+ dbRollbackTransaction();
+ // $id = false;
+ }
+
+ // logfile($fullSql);
+ $time_end = microtime(true);
+ $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['insert']++;
+
+ return $id;
+
+}//end dbInsert()
+
+
+/*
+ * Passed an array and a table name, it attempts to insert the data into the table.
+ * $data is an array (rows) of key value pairs. keys are fields. Rows need to have same fields.
+ * Check for boolean false to determine whether insert failed
+ * */
+
+
+function dbBulkInsert($data, $table) {
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // insert into the TABLE this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ }
+ if (count($data) === 0) {
+ return false;
+ }
+ if (count($data[0]) === 0) {
+ return false;
+ }
+
+ $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data[0])).'`) VALUES ';
+ $values ='';
+
+ foreach ($data as $row) {
+ if ($values != '') {
+ $values .= ',';
+ }
+ $rowvalues='';
+ foreach ($row as $key => $value) {
+ if ($rowvalues != '') {
+ $rowvalues .= ',';
+ }
+ $rowvalues .= "'".mres($value)."'";
+ }
+ $values .= "(".$rowvalues.")";
+ }
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql.$values);
+
+ // logfile($fullSql);
+ $time_end = microtime(true);
+ $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['insert']++;
+
+ return $result;
+
+}//end dbBulkInsert()
+
+
+/*
+ * Passed an array, table name, WHERE clause, and placeholder parameters, it attempts to update a record.
+ * Returns the number of affected rows
+ * */
+
+
+function dbUpdate($data, $table, $where=null, $parameters=array()) {
+ global $fullSql;
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // update the TABLE with this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ // trigger_error('QDB - The first two parameters passed to update() were in reverse order, but it has been allowed', E_USER_NOTICE);
+ }
+
+ // need field name and placeholder value
+ // but how merge these field placeholders with actual $parameters array for the WHERE clause
+ $sql = 'UPDATE `'.$table.'` set ';
+ foreach ($data as $key => $value) {
+ $sql .= '`'.$key.'` '.'=:'.$key.',';
+ }
+
+ $sql = substr($sql, 0, -1);
+ // strip off last comma
+ if ($where) {
+ $sql .= ' WHERE '.$where;
+ $data = array_merge($data, $parameters);
+ }
+
+ $time_start = microtime(true);
+ if (dbQuery($sql, $data)) {
+ $return = mysql_affected_rows();
+ }
+ else {
+ // echo("$fullSql");
+ trigger_error('QDB - Update failed.', E_USER_WARNING);
+ $return = false;
+ }
+
+ $time_end = microtime(true);
+ $db_stats['update_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['update']++;
+
+ return $return;
+
+}//end dbUpdate()
+
+
+function dbDelete($table, $where=null, $parameters=array()) {
+ $sql = 'DELETE FROM `'.$table.'`';
+ if ($where) {
+ $sql .= ' WHERE '.$where;
+ }
+
+ if (dbQuery($sql, $parameters)) {
+ return mysql_affected_rows();
+ }
+ else {
+ return false;
+ }
+
+}//end dbDelete()
+
+
+/*
+ * Fetches all of the rows (associatively) from the last performed query.
+ * Most other retrieval functions build off this
+ * */
+
+
+function dbFetchRows($sql, $parameters=array()) {
+ global $db_stats;
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql, $parameters);
+
+ if (mysql_num_rows($result) > 0) {
+ $rows = array();
+ while ($row = mysql_fetch_assoc($result)) {
+ $rows[] = $row;
+ }
+
+ mysql_free_result($result);
+ return $rows;
+ }
+
+ mysql_free_result($result);
+
+ $time_end = microtime(true);
+ $db_stats['fetchrows_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchrows']++;
+
+ // no records, thus return empty array
+ // which should evaluate to false, and will prevent foreach notices/warnings
+ return array();
+
+}//end dbFetchRows()
+
+
+/*
+ * This is intended to be the method used for large result sets.
+ * It is intended to return an iterator, and act upon buffered data.
+ * */
+
+
+function dbFetch($sql, $parameters=array()) {
+ return dbFetchRows($sql, $parameters);
+ /*
+ // for now, don't do the iterator thing
+ $result = dbQuery($sql, $parameters);
+ if($result) {
+ // return new iterator
+ return new dbIterator($result);
+ } else {
+ return null; // ??
+ }
+ */
+
+}//end dbFetch()
+
+
+/*
+ * Like fetch(), accepts any number of arguments
+ * The first argument is an sprintf-ready query stringTypes
+ * */
+
+
+function dbFetchRow($sql=null, $parameters=array()) {
+ global $db_stats;
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql, $parameters);
+ if ($result) {
+ $row = mysql_fetch_assoc($result);
+ mysql_free_result($result);
+ $time_end = microtime(true);
+
+ $db_stats['fetchrow_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchrow']++;
+
+ return $row;
+ }
+ else {
+ return null;
+ }
+
+ $time_start = microtime(true);
+
+}//end dbFetchRow()
+
+
+/*
+ * Fetches the first call from the first row returned by the query
+ * */
+
+
+function dbFetchCell($sql, $parameters=array()) {
+ global $db_stats;
+ $time_start = microtime(true);
+ $row = dbFetchRow($sql, $parameters);
+ if ($row) {
+ return array_shift($row);
+ // shift first field off first row
+ }
+
+ $time_end = microtime(true);
+
+ $db_stats['fetchcell_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchcell']++;
+
+ return null;
+
+}//end dbFetchCell()
+
+
+/*
+ * This method is quite different from fetchCell(), actually
+ * It fetches one cell from each row and places all the values in 1 array
+ * */
+
+
+function dbFetchColumn($sql, $parameters=array()) {
+ global $db_stats;
+ $time_start = microtime(true);
+ $cells = array();
+ foreach (dbFetch($sql, $parameters) as $row) {
+ $cells[] = array_shift($row);
+ }
+
+ $time_end = microtime(true);
+
+ $db_stats['fetchcol_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchcol']++;
+
+ return $cells;
+
+}//end dbFetchColumn()
+
+
+/*
+ * Should be passed a query that fetches two fields
+ * The first will become the array key
+ * The second the key's value
+ */
+
+
+function dbFetchKeyValue($sql, $parameters=array()) {
+ $data = array();
+ foreach (dbFetch($sql, $parameters) as $row) {
+ $key = array_shift($row);
+ if (sizeof($row) == 1) {
+ // if there were only 2 fields in the result
+ // use the second for the value
+ $data[$key] = array_shift($row);
+ }
+ else {
+ // if more than 2 fields were fetched
+ // use the array of the rest as the value
+ $data[$key] = $row;
+ }
+ }
+
+ return $data;
+
+}//end dbFetchKeyValue()
+
+
+/*
+ * This combines a query and parameter array into a final query string for execution
+ * PDO drivers don't need to use this
+ */
+
+
+function dbMakeQuery($sql, $parameters) {
+ // bypass extra logic if we have no parameters
+ if (sizeof($parameters) == 0) {
+ return $sql;
+ }
+
+ $parameters = dbPrepareData($parameters);
+ // separate the two types of parameters for easier handling
+ $questionParams = array();
+ $namedParams = array();
+ foreach ($parameters as $key => $value) {
+ if (is_numeric($key)) {
+ $questionParams[] = $value;
+ }
+ else {
+ $namedParams[':'.$key] = $value;
+ }
+ }
+
+ // sort namedParams in reverse to stop substring squashing
+ krsort($namedParams);
+
+ // split on question-mark and named placeholders
+ $result = preg_split('/(\?|:[a-zA-Z0-9_-]+)/', $sql, -1, (PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));
+
+ // every-other item in $result will be the placeholder that was found
+ $query = '';
+ $res_size = sizeof($result);
+ for ($i = 0; $i < $res_size; $i += 2) {
+ $query .= $result[$i];
+
+ $j = ($i + 1);
+ if (array_key_exists($j, $result)) {
+ $test = $result[$j];
+ if ($test == '?') {
+ $query .= array_shift($questionParams);
+ }
+ else {
+ $query .= $namedParams[$test];
+ }
+ }
+ }
+
+ return $query;
+
+}//end dbMakeQuery()
+
+
+function dbPrepareData($data) {
+ $values = array();
+
+ foreach ($data as $key => $value) {
+ $escape = true;
+ // don't quote or esc if value is an array, we treat it
+ // as a "decorator" that tells us not to escape the
+ // value contained in the array
+ if (is_array($value) && !is_object($value)) {
+ $escape = false;
+ $value = array_shift($value);
+ }
+
+ // it's not right to worry about invalid fields in this method because we may be operating on fields
+ // that are aliases, or part of other tables through joins
+ // if(!in_array($key, $columns)) // skip invalid fields
+ // continue;
+ if ($escape) {
+ $values[$key] = "'".mysql_real_escape_string($value)."'";
+ }
+ else {
+ $values[$key] = $value;
+ }
+ }
+
+ return $values;
+
+}//end dbPrepareData()
+
+
+/*
+ * Given a data array, this returns an array of placeholders
+ * These may be question marks, or ":email" type
+ */
+
+
+function dbPlaceHolders($values) {
+ $data = array();
+ foreach ($values as $key => $value) {
+ if (is_numeric($key)) {
+ $data[] = '?';
+ }
+ else {
+ $data[] = ':'.$key;
+ }
+ }
+
+ return $data;
+
+}//end dbPlaceHolders()
+
+
+function dbBeginTransaction() {
+ mysql_query('begin');
+
+}//end dbBeginTransaction()
+
+
+function dbCommitTransaction() {
+ mysql_query('commit');
+
+}//end dbCommitTransaction()
+
+
+function dbRollbackTransaction() {
+ mysql_query('rollback');
+
+}//end dbRollbackTransaction()
+
+
+/*
+ class dbIterator implements Iterator {
+ private $result;
+ private $i;
+
+ public function __construct($r) {
+ $this->result = $r;
+ $this->i = 0;
+ }
+ public function rewind() {
+ mysql_data_seek($this->result, 0);
+ $this->i = 0;
+ }
+ public function current() {
+ $a = mysql_fetch_assoc($this->result);
+ return $a;
+ }
+ public function key() {
+ return $this->i;
+ }
+ public function next() {
+ $this->i++;
+ $a = mysql_data_seek($this->result, $this->i);
+ if($a === false) {
+ $this->i = 0;
+ }
+ return $a;
+ }
+ public function valid() {
+ return ($this->current() !== false);
+ }
+ }
+ */
diff --git a/includes/dbFacile.mysqli.php b/includes/dbFacile.mysqli.php
new file mode 100644
index 0000000000..2408ca990f
--- /dev/null
+++ b/includes/dbFacile.mysqli.php
@@ -0,0 +1,559 @@
+convert("\nSQL[%y".$fullSql.'%n] ');
+ }
+ else {
+ $sql_debug[] = $fullSql;
+ }
+ }
+
+ /*
+ if($this->logFile)
+ $time_start = microtime(true);
+ */
+
+ $result = mysqli_query($database_link, $fullSql);
+ // sets $this->result
+ /*
+ if($this->logFile) {
+ $time_end = microtime(true);
+ fwrite($this->logFile, date('Y-m-d H:i:s') . "\n" . $fullSql . "\n" . number_format($time_end - $time_start, 8) . " seconds\n\n");
+ }
+ */
+
+ if ($result === false && (error_reporting() & 1)) {
+ // aye. this gets triggers on duplicate Contact insert
+ // trigger_error('QDB - Error in query: ' . $fullSql . ' : ' . mysql_error(), E_USER_WARNING);
+ }
+
+ return $result;
+
+}//end dbQuery()
+
+
+/*
+ * Passed an array and a table name, it attempts to insert the data into the table.
+ * Check for boolean false to determine whether insert failed
+ * */
+
+
+function dbInsert($data, $table) {
+ global $fullSql, $database_link;
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // insert into the TABLE this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ // trigger_error('QDB - Parameters passed to insert() were in reverse order, but it has been allowed', E_USER_NOTICE);
+ }
+
+ $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data)).'`) VALUES ('.implode(',', dbPlaceHolders($data)).')';
+
+ $time_start = microtime(true);
+ dbBeginTransaction();
+ $result = dbQuery($sql, $data);
+ if ($result) {
+ $id = mysqli_insert_id($database_link);
+ dbCommitTransaction();
+ // return $id;
+ }
+ else {
+ if ($table != 'Contact') {
+ trigger_error('QDB - Insert failed.', E_USER_WARNING);
+ }
+
+ dbRollbackTransaction();
+ // $id = false;
+ }
+
+ // logfile($fullSql);
+ $time_end = microtime(true);
+ $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['insert']++;
+
+ return $id;
+
+}//end dbInsert()
+
+
+/*
+ * Passed an array and a table name, it attempts to insert the data into the table.
+ * $data is an array (rows) of key value pairs. keys are fields. Rows need to have same fields.
+ * Check for boolean false to determine whether insert failed
+ * */
+
+
+function dbBulkInsert($data, $table) {
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // insert into the TABLE this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ }
+ if (count($data) === 0) {
+ return false;
+ }
+ if (count($data[0]) === 0) {
+ return false;
+ }
+
+ $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data[0])).'`) VALUES ';
+ $values ='';
+
+ foreach ($data as $row) {
+ if ($values != '') {
+ $values .= ',';
+ }
+ $rowvalues='';
+ foreach ($row as $key => $value) {
+ if ($rowvalues != '') {
+ $rowvalues .= ',';
+ }
+ $rowvalues .= "'".mres($value)."'";
+ }
+ $values .= "(".$rowvalues.")";
+ }
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql.$values);
+
+ // logfile($fullSql);
+ $time_end = microtime(true);
+ $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['insert']++;
+
+ return $result;
+
+}//end dbBulkInsert()
+
+
+/*
+ * Passed an array, table name, WHERE clause, and placeholder parameters, it attempts to update a record.
+ * Returns the number of affected rows
+ * */
+
+
+function dbUpdate($data, $table, $where=null, $parameters=array()) {
+ global $fullSql, $database_link;
+ global $db_stats;
+ // the following block swaps the parameters if they were given in the wrong order.
+ // it allows the method to work for those that would rather it (or expect it to)
+ // follow closer with SQL convention:
+ // update the TABLE with this DATA
+ if (is_string($data) && is_array($table)) {
+ $tmp = $data;
+ $data = $table;
+ $table = $tmp;
+ // trigger_error('QDB - The first two parameters passed to update() were in reverse order, but it has been allowed', E_USER_NOTICE);
+ }
+
+ // need field name and placeholder value
+ // but how merge these field placeholders with actual $parameters array for the WHERE clause
+ $sql = 'UPDATE `'.$table.'` set ';
+ foreach ($data as $key => $value) {
+ $sql .= '`'.$key.'` '.'=:'.$key.',';
+ }
+
+ $sql = substr($sql, 0, -1);
+ // strip off last comma
+ if ($where) {
+ $sql .= ' WHERE '.$where;
+ $data = array_merge($data, $parameters);
+ }
+
+ $time_start = microtime(true);
+ if (dbQuery($sql, $data)) {
+ $return = mysqli_affected_rows($database_link);
+ }
+ else {
+ // echo("$fullSql");
+ trigger_error('QDB - Update failed.', E_USER_WARNING);
+ $return = false;
+ }
+
+ $time_end = microtime(true);
+ $db_stats['update_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['update']++;
+
+ return $return;
+
+}//end dbUpdate()
+
+
+function dbDelete($table, $where=null, $parameters=array()) {
+ global $database_link;
+ $sql = 'DELETE FROM `'.$table.'`';
+ if ($where) {
+ $sql .= ' WHERE '.$where;
+ }
+
+ if (dbQuery($sql, $parameters)) {
+ return mysqli_affected_rows($database_link);
+ }
+ else {
+ return false;
+ }
+
+}//end dbDelete()
+
+
+/*
+ * Fetches all of the rows (associatively) from the last performed query.
+ * Most other retrieval functions build off this
+ * */
+
+
+function dbFetchRows($sql, $parameters=array()) {
+ global $db_stats;
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql, $parameters);
+
+ if (mysqli_num_rows($result) > 0) {
+ $rows = array();
+ while ($row = mysqli_fetch_assoc($result)) {
+ $rows[] = $row;
+ }
+
+ mysqli_free_result($result);
+ return $rows;
+ }
+
+ mysqli_free_result($result);
+
+ $time_end = microtime(true);
+ $db_stats['fetchrows_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchrows']++;
+
+ // no records, thus return empty array
+ // which should evaluate to false, and will prevent foreach notices/warnings
+ return array();
+
+}//end dbFetchRows()
+
+
+/*
+ * This is intended to be the method used for large result sets.
+ * It is intended to return an iterator, and act upon buffered data.
+ * */
+
+
+function dbFetch($sql, $parameters=array()) {
+ return dbFetchRows($sql, $parameters);
+ /*
+ // for now, don't do the iterator thing
+ $result = dbQuery($sql, $parameters);
+ if($result) {
+ // return new iterator
+ return new dbIterator($result);
+ } else {
+ return null; // ??
+ }
+ */
+
+}//end dbFetch()
+
+
+/*
+ * Like fetch(), accepts any number of arguments
+ * The first argument is an sprintf-ready query stringTypes
+ * */
+
+
+function dbFetchRow($sql=null, $parameters=array()) {
+ global $db_stats;
+
+ $time_start = microtime(true);
+ $result = dbQuery($sql, $parameters);
+ if ($result) {
+ $row = mysqli_fetch_assoc($result);
+ mysqli_free_result($result);
+ $time_end = microtime(true);
+
+ $db_stats['fetchrow_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchrow']++;
+
+ return $row;
+ }
+ else {
+ return null;
+ }
+
+ $time_start = microtime(true);
+
+}//end dbFetchRow()
+
+
+/*
+ * Fetches the first call from the first row returned by the query
+ * */
+
+
+function dbFetchCell($sql, $parameters=array()) {
+ global $db_stats;
+ $time_start = microtime(true);
+ $row = dbFetchRow($sql, $parameters);
+ if ($row) {
+ return array_shift($row);
+ // shift first field off first row
+ }
+
+ $time_end = microtime(true);
+
+ $db_stats['fetchcell_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchcell']++;
+
+ return null;
+
+}//end dbFetchCell()
+
+
+/*
+ * This method is quite different from fetchCell(), actually
+ * It fetches one cell from each row and places all the values in 1 array
+ * */
+
+
+function dbFetchColumn($sql, $parameters=array()) {
+ global $db_stats;
+ $time_start = microtime(true);
+ $cells = array();
+ foreach (dbFetch($sql, $parameters) as $row) {
+ $cells[] = array_shift($row);
+ }
+
+ $time_end = microtime(true);
+
+ $db_stats['fetchcol_sec'] += number_format(($time_end - $time_start), 8);
+ $db_stats['fetchcol']++;
+
+ return $cells;
+
+}//end dbFetchColumn()
+
+
+/*
+ * Should be passed a query that fetches two fields
+ * The first will become the array key
+ * The second the key's value
+ */
+
+
+function dbFetchKeyValue($sql, $parameters=array()) {
+ $data = array();
+ foreach (dbFetch($sql, $parameters) as $row) {
+ $key = array_shift($row);
+ if (sizeof($row) == 1) {
+ // if there were only 2 fields in the result
+ // use the second for the value
+ $data[$key] = array_shift($row);
+ }
+ else {
+ // if more than 2 fields were fetched
+ // use the array of the rest as the value
+ $data[$key] = $row;
+ }
+ }
+
+ return $data;
+
+}//end dbFetchKeyValue()
+
+
+/*
+ * This combines a query and parameter array into a final query string for execution
+ * PDO drivers don't need to use this
+ */
+
+
+function dbMakeQuery($sql, $parameters) {
+ // bypass extra logic if we have no parameters
+ if (sizeof($parameters) == 0) {
+ return $sql;
+ }
+
+ $parameters = dbPrepareData($parameters);
+ // separate the two types of parameters for easier handling
+ $questionParams = array();
+ $namedParams = array();
+ foreach ($parameters as $key => $value) {
+ if (is_numeric($key)) {
+ $questionParams[] = $value;
+ }
+ else {
+ $namedParams[':'.$key] = $value;
+ }
+ }
+
+ // sort namedParams in reverse to stop substring squashing
+ krsort($namedParams);
+
+ // split on question-mark and named placeholders
+ $result = preg_split('/(\?|:[a-zA-Z0-9_-]+)/', $sql, -1, (PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));
+
+ // every-other item in $result will be the placeholder that was found
+ $query = '';
+ $res_size = sizeof($result);
+ for ($i = 0; $i < $res_size; $i += 2) {
+ $query .= $result[$i];
+
+ $j = ($i + 1);
+ if (array_key_exists($j, $result)) {
+ $test = $result[$j];
+ if ($test == '?') {
+ $query .= array_shift($questionParams);
+ }
+ else {
+ $query .= $namedParams[$test];
+ }
+ }
+ }
+
+ return $query;
+
+}//end dbMakeQuery()
+
+
+function dbPrepareData($data) {
+ global $database_link;
+ $values = array();
+
+ foreach ($data as $key => $value) {
+ $escape = true;
+ // don't quote or esc if value is an array, we treat it
+ // as a "decorator" that tells us not to escape the
+ // value contained in the array
+ if (is_array($value) && !is_object($value)) {
+ $escape = false;
+ $value = array_shift($value);
+ }
+
+ // it's not right to worry about invalid fields in this method because we may be operating on fields
+ // that are aliases, or part of other tables through joins
+ // if(!in_array($key, $columns)) // skip invalid fields
+ // continue;
+ if ($escape) {
+ $values[$key] = "'".mysqli_real_escape_string($database_link,$value)."'";
+ }
+ else {
+ $values[$key] = $value;
+ }
+ }
+
+ return $values;
+
+}//end dbPrepareData()
+
+
+/*
+ * Given a data array, this returns an array of placeholders
+ * These may be question marks, or ":email" type
+ */
+
+
+function dbPlaceHolders($values) {
+ $data = array();
+ foreach ($values as $key => $value) {
+ if (is_numeric($key)) {
+ $data[] = '?';
+ }
+ else {
+ $data[] = ':'.$key;
+ }
+ }
+
+ return $data;
+
+}//end dbPlaceHolders()
+
+
+function dbBeginTransaction() {
+ global $database_link;
+ mysqli_query($database_link, 'begin');
+
+}//end dbBeginTransaction()
+
+
+function dbCommitTransaction() {
+ global $database_link;
+ mysqli_query($database_link, 'commit');
+
+}//end dbCommitTransaction()
+
+
+function dbRollbackTransaction() {
+ global $database_link;
+ mysqli_query($database_link, 'rollback');
+
+}//end dbRollbackTransaction()
+
+
+/*
+ class dbIterator implements Iterator {
+ private $result;
+ private $i;
+
+ public function __construct($r) {
+ $this->result = $r;
+ $this->i = 0;
+ }
+ public function rewind() {
+ mysql_data_seek($this->result, 0);
+ $this->i = 0;
+ }
+ public function current() {
+ $a = mysql_fetch_assoc($this->result);
+ return $a;
+ }
+ public function key() {
+ return $this->i;
+ }
+ public function next() {
+ $this->i++;
+ $a = mysql_data_seek($this->result, $this->i);
+ if($a === false) {
+ $this->i = 0;
+ }
+ return $a;
+ }
+ public function valid() {
+ return ($this->current() !== false);
+ }
+ }
+ */
diff --git a/includes/dbFacile.php b/includes/dbFacile.php
index 0d1d7150ce..7e7989bcab 100644
--- a/includes/dbFacile.php
+++ b/includes/dbFacile.php
@@ -1,554 +1,9 @@
convert("\nSQL[%y".$fullSql.'%n] ');
- }
- else {
- $sql_debug[] = $fullSql;
- }
- }
-
- /*
- if($this->logFile)
- $time_start = microtime(true);
- */
-
- $result = mysql_query($fullSql);
- // sets $this->result
- /*
- if($this->logFile) {
- $time_end = microtime(true);
- fwrite($this->logFile, date('Y-m-d H:i:s') . "\n" . $fullSql . "\n" . number_format($time_end - $time_start, 8) . " seconds\n\n");
- }
- */
-
- if ($result === false && (error_reporting() & 1)) {
- // aye. this gets triggers on duplicate Contact insert
- // trigger_error('QDB - Error in query: ' . $fullSql . ' : ' . mysql_error(), E_USER_WARNING);
- }
-
- return $result;
-
-}//end dbQuery()
-
-
-/*
- * Passed an array and a table name, it attempts to insert the data into the table.
- * Check for boolean false to determine whether insert failed
- * */
-
-
-function dbInsert($data, $table) {
- global $fullSql;
- global $db_stats;
- // the following block swaps the parameters if they were given in the wrong order.
- // it allows the method to work for those that would rather it (or expect it to)
- // follow closer with SQL convention:
- // insert into the TABLE this DATA
- if (is_string($data) && is_array($table)) {
- $tmp = $data;
- $data = $table;
- $table = $tmp;
- // trigger_error('QDB - Parameters passed to insert() were in reverse order, but it has been allowed', E_USER_NOTICE);
- }
-
- $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data)).'`) VALUES ('.implode(',', dbPlaceHolders($data)).')';
-
- $time_start = microtime(true);
- dbBeginTransaction();
- $result = dbQuery($sql, $data);
- if ($result) {
- $id = mysql_insert_id();
- dbCommitTransaction();
- // return $id;
- }
- else {
- if ($table != 'Contact') {
- trigger_error('QDB - Insert failed.', E_USER_WARNING);
- }
-
- dbRollbackTransaction();
- // $id = false;
- }
-
- // logfile($fullSql);
- $time_end = microtime(true);
- $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['insert']++;
-
- return $id;
-
-}//end dbInsert()
-
-
-/*
- * Passed an array and a table name, it attempts to insert the data into the table.
- * $data is an array (rows) of key value pairs. keys are fields. Rows need to have same fields.
- * Check for boolean false to determine whether insert failed
- * */
-
-
-function dbBulkInsert($data, $table) {
- global $db_stats;
- // the following block swaps the parameters if they were given in the wrong order.
- // it allows the method to work for those that would rather it (or expect it to)
- // follow closer with SQL convention:
- // insert into the TABLE this DATA
- if (is_string($data) && is_array($table)) {
- $tmp = $data;
- $data = $table;
- $table = $tmp;
- }
- if (count($data) === 0) {
- return false;
- }
- if (count($data[0]) === 0) {
- return false;
- }
-
- $sql = 'INSERT INTO `'.$table.'` (`'.implode('`,`', array_keys($data[0])).'`) VALUES ';
- $values ='';
-
- foreach ($data as $row) {
- if ($values != '') {
- $values .= ',';
- }
- $rowvalues='';
- foreach ($row as $key => $value) {
- if ($rowvalues != '') {
- $rowvalues .= ',';
- }
- $rowvalues .= "'".mres($value)."'";
- }
- $values .= "(".$rowvalues.")";
- }
-
- $time_start = microtime(true);
- $result = dbQuery($sql.$values);
-
- // logfile($fullSql);
- $time_end = microtime(true);
- $db_stats['insert_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['insert']++;
-
- return $result;
-
-}//end dbBulkInsert()
-
-
-/*
- * Passed an array, table name, WHERE clause, and placeholder parameters, it attempts to update a record.
- * Returns the number of affected rows
- * */
-
-
-function dbUpdate($data, $table, $where=null, $parameters=array()) {
- global $fullSql;
- global $db_stats;
- // the following block swaps the parameters if they were given in the wrong order.
- // it allows the method to work for those that would rather it (or expect it to)
- // follow closer with SQL convention:
- // update the TABLE with this DATA
- if (is_string($data) && is_array($table)) {
- $tmp = $data;
- $data = $table;
- $table = $tmp;
- // trigger_error('QDB - The first two parameters passed to update() were in reverse order, but it has been allowed', E_USER_NOTICE);
- }
-
- // need field name and placeholder value
- // but how merge these field placeholders with actual $parameters array for the WHERE clause
- $sql = 'UPDATE `'.$table.'` set ';
- foreach ($data as $key => $value) {
- $sql .= '`'.$key.'` '.'=:'.$key.',';
- }
-
- $sql = substr($sql, 0, -1);
- // strip off last comma
- if ($where) {
- $sql .= ' WHERE '.$where;
- $data = array_merge($data, $parameters);
- }
-
- $time_start = microtime(true);
- if (dbQuery($sql, $data)) {
- $return = mysql_affected_rows();
- }
- else {
- // echo("$fullSql");
- trigger_error('QDB - Update failed.', E_USER_WARNING);
- $return = false;
- }
-
- $time_end = microtime(true);
- $db_stats['update_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['update']++;
-
- return $return;
-
-}//end dbUpdate()
-
-
-function dbDelete($table, $where=null, $parameters=array()) {
- $sql = 'DELETE FROM `'.$table.'`';
- if ($where) {
- $sql .= ' WHERE '.$where;
- }
-
- if (dbQuery($sql, $parameters)) {
- return mysql_affected_rows();
- }
- else {
- return false;
- }
-
-}//end dbDelete()
-
-
-/*
- * Fetches all of the rows (associatively) from the last performed query.
- * Most other retrieval functions build off this
- * */
-
-
-function dbFetchRows($sql, $parameters=array()) {
- global $db_stats;
-
- $time_start = microtime(true);
- $result = dbQuery($sql, $parameters);
-
- if (mysql_num_rows($result) > 0) {
- $rows = array();
- while ($row = mysql_fetch_assoc($result)) {
- $rows[] = $row;
- }
-
- mysql_free_result($result);
- return $rows;
- }
-
- mysql_free_result($result);
-
- $time_end = microtime(true);
- $db_stats['fetchrows_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['fetchrows']++;
-
- // no records, thus return empty array
- // which should evaluate to false, and will prevent foreach notices/warnings
- return array();
-
-}//end dbFetchRows()
-
-
-/*
- * This is intended to be the method used for large result sets.
- * It is intended to return an iterator, and act upon buffered data.
- * */
-
-
-function dbFetch($sql, $parameters=array()) {
- return dbFetchRows($sql, $parameters);
- /*
- // for now, don't do the iterator thing
- $result = dbQuery($sql, $parameters);
- if($result) {
- // return new iterator
- return new dbIterator($result);
- } else {
- return null; // ??
- }
- */
-
-}//end dbFetch()
-
-
-/*
- * Like fetch(), accepts any number of arguments
- * The first argument is an sprintf-ready query stringTypes
- * */
-
-
-function dbFetchRow($sql=null, $parameters=array()) {
- global $db_stats;
-
- $time_start = microtime(true);
- $result = dbQuery($sql, $parameters);
- if ($result) {
- $row = mysql_fetch_assoc($result);
- mysql_free_result($result);
- $time_end = microtime(true);
-
- $db_stats['fetchrow_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['fetchrow']++;
-
- return $row;
- }
- else {
- return null;
- }
-
- $time_start = microtime(true);
-
-}//end dbFetchRow()
-
-
-/*
- * Fetches the first call from the first row returned by the query
- * */
-
-
-function dbFetchCell($sql, $parameters=array()) {
- global $db_stats;
- $time_start = microtime(true);
- $row = dbFetchRow($sql, $parameters);
- if ($row) {
- return array_shift($row);
- // shift first field off first row
- }
-
- $time_end = microtime(true);
-
- $db_stats['fetchcell_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['fetchcell']++;
-
- return null;
-
-}//end dbFetchCell()
-
-
-/*
- * This method is quite different from fetchCell(), actually
- * It fetches one cell from each row and places all the values in 1 array
- * */
-
-
-function dbFetchColumn($sql, $parameters=array()) {
- global $db_stats;
- $time_start = microtime(true);
- $cells = array();
- foreach (dbFetch($sql, $parameters) as $row) {
- $cells[] = array_shift($row);
- }
-
- $time_end = microtime(true);
-
- $db_stats['fetchcol_sec'] += number_format(($time_end - $time_start), 8);
- $db_stats['fetchcol']++;
-
- return $cells;
-
-}//end dbFetchColumn()
-
-
-/*
- * Should be passed a query that fetches two fields
- * The first will become the array key
- * The second the key's value
- */
-
-
-function dbFetchKeyValue($sql, $parameters=array()) {
- $data = array();
- foreach (dbFetch($sql, $parameters) as $row) {
- $key = array_shift($row);
- if (sizeof($row) == 1) {
- // if there were only 2 fields in the result
- // use the second for the value
- $data[$key] = array_shift($row);
- }
- else {
- // if more than 2 fields were fetched
- // use the array of the rest as the value
- $data[$key] = $row;
- }
- }
-
- return $data;
-
-}//end dbFetchKeyValue()
-
-
-/*
- * This combines a query and parameter array into a final query string for execution
- * PDO drivers don't need to use this
- */
-
-
-function dbMakeQuery($sql, $parameters) {
- // bypass extra logic if we have no parameters
- if (sizeof($parameters) == 0) {
- return $sql;
- }
-
- $parameters = dbPrepareData($parameters);
- // separate the two types of parameters for easier handling
- $questionParams = array();
- $namedParams = array();
- foreach ($parameters as $key => $value) {
- if (is_numeric($key)) {
- $questionParams[] = $value;
- }
- else {
- $namedParams[':'.$key] = $value;
- }
- }
-
- // sort namedParams in reverse to stop substring squashing
- krsort($namedParams);
-
- // split on question-mark and named placeholders
- $result = preg_split('/(\?|:[a-zA-Z0-9_-]+)/', $sql, -1, (PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE));
-
- // every-other item in $result will be the placeholder that was found
- $query = '';
- $res_size = sizeof($result);
- for ($i = 0; $i < $res_size; $i += 2) {
- $query .= $result[$i];
-
- $j = ($i + 1);
- if (array_key_exists($j, $result)) {
- $test = $result[$j];
- if ($test == '?') {
- $query .= array_shift($questionParams);
- }
- else {
- $query .= $namedParams[$test];
- }
- }
- }
-
- return $query;
-
-}//end dbMakeQuery()
-
-
-function dbPrepareData($data) {
- $values = array();
-
- foreach ($data as $key => $value) {
- $escape = true;
- // don't quote or esc if value is an array, we treat it
- // as a "decorator" that tells us not to escape the
- // value contained in the array
- if (is_array($value) && !is_object($value)) {
- $escape = false;
- $value = array_shift($value);
- }
-
- // it's not right to worry about invalid fields in this method because we may be operating on fields
- // that are aliases, or part of other tables through joins
- // if(!in_array($key, $columns)) // skip invalid fields
- // continue;
- if ($escape) {
- $values[$key] = "'".mysql_real_escape_string($value)."'";
- }
- else {
- $values[$key] = $value;
- }
- }
-
- return $values;
-
-}//end dbPrepareData()
-
-
-/*
- * Given a data array, this returns an array of placeholders
- * These may be question marks, or ":email" type
- */
-
-
-function dbPlaceHolders($values) {
- $data = array();
- foreach ($values as $key => $value) {
- if (is_numeric($key)) {
- $data[] = '?';
- }
- else {
- $data[] = ':'.$key;
- }
- }
-
- return $data;
-
-}//end dbPlaceHolders()
-
-
-function dbBeginTransaction() {
- mysql_query('begin');
-
-}//end dbBeginTransaction()
-
-
-function dbCommitTransaction() {
- mysql_query('commit');
-
-}//end dbCommitTransaction()
-
-
-function dbRollbackTransaction() {
- mysql_query('rollback');
-
-}//end dbRollbackTransaction()
-
-
-/*
- class dbIterator implements Iterator {
- private $result;
- private $i;
-
- public function __construct($r) {
- $this->result = $r;
- $this->i = 0;
- }
- public function rewind() {
- mysql_data_seek($this->result, 0);
- $this->i = 0;
- }
- public function current() {
- $a = mysql_fetch_assoc($this->result);
- return $a;
- }
- public function key() {
- return $this->i;
- }
- public function next() {
- $this->i++;
- $a = mysql_data_seek($this->result, $this->i);
- if($a === false) {
- $this->i = 0;
- }
- return $a;
- }
- public function valid() {
- return ($this->current() !== false);
- }
- }
- */
+if (file_exists($config['install_dir'].'/includes/dbFacile.'.$config['db']['extension'].'.php')) {
+ require_once $config['install_dir'].'/includes/dbFacile.'.$config['db']['extension'].'.php';
+}
+else {
+ echo $config['db']['extension'] . " extension not found\n";
+ exit;
+}
diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php
index e11046fced..7807ba1795 100644
--- a/includes/defaults.inc.php
+++ b/includes/defaults.inc.php
@@ -43,6 +43,9 @@ $config['temp_dir'] = '/tmp';
$config['install_dir'] = '/opt/'.$config['project_id'];
$config['log_dir'] = $config['install_dir'].'/logs';
+// MySQL extension to use
+$config['db']['extension'] = 'mysql';//mysql and mysqli available
+
// What is my own hostname (used to identify this host in its own database)
$config['own_hostname'] = 'localhost';
diff --git a/includes/definitions.inc.php b/includes/definitions.inc.php
index 171db75a40..0fc20c740d 100644
--- a/includes/definitions.inc.php
+++ b/includes/definitions.inc.php
@@ -5,14 +5,30 @@ require_once $config['install_dir'].'/includes/dbFacile.php';
require_once $config['install_dir'].'/includes/mergecnf.inc.php';
// Connect to database
-$database_link = mysql_pconnect($config['db_host'], $config['db_user'], $config['db_pass']);
+if ($config['db']['extension'] == 'mysqli') {
+ $database_link = mysqli_connect('p:'.$config['db_host'], $config['db_user'], $config['db_pass']);
+}
+else {
+ $database_link = mysql_pconnect($config['db_host'], $config['db_user'], $config['db_pass']);
+}
+
if (!$database_link) {
echo '
MySQL Error
';
- echo mysql_error();
+ if ($config['db']['extension'] == 'mysqli') {
+ echo mysqli_error($database_link);
+ }
+ else {
+ echo mysql_error();
+ }
die;
}
-$database_db = mysql_select_db($config['db_name'], $database_link);
+if ($config['db']['extension'] == 'mysqli') {
+ $database_db = mysqli_select_db($database_link, $config['db_name']);
+}
+else {
+ $database_db = mysql_select_db($config['db_name'], $database_link);
+}
$clone = $config;
foreach (dbFetchRows('select config_name,config_value from config') as $obj) {
diff --git a/includes/discovery/functions.inc.php b/includes/discovery/functions.inc.php
index c5177ff22d..512f39cff4 100644
--- a/includes/discovery/functions.inc.php
+++ b/includes/discovery/functions.inc.php
@@ -545,9 +545,6 @@ function discover_storage(&$valid, $device, $index, $type, $mib, $descr, $size,
),
'storage'
);
- if ($debug) {
- mysql_error();
- }
echo '+';
}
diff --git a/includes/discovery/hr-device.inc.php b/includes/discovery/hr-device.inc.php
index d7a261eb13..aa168da8ce 100644
--- a/includes/discovery/hr-device.inc.php
+++ b/includes/discovery/hr-device.inc.php
@@ -56,11 +56,9 @@ $sql = "SELECT * FROM `hrDevice` WHERE `device_id` = '".$device['device_id']."'
foreach (dbFetchRows($sql) as $test_hrDevice) {
if (!$valid_hrDevice[$test_hrDevice['hrDeviceIndex']]) {
echo '-';
- mysql_query("DELETE FROM `hrDevice` WHERE hrDevice_id = '".$test_hrDevice['hrDevice_id']."'");
dbDelete('hrDevice', '`hrDevice_id` = ?', array($test_hrDevice['hrDevice_id']));
if ($debug) {
print_r($test_hrDevice);
- echo mysql_affected_rows().' row deleted';
}
}
}
diff --git a/includes/discovery/ports-stack.inc.php b/includes/discovery/ports-stack.inc.php
index 81b927d3b8..dfa03b111d 100644
--- a/includes/discovery/ports-stack.inc.php
+++ b/includes/discovery/ports-stack.inc.php
@@ -20,9 +20,6 @@ foreach ($stack_poll_array as $port_id_high => $entry_high) {
else {
dbUpdate(array('ifStackStatus' => $ifStackStatus), 'ports_stack', 'device_id=? AND port_id_high=? AND `port_id_low`=?', array($device['device_id'], $port_id_high, $port_id_low));
echo 'U';
- if ($debug) {
- echo mysql_error();
- }
}
unset($stack_db_array[$port_id_high][$port_id_low]);
@@ -30,9 +27,6 @@ foreach ($stack_poll_array as $port_id_high => $entry_high) {
else {
dbInsert(array('device_id' => $device['device_id'], 'port_id_high' => $port_id_high, 'port_id_low' => $port_id_low, 'ifStackStatus' => $ifStackStatus), 'ports_stack');
echo '+';
- if ($debug) {
- echo mysql_error();
- }
}
}//end foreach
}//end foreach
diff --git a/includes/sql-schema/update.php b/includes/sql-schema/update.php
index aa5e307bf7..6497d1ca55 100644
--- a/includes/sql-schema/update.php
+++ b/includes/sql-schema/update.php
@@ -108,11 +108,21 @@ foreach ($filelist as $file) {
}
if ($line[0] != '#') {
- $update = mysql_query($line);
+ if ($config['db']['extension'] == 'mysqli') {
+ $update = mysqli_query($database_link, $line);
+ }
+ else {
+ $update = mysql_query($line);
+ }
if (!$update) {
$err++;
if ($debug) {
- echo mysql_error()."\n";
+ if ($config['db']['extension'] == 'mysqli') {
+ echo mysqli_error($database_link)."\n";
+ }
+ else {
+ echo mysql_error()."\n";
+ }
}
}
}