0);
private static $_sql;
private static $_error;
private static $config;
/**
* constructor
* This does nothing with the DBA class
*/
private function __construct() {
// Rien a faire
} // construct
/**
* query
*/
public static function query($sql, $params) {
// json_encode throws errors about UTF-8 cleanliness, which we don't
// care about here.
debug_event('Query', $sql . ' ' . @json_encode($params), 6);
// Be aggressive, be strong, be dumb
$tries = 0;
do {
$stmt = self::_query($sql, $params);
} while (!$stmt && $tries++ < 3);
return $stmt;
}
private static function _query($sql, $params) {
$dbh = self::dbh();
if (!$dbh) {
debug_event('Dba', 'Error: failed to get database handle', 1);
return false;
}
// Run the query
if ($params) {
$stmt = $dbh->prepare($sql);
$stmt->execute($params);
}
else {
$stmt = $dbh->query($sql);
}
// Save the query, to make debug easier
self::$_sql = $sql;
self::$stats['query']++;
if (!$stmt) {
self::$_error = json_encode($dbh->errorInfo());
debug_event('Dba', 'Error: ' . json_encode($dbh->errorInfo()), 1);
self::disconnect();
}
else if ($stmt->errorCode() && $stmt->errorCode() != '00000') {
self::$_error = json_encode($stmt->errorInfo());
debug_event('Dba', 'Error: ' . json_encode($stmt->errorInfo()), 1);
self::disconnect();
return false;
}
return $stmt;
}
/**
* read
*/
public static function read($sql, $params = null) {
return self::query($sql, $params);
}
/**
* write
*/
public static function write($sql, $params = null) {
return self::query($sql, $params);
}
/**
* escape
*
* This runs a escape on a variable so that it can be safely inserted
* into the sql
*/
public static function escape($var) {
$var = self::dbh()->quote($var);
// This is slightly less ugly than it was, but still ugly
return substr($var, 1, -1);
}
/**
* fetch_assoc
*
* This emulates the mysql_fetch_assoc.
* We force it to always return an array, albeit an empty one
* The optional finish parameter affects whether we automatically clean
* up the result set after the last row is read.
*/
public static function fetch_assoc($resource, $finish = true) {
if (!$resource) {
return array();
}
$result = $resource->fetch(PDO::FETCH_ASSOC);
if (!$result) {
if ($finish) {
self::finish($resource);
}
return array();
}
return $result;
}
/**
* fetch_row
*
* This emulates the mysql_fetch_row
* we force it to always return an array, albeit an empty one
* The optional finish parameter affects whether we automatically clean
* up the result set after the last row is read.
*/
public static function fetch_row($resource, $finish = true) {
if (!$resource) {
return array();
}
$result = $resource->fetch(PDO::FETCH_NUM);;
if (!$result) {
if ($finish) {
self::finish($resource);
}
return array();
}
return $result;
}
/**
* num_rows
*
* This emulates the mysql_num_rows function which is really
* just a count of rows returned by our select statement, this
* doesn't work for updates or inserts.
*/
public static function num_rows($resource) {
if ($resource) {
$result = $resource->rowCount();
if ($result) {
return $result;
}
}
return 0;
}
/**
* finish
*
* This closes a result handle and clears the memory associated with it
*/
public static function finish($resource) {
if ($resource) {
$resource->closeCursor();
}
}
/**
* affected_rows
*
* This emulates the mysql_affected_rows function
*/
public static function affected_rows($resource) {
if ($resource) {
$result = $resource->rowCount();
if ($result) {
return $result;
}
}
return 0;
}
/**
* _connect
*
* This connects to the database, used by the DBH function
*/
private static function _connect() {
$username = Config::get('database_username');
$hostname = Config::get('database_hostname');
$password = Config::get('database_password');
$port = Config::get('database_port');
// Build the data source name
if (strpos($hostname, '/') === 0) {
$dsn = 'mysql:unix_socket=' . $hostname;
}
else {
$dsn = 'mysql:host=' . $hostname ?: 'localhost';
}
if ($port) {
$dsn .= ';port=' . intval($port);
}
try {
$dbh = new PDO($dsn, $username, $password);
}
catch (PDOException $e) {
self::$_error = $e->getMessage();
debug_event('Dba', 'Connection failed: ' . $e->getMessage(), 1);
return null;
}
return $dbh;
}
private static function _setup_dbh($dbh, $database) {
if (!$dbh) {
return false;
}
$charset = self::translate_to_mysqlcharset(Config::get('site_charset'));
$charset = $charset['charset'];
if ($dbh->exec('SET NAMES ' . $charset) === false) {
debug_event('Dba', 'Unable to set connection charset to ' . $charset, 1);
}
if ($dbh->exec('USE `' . $database . '`') === false) {
self::$_error = json_encode($dbh->errorInfo());
debug_event('Dba', 'Unable to select database ' . $database . ': ' . json_encode($dbh->errorInfo()), 1);
}
if (Config::get('sql_profiling')) {
$dbh->exec('SET profiling=1');
$dbh->exec('SET profiling_history_size=50');
$dbh->exec('SET query_cache_type=0');
}
}
/**
* check_database
*
* Make sure that we can connect to the database
*/
public static function check_database() {
$dbh = self::_connect();
if (!$dbh || $dbh->errorCode()) {
self::$_error = json_encode($dbh->errorInfo());
return false;
}
return true;
}
/**
* check_database_inserted
*
* Checks to make sure that you have inserted the database
* and that the user you are using has access to it.
*/
public static function check_database_inserted() {
$sql = "DESCRIBE session";
$db_results = Dba::read($sql);
if (!$db_results) {
return false;
}
// Make sure the whole table is there
if (Dba::num_rows($db_results) != '7') {
return false;
}
return true;
}
/**
* show_profile
*
* This function is used for debug, helps with profiling
*/
public static function show_profile() {
if (Config::get('sql_profiling')) {
print '
Profiling data:
';
$res = Dba::read('SHOW PROFILES');
print '
' . implode(' | ', $r) . ' |