We now can work with prepared statements
This commit is contained in:
parent
772825690f
commit
63b0b05445
242
include/dba.php
242
include/dba.php
|
@ -15,12 +15,15 @@ require_once('include/datetime.php');
|
||||||
class dba {
|
class dba {
|
||||||
|
|
||||||
private $debug = 0;
|
private $debug = 0;
|
||||||
private $db;
|
//private $db;
|
||||||
|
public $db;
|
||||||
private $result;
|
private $result;
|
||||||
private $driver;
|
//private $driver;
|
||||||
|
public $driver;
|
||||||
public $connected = false;
|
public $connected = false;
|
||||||
public $error = false;
|
public $error = false;
|
||||||
private $_server_info = '';
|
private $_server_info = '';
|
||||||
|
private static $dbo;
|
||||||
|
|
||||||
function __construct($server, $user, $pass, $db, $install = false) {
|
function __construct($server, $user, $pass, $db, $install = false) {
|
||||||
$a = get_app();
|
$a = get_app();
|
||||||
|
@ -93,6 +96,8 @@ class dba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$a->save_timestamp($stamp1, "network");
|
$a->save_timestamp($stamp1, "network");
|
||||||
|
|
||||||
|
self::$dbo = $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -462,22 +467,6 @@ class dba {
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function __destruct() {
|
|
||||||
if ($this->db) {
|
|
||||||
switch ($this->driver) {
|
|
||||||
case 'pdo':
|
|
||||||
$this->db = null;
|
|
||||||
break;
|
|
||||||
case 'mysqli':
|
|
||||||
$this->db->close();
|
|
||||||
break;
|
|
||||||
case 'mysql':
|
|
||||||
mysql_close($this->db);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Replaces ANY_VALUE() function by MIN() function,
|
* @brief Replaces ANY_VALUE() function by MIN() function,
|
||||||
* if the database server does not support ANY_VALUE().
|
* if the database server does not support ANY_VALUE().
|
||||||
|
@ -497,6 +486,223 @@ class dba {
|
||||||
}
|
}
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
if ($this->db) {
|
||||||
|
switch ($this->driver) {
|
||||||
|
case 'pdo':
|
||||||
|
$this->db = null;
|
||||||
|
break;
|
||||||
|
case 'mysqli':
|
||||||
|
$this->db->close();
|
||||||
|
break;
|
||||||
|
case 'mysql':
|
||||||
|
mysql_close($this->db);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes a prepared statement
|
||||||
|
*
|
||||||
|
* @param string $sql SQL statement
|
||||||
|
* @return object statement object
|
||||||
|
*/
|
||||||
|
static public function p($sql) {
|
||||||
|
$a = get_app();
|
||||||
|
|
||||||
|
$stamp1 = microtime(true);
|
||||||
|
|
||||||
|
$args = func_get_args();
|
||||||
|
unset($args[0]);
|
||||||
|
|
||||||
|
if (!self::$dbo OR !self::$dbo->connected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = self::$dbo->any_value_fallback($sql);
|
||||||
|
|
||||||
|
$orig_sql = $sql;
|
||||||
|
|
||||||
|
if (x($a->config,'system') && x($a->config['system'], 'db_callstack')) {
|
||||||
|
$sql = "/*".$a->callstack()." */ ".$sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (self::$dbo->driver) {
|
||||||
|
case 'pdo':
|
||||||
|
$stmt = self::$dbo->db->prepare($sql);
|
||||||
|
|
||||||
|
foreach ($args AS $param => $value) {
|
||||||
|
$stmt->bindParam($param, $args[$param]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$success = $stmt->execute();
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
$retval = $stmt;
|
||||||
|
} else {
|
||||||
|
$retval = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorInfo = self::$dbo->db->errorInfo();
|
||||||
|
|
||||||
|
if ($errorInfo) {
|
||||||
|
self::$dbo->error = $errorInfo[2];
|
||||||
|
self::$dbo->errorno = $errorInfo[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'mysqli':
|
||||||
|
$stmt = self::$dbo->db->stmt_init();
|
||||||
|
|
||||||
|
if (!$stmt->prepare($sql)) {
|
||||||
|
self::$dbo->error = self::$dbo->db->error;
|
||||||
|
self::$dbo->errorno = self::$dbo->db->errno;
|
||||||
|
$retval = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = '';
|
||||||
|
$values = array();
|
||||||
|
foreach ($args AS $param => $value) {
|
||||||
|
if (is_int($args[$param])) {
|
||||||
|
$params .= 'i';
|
||||||
|
} elseif (is_float($args[$param])) {
|
||||||
|
$params .= 'd';
|
||||||
|
} elseif (is_string($args[$param])) {
|
||||||
|
$params .= 's';
|
||||||
|
} else {
|
||||||
|
$params .= 'b';
|
||||||
|
}
|
||||||
|
$values[] = &$args[$param];
|
||||||
|
}
|
||||||
|
|
||||||
|
array_unshift($values, $params);
|
||||||
|
|
||||||
|
call_user_func_array(array($stmt, 'bind_param'), $values);
|
||||||
|
|
||||||
|
if (!$stmt->execute()) {
|
||||||
|
self::$dbo->error = self::$dbo->db->error;
|
||||||
|
self::$dbo->errorno = self::$dbo->db->errno;
|
||||||
|
$retval = false;
|
||||||
|
} elseif (method_exists($stmt, 'get_result')) {
|
||||||
|
// Is mysqlnd installed?
|
||||||
|
$retval = $stmt->get_result();
|
||||||
|
} else {
|
||||||
|
$retval = $stmt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'mysql':
|
||||||
|
// For the old "mysql" functions we cannot use prepared statements
|
||||||
|
foreach ($args AS $param => $value) {
|
||||||
|
if (is_int($args[$param]) OR is_float($args[$param])) {
|
||||||
|
$replace = intval($args[$param]);
|
||||||
|
} else {
|
||||||
|
$replace = "'".dbesc($args[$param])."'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$pos = strpos($sql, '?');
|
||||||
|
if ($pos !== false) {
|
||||||
|
$sql = substr_replace($sql, $replace, $pos, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$retval = mysql_query($sql, self::$dbo->db);
|
||||||
|
if (mysql_errno(self::$dbo->db)) {
|
||||||
|
self::$dbo->error = mysql_error(self::$dbo->db);
|
||||||
|
self::$dbo->errorno = mysql_errno(self::$dbo->db);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stamp2 = microtime(true);
|
||||||
|
$duration = (float)($stamp2 - $stamp1);
|
||||||
|
|
||||||
|
$a->save_timestamp($stamp1, 'database');
|
||||||
|
|
||||||
|
if (strtolower(substr($orig_sql, 0, 6)) != "select") {
|
||||||
|
$a->save_timestamp($stamp1, "database_write");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes a prepared statement
|
||||||
|
*
|
||||||
|
* @param string $sql SQL statement
|
||||||
|
* @return boolean Was the query successfull?
|
||||||
|
*/
|
||||||
|
static public function e($sql) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetch a single row
|
||||||
|
*
|
||||||
|
* @param object $stmt statement object
|
||||||
|
* @return array current row
|
||||||
|
*/
|
||||||
|
static public function fetch($stmt) {
|
||||||
|
switch (self::$dbo->driver) {
|
||||||
|
case 'pdo':
|
||||||
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
case 'mysqli':
|
||||||
|
// When mysqlnd is installed, we can use a shortcut
|
||||||
|
if (method_exists($stmt, 'fetch_array')) {
|
||||||
|
return $stmt->fetch_array(MYSQLI_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This code works, but is slow
|
||||||
|
|
||||||
|
// Bind the result to a result array
|
||||||
|
$cols = array();
|
||||||
|
|
||||||
|
$cols_num = array();
|
||||||
|
for ($x = 0; $x < $stmt->field_count; $x++) {
|
||||||
|
$cols[] = &$cols_num[$x];
|
||||||
|
}
|
||||||
|
|
||||||
|
call_user_func_array(array($stmt, 'bind_result'), $cols);
|
||||||
|
|
||||||
|
$success = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The slow part:
|
||||||
|
// We need to get the field names for the array keys
|
||||||
|
// It seems that there is no better way to do this.
|
||||||
|
$result = $stmt->result_metadata();
|
||||||
|
|
||||||
|
$columns = array();
|
||||||
|
foreach ($cols_num AS $col) {
|
||||||
|
$field = $result->fetch_field();
|
||||||
|
$columns[$field->name] = $col;
|
||||||
|
}
|
||||||
|
return $columns;
|
||||||
|
case 'mysql':
|
||||||
|
return mysql_fetch_array(self::$dbo->result, MYSQL_ASSOC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes the current statement
|
||||||
|
*
|
||||||
|
* @param object $stmt statement object
|
||||||
|
* @return boolean was the close successfull?
|
||||||
|
*/
|
||||||
|
static public function close($stmt) {
|
||||||
|
switch (self::$dbo->driver) {
|
||||||
|
case 'pdo':
|
||||||
|
return $stmt->closeCursor();
|
||||||
|
case 'mysqli':
|
||||||
|
return $stmt->close();
|
||||||
|
case 'mysql':
|
||||||
|
return mysql_free_result($stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function printable($s) {
|
function printable($s) {
|
||||||
|
|
|
@ -47,6 +47,11 @@ class dbm {
|
||||||
if (is_bool($array)) {
|
if (is_bool($array)) {
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_object($array)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return (is_array($array) && count($array) > 0);
|
return (is_array($array) && count($array) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user