3 Commits
v1.1 ... v1.2

Author SHA1 Message Date
Sergey Tsalkov
5525d22a9b we can now throw an exception on errors if DB::$throw_exception_on_error is set 2011-03-04 17:23:42 -05:00
Sergey Tsalkov
0a7b323e81 you can now specify your own error handling function by changing DB::$error_handler 2011-03-04 16:49:17 -05:00
Sergey Tsalkov
620c607f61 remove array_map with inline functions for PHP 5.2 compatability
thanks to Adam for pointing this out!
2011-03-02 12:46:07 -05:00
2 changed files with 102 additions and 8 deletions

View File

@@ -16,7 +16,9 @@ class DB
public static $password = '';
public static $host = 'localhost';
public static $encoding = 'latin1';
public static $queryMode = 'queryAllRows'; //buffered, unbuffered, queryAllRows
public static $queryMode = 'queryAllRows';
public static $error_handler = 'meekrodb_error_handler';
public static $throw_exception_on_error = false;
public static function get($dbName = '') {
static $mysql = null;
@@ -89,6 +91,20 @@ class DB
return call_user_func_array($function, $args);
}
private static function wrapStr($strOrArray, $wrapChar, $escape = false) {
if (! is_array($strOrArray)) {
if ($escape) return $wrapChar . DB::escape($strOrArray) . $wrapChar;
else return $wrapChar . $strOrArray . $wrapChar;
} else {
$R = array();
foreach ($strOrArray as $element) {
$R[] = DB::wrapStr($element, $wrapChar, $escape);
}
return $R;
}
}
public static function freeResult($result) {
if (! ($result instanceof MySQLi_Result)) return;
return $result->free();
@@ -112,7 +128,7 @@ class DB
public static function insertOrReplace($which, $table, $data) {
$data = unserialize(serialize($data)); // break references within array
$keys_str = implode(', ', array_map(function($x) { return "`" . $x . "`"; }, array_keys($data)));
$keys_str = implode(', ', DB::wrapStr(array_keys($data), '`'));
foreach ($data as &$datum) {
if (is_array($datum)) $datum = serialize($datum);
@@ -219,7 +235,7 @@ class DB
if (! is_array($arg)) die("Badly formatted SQL query: $sql -- expecting array, but didn't get one!");
}
if ($type == '%ls') $result = array_map(function($x) { return "'" . DB::escape($x) . "'"; }, $arg);
if ($type == '%ls') $result = DB::wrapStr($arg, "'", true);
else if ($type == '%li') $result = array_map('intval', $arg);
else if ($type == '%ld') $result = array_map('floatval', $arg);
else if ($type == '%lb') $result = array_map('DB::formatTableName', $arg);
@@ -276,14 +292,21 @@ class DB
$result = $db->query($sql, $is_buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
if (DB::$debug) $runtime = microtime(true) - $starttime;
$sqlShow = "$sql (" . ($is_buffered ? 'MYSQLI_STORE_RESULT' : 'MYSQLI_USE_RESULT') . ")";
if (!$sql || $error = DB::checkError()) {
echo "ATTEMPTED QUERY: $sqlShow<br>\n";
echo "ERROR: $error<br>\n";
debug_print_backtrace();
die;
if (function_exists(DB::$error_handler)) {
call_user_func(DB::$error_handler, array(
'query' => $sql,
'error' => $error
));
}
if (DB::$throw_exception_on_error) {
$e = new MeekroDBException($error, $sql);
throw $e;
}
} else if (DB::$debug) {
$runtime = sprintf('%f', $runtime * 1000);
$sqlShow = "$sql (" . ($is_buffered ? 'MYSQLI_STORE_RESULT' : 'MYSQLI_USE_RESULT') . ")";
echo "QUERY: $sqlShow [$runtime ms]<br>\n";
}
@@ -468,4 +491,31 @@ class DBTransaction {
}
class MeekroDBException extends Exception {
protected $query = '';
function __construct($message='', $query='') {
parent::__construct($message);
$this->query = $query;
}
public function getQuery() { return $this->query; }
}
function meekrodb_error_handler($params) {
$out[] = "QUERY: " . $params['query'];
$out[] = "ERROR: " . $params['error'];
$out[] = "";
if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) {
echo implode("\n", $out);
} else {
echo implode("<br>\n", $out);
}
debug_print_backtrace();
die;
}
?>

View File

@@ -1,4 +1,11 @@
<?
function new_error_callback($params) {
global $error_callback_worked;
if (substr_count($params['error'], 'You have an error in your SQL syntax')) $error_callback_worked = 1;
}
class BasicTest extends SimpleTest {
function __construct() {
error_reporting(E_ALL);
@@ -95,6 +102,43 @@ class BasicTest extends SimpleTest {
$results = DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
$this->assert(count($results) === 2);
}
function test_5_error_handler() {
global $error_callback_worked;
DB::$error_handler = 'new_error_callback';
DB::query("SELET * FROM accounts");
$this->assert($error_callback_worked === 1);
}
function test_6_exception_catch() {
DB::$error_handler = '';
DB::$throw_exception_on_error = true;
try {
DB::query("SELET * FROM accounts");
} catch(MeekroDBException $e) {
$this->assert(substr_count($e->getMessage(), 'You have an error in your SQL syntax'));
$this->assert($e->getQuery() === 'SELET * FROM accounts');
$exception_was_caught = 1;
}
$this->assert($exception_was_caught === 1);
try {
DB::insert('`libdb_test`.`accounts`', array(
'id' => 2,
'username' => 'Another Dude\'s \'Mom"',
'password' => 'asdfsdse',
'age' => 35,
'height' => 555.23
));
} catch(MeekroDBException $e) {
$this->assert(substr_count($e->getMessage(), 'Duplicate entry'));
$exception_was_caught = 2;
}
$this->assert($exception_was_caught === 2);
}
}