diff --git a/db.class.php b/db.class.php index d5a458e..f9c22c1 100644 --- a/db.class.php +++ b/db.class.php @@ -35,7 +35,7 @@ class DB public static $encoding = 'latin1'; public static $queryMode = 'queryAllRows'; public static $success_handler = false; - public static $error_handler = 'meekrodb_error_handler'; + public static $error_handler = true; public static $throw_exception_on_error = false; public static function get() { @@ -145,31 +145,57 @@ class DB call_user_func_array('DB::queryNull', $args); } - public static function insertOrReplace($which, $table, $data) { - $data = unserialize(serialize($data)); // break references within array - $keys_str = implode(', ', DB::wrapStr(array_keys($data), '`')); + public static function insertOrReplace($which, $table, $datas, $many) { + $datas = unserialize(serialize($datas)); // break references within array + $keys = null; + if (! $many) $datas = array($datas); - foreach ($data as &$datum) { - if (is_object($datum) && ($datum instanceof MeekroDBEval)) { - $datum = $datum->text; - } else { - if (is_array($datum)) $datum = serialize($datum); - $datum = (is_int($datum) ? $datum : "'" . DB::escape($datum) . "'"); + foreach ($datas as $data) { + if (! $keys) { + $keys = array_keys($data); + if ($many) sort($keys); } + + $insert_values = array(); + + foreach ($keys as $key) { + if ($many && !isset($data[$key])) die("insert/replace many: each assoc array must have the same keys!"); + $datum = $data[$key]; + + if (is_object($datum) && ($datum instanceof MeekroDBEval)) { + $datum = $datum->text; + } else { + if (is_array($datum)) $datum = serialize($datum); + $datum = (is_int($datum) ? $datum : "'" . DB::escape($datum) . "'"); + } + $insert_values[] = $datum; + } + + + $values[] = '(' . implode(', ', $insert_values) . ')'; } - $values_str = implode(', ', array_values($data)); $table = self::formatTableName($table); + $keys_str = implode(', ', DB::wrapStr($keys, '`')); + $values_str = implode(',', $values); - DB::queryNull("$which INTO $table ($keys_str) VALUES ($values_str)"); + DB::queryNull("$which INTO $table ($keys_str) VALUES $values_str"); } public static function insert($table, $data) { - return DB::insertOrReplace('INSERT', $table, $data); + return DB::insertOrReplace('INSERT', $table, $data, false); + } + + public static function insertMany($table, $data) { + return DB::insertOrReplace('INSERT', $table, $data, true); } public static function replace($table, $data) { - return DB::insertOrReplace('REPLACE', $table, $data); + return DB::insertOrReplace('REPLACE', $table, $data, false); + } + + public static function replaceMany($table, $data) { + return DB::insertOrReplace('REPLACE', $table, $data, true); } public static function delete() { @@ -326,8 +352,10 @@ class DB if (DB::$success_handler) $runtime = microtime(true) - $starttime; if (!$sql || $error = DB::checkError()) { - if (function_exists(DB::$error_handler)) { - call_user_func(DB::$error_handler, array( + if (DB::$error_handler) { + $error_handler = is_callable(DB::$error_handler) ? DB::$error_handler : 'meekrodb_error_handler'; + + call_user_func($error_handler, array( 'query' => $sql, 'error' => $error )); @@ -339,7 +367,7 @@ class DB } } else if (DB::$success_handler) { $runtime = sprintf('%f', $runtime * 1000); - $success_handler = function_exists(DB::$success_handler) ? DB::$success_handler : 'meekrodb_debugmode_handler'; + $success_handler = is_callable(DB::$success_handler) ? DB::$success_handler : 'meekrodb_debugmode_handler'; call_user_func($success_handler, array( 'query' => $sql, diff --git a/simpletest/BasicTest.php b/simpletest/BasicTest.php index e72d8e7..93abb3d 100644 --- a/simpletest/BasicTest.php +++ b/simpletest/BasicTest.php @@ -174,12 +174,66 @@ class BasicTest extends SimpleTest { $this->assert(intval($ct) === 0); } + function test_4_3_insertmany() { + $ins[] = array( + 'username' => '1ofmany', + 'password' => 'something', + 'age' => 23, + 'height' => 190.194 + ); + $ins[] = array( + 'password' => 'somethingelse', + 'username' => '2ofmany', + 'age' => 25, + 'height' => 190.194 + ); + + DB::insertMany('accounts', $ins); + $this->assert(DB::affectedRows() === 2); + + $rows = DB::query("SELECT * FROM accounts WHERE height=%d ORDER BY age ASC", 190.194); + $this->assert(count($rows) === 2); + $this->assert($rows[0]['username'] === '1ofmany'); + $this->assert($rows[0]['age'] === '23'); + $this->assert($rows[1]['age'] === '25'); + $this->assert($rows[1]['password'] === 'somethingelse'); + $this->assert($rows[1]['username'] === '2ofmany'); + + } + function test_5_error_handler() { - global $error_callback_worked; + global $error_callback_worked, $static_error_callback_worked, $nonstatic_error_callback_worked, + $anonymous_error_callback_worked; DB::$error_handler = 'new_error_callback'; DB::query("SELET * FROM accounts"); $this->assert($error_callback_worked === 1); + + DB::$error_handler = array('BasicTest', 'static_error_callback'); + DB::query("SELET * FROM accounts"); + $this->assert($static_error_callback_worked === 1); + + DB::$error_handler = array($this, 'nonstatic_error_callback'); + DB::query("SELET * FROM accounts"); + $this->assert($nonstatic_error_callback_worked === 1); + + DB::$error_handler = function($params) { + global $anonymous_error_callback_worked; + if (substr_count($params['error'], 'You have an error in your SQL syntax')) $anonymous_error_callback_worked = 1; + }; + DB::query("SELET * FROM accounts"); + $this->assert($anonymous_error_callback_worked === 1); + + } + + public static function static_error_callback($params) { + global $static_error_callback_worked; + if (substr_count($params['error'], 'You have an error in your SQL syntax')) $static_error_callback_worked = 1; + } + + public function nonstatic_error_callback($params) { + global $nonstatic_error_callback_worked; + if (substr_count($params['error'], 'You have an error in your SQL syntax')) $nonstatic_error_callback_worked = 1; } function test_6_exception_catch() { diff --git a/simpletest/test.php b/simpletest/test.php index 37c9543..6b9fa2c 100755 --- a/simpletest/test.php +++ b/simpletest/test.php @@ -48,7 +48,7 @@ foreach ($classes_to_test as $class) { $object = new $class(); foreach (get_class_methods($object) as $method) { - if (substr($method, 0, 2) == '__') continue; + if (substr($method, 0, 4) != 'test') continue; echo "Running $class::$method..\n"; $object->$method(); }