Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed0b6f040d | ||
|
|
f82f0cc208 | ||
|
|
7febdbd1f5 | ||
|
|
57b7527a46 | ||
|
|
e30c240d54 | ||
|
|
13f249f200 | ||
|
|
f7a52ca410 | ||
|
|
d944430401 | ||
|
|
a10b76b2de | ||
|
|
50ed9675f3 | ||
|
|
1724b7276b | ||
|
|
aad5cbbbac | ||
|
|
5108480e03 | ||
|
|
cd64dd724b | ||
|
|
15f40efe5d | ||
|
|
30f3d9454a | ||
|
|
dc21f646af | ||
|
|
50fd6ed6d2 | ||
|
|
6487873c68 | ||
|
|
ac626b0795 | ||
|
|
bac5503d5a | ||
|
|
42894b70ae | ||
|
|
20c7acd8a4 | ||
|
|
c0f3a7f31d | ||
|
|
1d2ad974f8 | ||
|
|
2ea4c4c539 | ||
|
|
7c1f9bc226 | ||
|
|
dab71efacd | ||
|
|
38545ddb3a | ||
|
|
0fb0071314 | ||
|
|
03ff51a997 | ||
|
|
4ff57845e4 |
136
README.md
136
README.md
@@ -15,61 +15,85 @@ When you're ready to get started, see the [Quick Start Guide](http://www.meekro.
|
||||
### Manual Setup
|
||||
Include the `db.class.php` file into your project and set it up like this:
|
||||
|
||||
require_once 'db.class.php';
|
||||
DB::$user = 'my_database_user';
|
||||
DB::$password = 'my_database_password';
|
||||
DB::$dbName = 'my_database_name';
|
||||
```php
|
||||
require_once 'db.class.php';
|
||||
DB::$user = 'my_database_user';
|
||||
DB::$password = 'my_database_password';
|
||||
DB::$dbName = 'my_database_name';
|
||||
```
|
||||
|
||||
### Composer
|
||||
Add this to your `composer.json`
|
||||
|
||||
{
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"sergeytsalkov/meekrodb": "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Code Examples
|
||||
========
|
||||
### Grab some rows from the database and print out a field from each row.
|
||||
|
||||
$accounts = DB::query("SELECT * FROM accounts WHERE type = %s AND age > %i", $type, 15);
|
||||
foreach ($accounts as $account) {
|
||||
```php
|
||||
$accounts = DB::query("SELECT * FROM accounts WHERE type = %s AND age > %i", $type, 15);
|
||||
foreach ($accounts as $account) {
|
||||
echo $account['username'] . "\n";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Insert a new row.
|
||||
|
||||
DB::insert('mytable', array(
|
||||
```php
|
||||
DB::insert('mytable', array(
|
||||
'name' => $name,
|
||||
'rank' => $rank,
|
||||
'location' => $location,
|
||||
'age' => $age,
|
||||
'intelligence' => $intelligence
|
||||
));
|
||||
));
|
||||
```
|
||||
|
||||
### Grab one row or field
|
||||
|
||||
$account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe');
|
||||
$number_accounts = DB::queryFirstField("SELECT COUNT(*) FROM accounts");
|
||||
```php
|
||||
$account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe');
|
||||
$number_accounts = DB::queryFirstField("SELECT COUNT(*) FROM accounts");
|
||||
```
|
||||
|
||||
### Use a list in a query
|
||||
DB::query("SELECT * FROM tbl WHERE name IN %ls AND age NOT IN %li", array('John', 'Bob'), array(12, 15));
|
||||
```php
|
||||
DB::query("SELECT * FROM tbl WHERE name IN %ls AND age NOT IN %li", array('John', 'Bob'), array(12, 15));
|
||||
```
|
||||
|
||||
### Log all queries and errors
|
||||
```php
|
||||
// log all queries and errors to file, or ..
|
||||
DB::$logfile = '/home/username/logfile.txt';
|
||||
|
||||
// log all queries and errors to screen
|
||||
DB::$logfile = fopen('php://output', 'w');
|
||||
```
|
||||
|
||||
### Nested Transactions
|
||||
```php
|
||||
DB::$nested_transactions = true;
|
||||
DB::startTransaction(); // outer transaction
|
||||
// .. some queries..
|
||||
$depth = DB::startTransaction(); // inner transaction
|
||||
echo $depth . 'transactions are currently active'; // 2
|
||||
|
||||
DB::$nested_transactions = true;
|
||||
DB::startTransaction(); // outer transaction
|
||||
// .. some queries..
|
||||
$depth = DB::startTransaction(); // inner transaction
|
||||
echo $depth . 'transactions are currently active'; // 2
|
||||
// .. some queries..
|
||||
DB::commit(); // commit inner transaction
|
||||
// .. some queries..
|
||||
DB::commit(); // commit outer transaction
|
||||
```
|
||||
|
||||
// .. some queries..
|
||||
DB::commit(); // commit inner transaction
|
||||
// .. some queries..
|
||||
DB::commit(); // commit outer transaction
|
||||
|
||||
### Lots More - See: http://www.meekro.com/docs.php
|
||||
### Lots More - See: http://meekro.com/docs
|
||||
|
||||
|
||||
How is MeekroDB better than PDO?
|
||||
@@ -84,13 +108,23 @@ MeekroDB works. Still, if you need database objects, MeekroDB can do that too.
|
||||
The code below escapes your parameters for safety, runs the query, and grabs
|
||||
the first row of results. Try doing that in one line with PDO.
|
||||
|
||||
$account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe');
|
||||
```php
|
||||
$account = DB::queryFirstRow("SELECT * FROM accounts WHERE username=%s", 'Joe');
|
||||
```
|
||||
|
||||
Or how about just one field?
|
||||
|
||||
```php
|
||||
$created_at = DB::queryFirstField("SELECT created_at FROM accounts WHERE username=%s", 'Joe');
|
||||
```
|
||||
|
||||
### Work with list parameters easily
|
||||
Using MySQL's IN keyword should not be hard. MeekroDB smooths out the syntax for you,
|
||||
PDO does not.
|
||||
|
||||
$accounts = DB::query("SELECT * FROM accounts WHERE username IN %ls", array('Joe', 'Frank'));
|
||||
```php
|
||||
$accounts = DB::query("SELECT * FROM accounts WHERE username IN %ls", array('Joe', 'Frank'));
|
||||
```
|
||||
|
||||
|
||||
### Simple inserts
|
||||
@@ -98,52 +132,36 @@ Using MySQL's INSERT should not be more complicated than passing in an
|
||||
associative array. MeekroDB also simplifies many related commands, including
|
||||
the useful and bizarre INSERT .. ON DUPLICATE UPDATE command. PDO does none of this.
|
||||
|
||||
DB::insert('accounts', array('username' => 'John', 'password' => 'whatever'));
|
||||
|
||||
### Focus on the goal, not the task
|
||||
Want to do INSERT yourself rather than relying on DB::insert()?
|
||||
It's dead simple. I don't even want to think about how many lines
|
||||
you'd need to pull this off in PDO.
|
||||
|
||||
// Insert 2 rows at once
|
||||
DB::query("INSERT INTO %b %lb VALUES %ll?", 'accounts',
|
||||
array('username', 'password', 'last_login_timestamp'),
|
||||
array(
|
||||
array('Joe', 'joes_password', new DateTime('yesterday')),
|
||||
array('Frank', 'franks_password', new DateTime('last Monday'))
|
||||
)
|
||||
);
|
||||
```php
|
||||
DB::insert('accounts', array('username' => 'John', 'password' => 'whatever'));
|
||||
```
|
||||
|
||||
### Nested transactions
|
||||
MySQL's SAVEPOINT commands lets you create nested transactions, but only
|
||||
if you keep track of SAVEPOINT ids yourself. MeekroDB does this for you,
|
||||
so you can have nested transactions with no complexity or learning curve.
|
||||
|
||||
DB::$nested_transactions = true;
|
||||
DB::startTransaction(); // outer transaction
|
||||
// .. some queries..
|
||||
$depth = DB::startTransaction(); // inner transaction
|
||||
echo $depth . 'transactions are currently active'; // 2
|
||||
```php
|
||||
DB::$nested_transactions = true;
|
||||
DB::startTransaction(); // outer transaction
|
||||
// .. some queries..
|
||||
$depth = DB::startTransaction(); // inner transaction
|
||||
echo $depth . 'transactions are currently active'; // 2
|
||||
|
||||
// .. some queries..
|
||||
DB::commit(); // commit inner transaction
|
||||
// .. some queries..
|
||||
DB::commit(); // commit outer transaction
|
||||
// .. some queries..
|
||||
DB::commit(); // commit inner transaction
|
||||
// .. some queries..
|
||||
DB::commit(); // commit outer transaction
|
||||
```
|
||||
|
||||
### Flexible error and success handlers
|
||||
Set your own custom function run on errors, or on every query that succeeds.
|
||||
You can easily have separate error handling behavior for the dev and live
|
||||
versions of your application. Want to count up all your queries and their
|
||||
runtime? Just add a new success handler.
|
||||
### Flexible debug logging and error handling
|
||||
You can log all queries (and any errors they produce) to a file for debugging purposes. You can also add hooks that let you run your own functions at any point in the query handling process.
|
||||
|
||||
### More about MeekroDB's design philosophy: http://www.meekro.com/beliefs.php
|
||||
|
||||
My Other Projects
|
||||
========
|
||||
A little shameless self-promotion!
|
||||
|
||||
* [Ark Server Hosting](https://arkservers.io) -- Ark: Survival Evolved server hosting by ArkServers.io!
|
||||
* [7 Days To Die Server Hosting](https://arkservers.io/7days) -- 7 Days to Die server hosting by ArkServers.io!
|
||||
* [Best Minecraft Server Hosting](https://bestminecraft.org) -- Ranking and recommendations for minecraft server hosting!
|
||||
* [ChunkHost](https://chunkhost.com) -- VPS Hosting starting at $5/month! We accept bitcoin!
|
||||
* [brooce](https://github.com/SergeyTsalkov/brooce) - Language-agnostic job queue written in Go! Write your jobs in any language, schedule them from any language, run them anywhere!
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "SergeyTsalkov/meekrodb",
|
||||
"name": "sergeytsalkov/meekrodb",
|
||||
"description": "The Simple PHP/MySQL Library",
|
||||
"homepage": "http://www.meekro.com",
|
||||
"support": {
|
||||
@@ -19,7 +19,7 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
||||
898
db.class.php
898
db.class.php
File diff suppressed because it is too large
Load Diff
@@ -28,15 +28,12 @@ class BasicTest extends SimpleTest {
|
||||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
||||
`name` VARCHAR( 255 ) NULL DEFAULT 'blah'
|
||||
) ENGINE = InnoDB");
|
||||
|
||||
$mysqli = DB::get();
|
||||
DB::disconnect();
|
||||
@$this->assert(!$mysqli->server_info);
|
||||
}
|
||||
|
||||
function test_1_5_empty_table() {
|
||||
$counter = DB::queryFirstField("SELECT COUNT(*) FROM accounts");
|
||||
$this->assert($counter === strval(0));
|
||||
$this->assert(DB::lastQuery() === 'SELECT COUNT(*) FROM accounts');
|
||||
|
||||
$row = DB::queryFirstRow("SELECT * FROM accounts");
|
||||
$this->assert($row === null);
|
||||
@@ -100,16 +97,6 @@ class BasicTest extends SimpleTest {
|
||||
$password = DB::queryFirstField("SELECT password FROM accounts WHERE favorite_word IS NULL");
|
||||
$this->assert($password === 'goodbye');
|
||||
|
||||
DB::$usenull = false;
|
||||
DB::insertUpdate('accounts', array(
|
||||
'id' => 3,
|
||||
'favorite_word' => null,
|
||||
));
|
||||
|
||||
$password = DB::queryFirstField("SELECT password FROM accounts WHERE favorite_word=%s AND favorite_word=%s", null, '');
|
||||
$this->assert($password === 'goodbye');
|
||||
|
||||
DB::$usenull = true;
|
||||
DB::insertUpdate('accounts', array(
|
||||
'id' => 3,
|
||||
'favorite_word' => null,
|
||||
@@ -161,10 +148,12 @@ class BasicTest extends SimpleTest {
|
||||
$results = DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert(count($results) === 3);
|
||||
|
||||
$columnlist = DB::columnList('accounts');
|
||||
$this->assert(count($columnlist) === 8);
|
||||
$this->assert($columnlist[0] === 'id');
|
||||
$this->assert($columnlist[5] === 'height');
|
||||
$columnList = DB::columnList('accounts');
|
||||
$columnKeys = array_keys($columnList);
|
||||
$this->assert(count($columnList) === 8);
|
||||
$this->assert($columnList['id']['type'] == 'int(11)');
|
||||
$this->assert($columnList['height']['type'] == 'double');
|
||||
$this->assert($columnKeys[5] == 'height');
|
||||
|
||||
$tablelist = DB::tableList();
|
||||
$this->assert(count($tablelist) === 3);
|
||||
@@ -174,6 +163,12 @@ class BasicTest extends SimpleTest {
|
||||
$tablelist = DB::tableList(DB::$dbName);
|
||||
$this->assert(count($tablelist) === 3);
|
||||
$this->assert($tablelist[0] === 'accounts');
|
||||
|
||||
$date = DB::queryFirstField("SELECT DATE_FORMAT(birthday, '%%m/%%d/%%Y') FROM accounts WHERE username=%s", "Charlie's Friend");
|
||||
$this->assert($date === '09/10/2000');
|
||||
|
||||
$date = DB::queryFirstField("SELECT DATE_FORMAT('2009-10-04 22:23:00', '%m/%d/%Y')");;
|
||||
$this->assert($date === '10/04/2009');
|
||||
}
|
||||
|
||||
function test_4_1_query() {
|
||||
@@ -283,10 +278,13 @@ class BasicTest extends SimpleTest {
|
||||
|
||||
$columns = DB::columnList('store data');
|
||||
$this->assert(count($columns) === 2);
|
||||
$this->assert($columns[1] === 'picture');
|
||||
$this->assert($columns['picture']['type'] === 'blob');
|
||||
$this->assert($columns['picture']['null'] === 'YES');
|
||||
$this->assert($columns['picture']['key'] === '');
|
||||
$this->assert($columns['picture']['default'] === NULL);
|
||||
$this->assert($columns['picture']['extra'] === '');
|
||||
|
||||
|
||||
$smile = file_get_contents('smile1.jpg');
|
||||
$smile = file_get_contents(__DIR__ . '/smile1.jpg');
|
||||
DB::insert('store data', array(
|
||||
'picture' => $smile,
|
||||
));
|
||||
@@ -431,6 +429,16 @@ class BasicTest extends SimpleTest {
|
||||
$this->assert($count === '0');
|
||||
}
|
||||
|
||||
function test_10_parse() {
|
||||
$parsed_query = DB::parse("SELECT * FROM %b WHERE id=%i AND name=%s", 'accounts', 5, 'Joe');
|
||||
$correct_query = "SELECT * FROM `accounts` WHERE id=5 AND name='Joe'";
|
||||
$this->assert($parsed_query === $correct_query);
|
||||
|
||||
$parsed_query = DB::parse("SELECT DATE_FORMAT(birthday, '%%Y-%%M-%%d %%h:%%i:%%s') AS mydate FROM accounts WHERE id=%i", 5);
|
||||
$correct_query = "SELECT DATE_FORMAT(birthday, '%Y-%M-%d %h:%i:%s') AS mydate FROM accounts WHERE id=5";
|
||||
$this->assert($parsed_query === $correct_query);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function my_debug_handler($params) {
|
||||
global $debug_callback_worked;
|
||||
if (substr_count($params['query'], 'SELECT')) $debug_callback_worked = 1;
|
||||
}
|
||||
|
||||
class ErrorTest extends SimpleTest {
|
||||
function test_1_error_handler() {
|
||||
global $error_callback_worked, $static_error_callback_worked, $nonstatic_error_callback_worked;
|
||||
|
||||
DB::$error_handler = 'new_error_callback';
|
||||
DB::query("SELET * FROM accounts");
|
||||
$this->assert($error_callback_worked === 1);
|
||||
|
||||
DB::$error_handler = array('ErrorTest', '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);
|
||||
|
||||
}
|
||||
|
||||
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_2_exception_catch() {
|
||||
$dbname = DB::$dbName;
|
||||
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("`$dbname`.`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);
|
||||
}
|
||||
|
||||
function test_3_debugmode_handler() {
|
||||
global $debug_callback_worked;
|
||||
|
||||
DB::debugMode('my_debug_handler');
|
||||
DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
|
||||
$this->assert($debug_callback_worked === 1);
|
||||
|
||||
DB::debugMode(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
class ErrorTest_53 extends SimpleTest {
|
||||
function test_1_error_handler() {
|
||||
global $anonymous_error_callback_worked;
|
||||
|
||||
DB::$throw_exception_on_error = false;
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
class HelperTest extends SimpleTest {
|
||||
function test_1_verticalslice() {
|
||||
$all = DB::query("SELECT * FROM accounts ORDER BY id ASC");
|
||||
$names = DBHelper::verticalSlice($all, 'username');
|
||||
$this->assert(count($names) === 5);
|
||||
$this->assert($names[0] === 'Abe');
|
||||
|
||||
$ages = DBHelper::verticalSlice($all, 'age', 'username');
|
||||
$this->assert(count($ages) === 5);
|
||||
$this->assert($ages['Abe'] === '700');
|
||||
}
|
||||
|
||||
function test_2_reindex() {
|
||||
$all = DB::query("SELECT * FROM accounts ORDER BY id ASC");
|
||||
$names = DBHelper::reIndex($all, 'username');
|
||||
$this->assert(count($names) === 5);
|
||||
$this->assert($names['Bart']['username'] === 'Bart');
|
||||
$this->assert($names['Bart']['age'] === '15');
|
||||
|
||||
$names = DBHelper::reIndex($all, 'username', 'age');
|
||||
$this->assert($names['Bart']['15']['username'] === 'Bart');
|
||||
$this->assert($names['Bart']['15']['age'] === '15');
|
||||
}
|
||||
|
||||
function test_3_empty() {
|
||||
$none = DB::query("SELECT * FROM accounts WHERE username=%s", 'doesnotexist');
|
||||
$this->assert(is_array($none) && count($none) === 0);
|
||||
$names = DBHelper::verticalSlice($none, 'username', 'age');
|
||||
$this->assert(is_array($names) && count($names) === 0);
|
||||
|
||||
$names_other = DBHelper::reIndex($none, 'username', 'age');
|
||||
$this->assert(is_array($names_other) && count($names_other) === 0);
|
||||
}
|
||||
|
||||
function test_4_null() {
|
||||
DB::query("UPDATE accounts SET password = NULL WHERE username=%s", 'Bart');
|
||||
|
||||
$all = DB::query("SELECT * FROM accounts ORDER BY id ASC");
|
||||
$ages = DBHelper::verticalSlice($all, 'age', 'password');
|
||||
$this->assert(count($ages) === 5);
|
||||
$this->assert($ages[''] === '15');
|
||||
|
||||
$passwords = DBHelper::reIndex($all, 'password');
|
||||
$this->assert(count($passwords) === 5);
|
||||
$this->assert($passwords['']['username'] === 'Bart');
|
||||
$this->assert($passwords['']['password'] === NULL);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
287
simpletest/HookTest.php
Normal file
287
simpletest/HookTest.php
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
function my_error_handler($hash) {
|
||||
global $error_callback_worked;
|
||||
if (substr_count($hash['error'], 'You have an error in your SQL syntax')) $error_callback_worked = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
function my_success_handler($hash) {
|
||||
global $debug_callback_worked;
|
||||
if (substr_count($hash['query'], 'SELECT')) $debug_callback_worked = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class HookTest extends SimpleTest {
|
||||
static function static_error_callback($hash) {
|
||||
global $static_error_callback_worked;
|
||||
if (substr_count($hash['error'], 'You have an error in your SQL syntax')) $static_error_callback_worked = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
function nonstatic_error_callback($hash) {
|
||||
global $nonstatic_error_callback_worked;
|
||||
if (substr_count($hash['error'], 'You have an error in your SQL syntax')) $nonstatic_error_callback_worked = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
function test_1_error_handler() {
|
||||
global $error_callback_worked, $static_error_callback_worked, $nonstatic_error_callback_worked;
|
||||
|
||||
DB::addHook('run_failed', 'my_error_handler');
|
||||
DB::query("SELET * FROM accounts");
|
||||
$this->assert($error_callback_worked === 1);
|
||||
DB::removeHooks('run_failed');
|
||||
|
||||
DB::addHook('run_failed', array('HookTest', 'static_error_callback'));
|
||||
DB::query("SELET * FROM accounts");
|
||||
$this->assert($static_error_callback_worked === 1);
|
||||
DB::removeHooks('run_failed');
|
||||
|
||||
DB::addHook('run_failed', array($this, 'nonstatic_error_callback'));
|
||||
DB::query("SELET * FROM accounts");
|
||||
$this->assert($nonstatic_error_callback_worked === 1);
|
||||
DB::removeHooks('run_failed');
|
||||
}
|
||||
|
||||
function test_2_exception_catch() {
|
||||
$dbname = DB::$dbName;
|
||||
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);
|
||||
$this->assert(DB::lastQuery() === 'SELET * FROM accounts');
|
||||
|
||||
try {
|
||||
DB::insert("`$dbname`.`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);
|
||||
}
|
||||
|
||||
function test_3_success_handler() {
|
||||
global $debug_callback_worked;
|
||||
|
||||
DB::addHook('run_success', 'my_success_handler');
|
||||
DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert($debug_callback_worked === 1);
|
||||
DB::removeHooks('run_success');
|
||||
}
|
||||
|
||||
function test_4_error_handler() {
|
||||
global $anonymous_error_callback_worked;
|
||||
|
||||
$error_handler = function($hash) {
|
||||
global $anonymous_error_callback_worked;
|
||||
if (substr_count($hash['error'], 'You have an error in your SQL syntax')) {
|
||||
$anonymous_error_callback_worked = 1;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
DB::addHook('run_failed', $error_handler);
|
||||
DB::query("SELET * FROM accounts");
|
||||
$this->assert($anonymous_error_callback_worked === 1);
|
||||
DB::removeHooks('run_failed');
|
||||
}
|
||||
|
||||
function test_5_post_run_success() {
|
||||
$callback_worked = false;
|
||||
|
||||
$fn = function($hash) use (&$callback_worked) {
|
||||
if (!isset($hash['error']) && !isset($hash['exception'])) {
|
||||
$callback_worked = true;
|
||||
}
|
||||
};
|
||||
|
||||
DB::addHook('post_run', $fn);
|
||||
DB::query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert($callback_worked);
|
||||
DB::removeHooks('post_run');
|
||||
}
|
||||
|
||||
function test_6_post_run_failed() {
|
||||
$callback_worked = false;
|
||||
|
||||
$fn = function($hash) use (&$callback_worked) {
|
||||
if ($hash['error'] && $hash['exception']) {
|
||||
$expected_query = "SELEC * FROM accounts WHERE username!='Charlie\'s Friend'";
|
||||
$expected_error = "error in your SQL syntax";
|
||||
if ($hash['exception']->getQuery() == $expected_query && substr_count($hash['error'], $expected_error)) {
|
||||
$callback_worked = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DB::addHook('post_run', $fn);
|
||||
DB::addHook('run_failed', function() { return false; }); // disable exception throwing
|
||||
DB::query("SELEC * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert($callback_worked);
|
||||
DB::removeHooks('post_run');
|
||||
DB::removeHooks('run_failed');
|
||||
}
|
||||
|
||||
function test_7_pre_run() {
|
||||
$callback_worked = false;
|
||||
|
||||
$fn = function($args) { return str_replace('SLCT', 'SELET', $args['query']); };
|
||||
$fn2 = function($args) { return str_replace('SELET', 'SELECT', $args['query']); };
|
||||
$fn3 = function($args) use (&$callback_worked) { $callback_worked = true; };
|
||||
|
||||
DB::addHook('pre_run', $fn);
|
||||
DB::addHook('pre_run', $fn2);
|
||||
$last_hook = DB::addHook('pre_run', $fn3);
|
||||
$results = DB::query("SLCT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert(count($results) == 4);
|
||||
$this->assert($callback_worked);
|
||||
|
||||
$callback_worked = false;
|
||||
DB::removeHook('pre_run', $last_hook);
|
||||
$results = DB::query("SLCT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert(count($results) == 4);
|
||||
$this->assert(!$callback_worked);
|
||||
|
||||
DB::removeHooks('pre_run');
|
||||
}
|
||||
|
||||
function test_8_pre_parse() {
|
||||
$callback_worked = false;
|
||||
|
||||
$fn = function($args) {
|
||||
$args['query'] = str_replace('SLCT', 'SELECT', $args['query']);
|
||||
return array($args['query'], $args['args']);
|
||||
};
|
||||
$fn2 = function($args) {
|
||||
$args['args'][0] = '1ofmany';
|
||||
return array($args['query'], $args['args']);
|
||||
};
|
||||
$fn3 = function() use (&$callback_worked) {
|
||||
$callback_worked = true;
|
||||
};
|
||||
|
||||
DB::addHook('pre_parse', $fn);
|
||||
DB::addHook('pre_parse', $fn2);
|
||||
DB::addHook('pre_parse', $fn3);
|
||||
$row = DB::queryFirstRow("SLCT * FROM accounts WHERE username=%s", "asdf");
|
||||
$this->assert($row['password'] == 'something');
|
||||
$this->assert($callback_worked);
|
||||
DB::removeHooks('pre_parse');
|
||||
}
|
||||
|
||||
function test_9_enough_args() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id=%i AND username=%s", 1);
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == 'Expected 2 args, but only got 1!') {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_10_named_keys_present() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id=%i_id AND username=%s_username", array('username' => 'asdf'));
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "Couldn't find named arg id!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_11_expect_array() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id IN %li", 5);
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "Expected an array for arg 0 but didn't get one!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_12_named_keys_without_array() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id=%i_named", 1);
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "If you use named args, you must pass an assoc array of args!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_13_mix_named_numbered_args() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id=%i_named AND username=%s", array('named' => 1));
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "You can't mix named and numbered args!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_14_arrays_not_empty() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id IN %li", array());
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "Arg 0 array can't be empty!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
function test_15_named_array_not_empty() {
|
||||
$error_worked = false;
|
||||
|
||||
try {
|
||||
DB::query("SELECT * FROM accounts WHERE id IN %li_ids", array('ids' => array()));
|
||||
} catch (MeekroDBException $e) {
|
||||
if ($e->getMessage() == "Arg ids array can't be empty!") {
|
||||
$error_worked = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($error_worked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -117,10 +117,12 @@ class ObjectTest extends SimpleTest {
|
||||
$results = $this->mdb->query("SELECT * FROM accounts WHERE username!=%s", "Charlie's Friend");
|
||||
$this->assert(count($results) === 2);
|
||||
|
||||
$columnlist = $this->mdb->columnList('accounts');
|
||||
$this->assert(count($columnlist) === 6);
|
||||
$this->assert($columnlist[0] === 'id');
|
||||
$this->assert($columnlist[4] === 'height');
|
||||
$columnList = $this->mdb->columnList('accounts');
|
||||
$columnKeys = array_keys($columnList);
|
||||
$this->assert(count($columnList) === 6);
|
||||
$this->assert($columnList['id']['type'] == 'int(11)');
|
||||
$this->assert($columnList['height']['type'] == 'double');
|
||||
$this->assert($columnKeys[4] == 'height');
|
||||
|
||||
$tablelist = $this->mdb->tableList();
|
||||
$this->assert(count($tablelist) === 1);
|
||||
@@ -215,7 +217,7 @@ class ObjectTest extends SimpleTest {
|
||||
) ENGINE = InnoDB");
|
||||
|
||||
|
||||
$smile = file_get_contents('smile1.jpg');
|
||||
$smile = file_get_contents(__DIR__ . '/smile1.jpg');
|
||||
$this->mdb->insert('storedata', array(
|
||||
'picture' => $smile,
|
||||
));
|
||||
|
||||
64
simpletest/WalkTest.php
Normal file
64
simpletest/WalkTest.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
class WalkTest extends SimpleTest {
|
||||
function test_1_walk() {
|
||||
$Walk = DB::queryWalk("SELECT * FROM accounts");
|
||||
|
||||
$results = array();
|
||||
while ($row = $Walk->next()) {
|
||||
$results[] = $row;
|
||||
}
|
||||
|
||||
$this->assert(count($results) == 8);
|
||||
$this->assert($results[7]['username'] == 'vookoo');
|
||||
}
|
||||
|
||||
function test_2_walk_empty() {
|
||||
$Walk = DB::queryWalk("SELECT * FROM accounts WHERE id>100");
|
||||
|
||||
$results = array();
|
||||
while ($row = $Walk->next()) {
|
||||
$results[] = $row;
|
||||
}
|
||||
|
||||
$this->assert(count($results) == 0);
|
||||
}
|
||||
|
||||
function test_3_walk_insert() {
|
||||
$Walk = DB::queryWalk("INSERT INTO profile (id) VALUES (100)");
|
||||
|
||||
$results = array();
|
||||
while ($row = $Walk->next()) {
|
||||
$results[] = $row;
|
||||
}
|
||||
|
||||
$this->assert(count($results) == 0);
|
||||
|
||||
DB::query("DELETE FROM profile WHERE id=100");
|
||||
}
|
||||
|
||||
function test_4_walk_incomplete() {
|
||||
$Walk = DB::queryWalk("SELECT * FROM accounts");
|
||||
$Walk->next();
|
||||
unset($Walk);
|
||||
|
||||
// if $Walk hasn't been properly freed, this will produce an out of sync error
|
||||
DB::query("SELECT * FROM accounts");
|
||||
}
|
||||
|
||||
function test_5_walk_error() {
|
||||
$Walk = DB::queryWalk("SELECT * FROM accounts");
|
||||
$Walk->next();
|
||||
|
||||
try {
|
||||
// this will produce an out of sync error
|
||||
DB::query("SELECT * FROM accounts");
|
||||
} catch (MeekroDBException $e) {
|
||||
if (substr_count($e->getMessage(), 'out of sync')) {
|
||||
$exception_was_caught = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assert($exception_was_caught === 1);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ class WhereClauseTest extends SimpleTest {
|
||||
$where->add('username=%s', 'Bart');
|
||||
$where->add('password=%s', 'hello');
|
||||
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where->text());
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where);
|
||||
$this->assert(count($result) === 1);
|
||||
$this->assert($result[0]['age'] === '15');
|
||||
}
|
||||
@@ -17,7 +17,7 @@ class WhereClauseTest extends SimpleTest {
|
||||
$subclause->add('age=%i', 15);
|
||||
$subclause->add('age=%i', 14);
|
||||
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where->text());
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where);
|
||||
$this->assert(count($result) === 1);
|
||||
$this->assert($result[0]['age'] === '15');
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class WhereClauseTest extends SimpleTest {
|
||||
$subclause->add('username!=%s', 'Bart');
|
||||
$subclause->negateLast();
|
||||
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where->text());
|
||||
$result = DB::query("SELECT * FROM accounts WHERE %l", $where);
|
||||
$this->assert(count($result) === 1);
|
||||
$this->assert($result[0]['age'] === '15');
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ class SimpleTest {
|
||||
debug_print_backtrace();
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function microtime_float()
|
||||
@@ -20,14 +18,11 @@ function microtime_float()
|
||||
return ((float)$usec + (float)$sec);
|
||||
}
|
||||
|
||||
if (phpversion() >= '5.3') $is_php_53 = true;
|
||||
else $is_php_53 = false;
|
||||
|
||||
ini_set('date.timezone', 'America/Los_Angeles');
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
require_once '../db.class.php';
|
||||
include 'test_setup.php'; //test config values go here
|
||||
require_once __DIR__ . '/../db.class.php';
|
||||
require_once __DIR__ . '/test_setup.php'; //test config values go here
|
||||
// WARNING: ALL tables in the database will be dropped before the tests, including non-test related tables.
|
||||
DB::$user = $set_db_user;
|
||||
DB::$password = $set_password;
|
||||
@@ -35,34 +30,27 @@ DB::$dbName = $set_db;
|
||||
DB::$host = $set_host;
|
||||
DB::get(); //connect to mysql
|
||||
|
||||
require_once 'BasicTest.php';
|
||||
require_once 'CallTest.php';
|
||||
require_once 'ObjectTest.php';
|
||||
require_once 'WhereClauseTest.php';
|
||||
require_once 'ErrorTest.php';
|
||||
require_once 'TransactionTest.php';
|
||||
require_once 'HelperTest.php';
|
||||
require_once __DIR__ . '/BasicTest.php';
|
||||
require_once __DIR__ . '/WalkTest.php';
|
||||
require_once __DIR__ . '/CallTest.php';
|
||||
require_once __DIR__ . '/ObjectTest.php';
|
||||
require_once __DIR__ . '/WhereClauseTest.php';
|
||||
require_once __DIR__ . '/HookTest.php';
|
||||
require_once __DIR__ . '/TransactionTest.php';
|
||||
|
||||
$classes_to_test = array(
|
||||
'BasicTest',
|
||||
'WalkTest',
|
||||
'CallTest',
|
||||
'WhereClauseTest',
|
||||
'ObjectTest',
|
||||
'ErrorTest',
|
||||
'HookTest',
|
||||
'TransactionTest',
|
||||
'HelperTest',
|
||||
);
|
||||
|
||||
if ($is_php_53) {
|
||||
require_once 'ErrorTest_53.php';
|
||||
$classes_to_test[] = 'ErrorTest_53';
|
||||
} else {
|
||||
echo "PHP 5.3 not detected, skipping 5.3 tests..\n";
|
||||
}
|
||||
|
||||
$mysql_version = DB::serverVersion();
|
||||
if ($mysql_version >= '5.5') {
|
||||
require_once 'TransactionTest_55.php';
|
||||
require_once __DIR__ . '/TransactionTest_55.php';
|
||||
$classes_to_test[] = 'TransactionTest_55';
|
||||
} else {
|
||||
echo "MySQL 5.5 not available (version is $mysql_version) -- skipping MySQL 5.5 tests\n";
|
||||
|
||||
Reference in New Issue
Block a user