Commit 9026a39c authored by Josh Campbell's avatar Josh Campbell

Merge pull request #198 from avbdr/master

Bugfixes an features
parents 433ba3bd 0b90f4c9
......@@ -92,6 +92,7 @@ class MysqliDb
protected $password;
protected $db;
protected $port;
protected $charset;
/**
* Is Subquery object
......@@ -106,24 +107,36 @@ class MysqliDb
* @param string $db
* @param int $port
*/
public function __construct($host = NULL, $username = NULL, $password = NULL, $db = NULL, $port = NULL)
public function __construct($host = NULL, $username = NULL, $password = NULL, $db = NULL, $port = NULL, $charset = 'utf8')
{
$this->host = $host;
$isSubQuery = false;
// if params were passed as array
if (is_array ($host)) {
foreach ($host as $key => $val)
$$key = $val;
}
// if host were set as mysqli socket
if (is_object ($host))
$this->_mysqli = $host;
else
$this->host = $host;
$this->username = $username;
$this->password = $password;
$this->db = $db;
if($port == NULL)
$this->port = ini_get ('mysqli.default_port');
else
$this->port = $port;
$this->port = $port;
$this->charset = $charset;
if ($host == null && $username == null && $db == null) {
if ($isSubQuery) {
$this->isSubQuery = true;
return;
}
// for subqueries we do not need database connection and redefine root instance
$this->connect();
if (!is_object ($host))
$this->connect();
$this->setPrefix();
self::$_instance = $this;
}
......@@ -137,10 +150,14 @@ class MysqliDb
if ($this->isSubQuery)
return;
if (empty ($this->host))
die ('Mysql host is not set');
$this->_mysqli = new mysqli ($this->host, $this->username, $this->password, $this->db, $this->port)
or die('There was a problem connecting to the database');
$this->_mysqli->set_charset ('utf8');
if ($this->charset)
$this->_mysqli->set_charset ($this->charset);
}
/**
* A method of returning the static instance to allow access to the
......@@ -427,12 +444,14 @@ class MysqliDb
{
$allowedTypes = array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER');
$joinType = strtoupper (trim ($joinType));
$joinTable = filter_var($joinTable, FILTER_SANITIZE_STRING);
if ($joinType && !in_array ($joinType, $allowedTypes))
die ('Wrong JOIN type: '.$joinType);
$this->_join[$joinType . " JOIN " . self::$_prefix . $joinTable] = $joinCondition;
if (!is_object ($joinTable))
$joinTable = self::$_prefix . filter_var($joinTable, FILTER_SANITIZE_STRING);
$this->_join[] = Array ($joinType, $joinTable, $joinCondition);
return $this;
}
......@@ -587,7 +606,7 @@ class MysqliDb
$subQuery = $value->getSubQuery ();
$this->_bindParams ($subQuery['params']);
return " " . $operator . " (" . $subQuery['query'] . ")";
return " " . $operator . " (" . $subQuery['query'] . ") " . $subQuery['alias'];
}
/**
......@@ -679,8 +698,16 @@ class MysqliDb
if (empty ($this->_join))
return;
foreach ($this->_join as $prop => $value)
$this->_query .= " " . $prop . " on " . $value;
foreach ($this->_join as $data) {
list ($joinType, $joinTable, $joinCondition) = $data;
if (is_object ($joinTable))
$joinStr = $this->_buildPair ("", $joinTable);
else
$joinStr = $joinTable;
$this->_query .= " " . $joinType. " JOIN " . $joinStr ." on " . $joinCondition;
}
}
/**
......@@ -946,7 +973,8 @@ class MysqliDb
array_shift ($this->_bindParams);
$val = Array ('query' => $this->_query,
'params' => $this->_bindParams
'params' => $this->_bindParams,
'alias' => $this->host
);
$this->reset();
return $val;
......@@ -1031,9 +1059,9 @@ class MysqliDb
/**
* Method creates new mysqlidb object for a subquery generation
*/
public static function subQuery()
public static function subQuery($subQueryAlias = "")
{
return new MysqliDb();
return new MysqliDb (Array('host' => $subQueryAlias, 'isSubQuery' => true));
}
/**
......@@ -1043,7 +1071,9 @@ class MysqliDb
*/
public function copy ()
{
return clone $this;
$copy = unserialize (serialize ($this));
$copy->_mysqli = $this->_mysqli;
return $copy;
}
/**
......
......@@ -25,12 +25,29 @@ To utilize this class, first import MysqliDb.php into your project, and require
require_once ('MysqliDb.php');
```
After that, create a new instance of the class.
Simple initialization with utf8 charset by default:
```php
$db = new MysqliDb ('host', 'username', 'password', 'databaseName');
```
Advanced initialization. If no charset should be set charset, set it to null
```php
$db = new Mysqlidb (Array (
'host' => 'host',
'username' => 'username',
'password' => 'password',
'db'=> 'databaseName',
'port' => 3306,
'charset' => 'utf8'));
```
port and charset params are optional.
Reuse already connected mysqli:
```php
$mysqli = new mysqli ('host', 'username', 'password', 'databaseName');
$db = new Mysqlidb ($mysqli);
```
Its also possible to set a table prefix:
```php
$db->setPrefix ('my_');
......@@ -301,12 +318,26 @@ $customers = $db->copy ();
$res = $customers->get ("customers", Array (10, 10));
// SELECT * FROM customers where agentId = 10 and active = 1 limit 10, 10
$res = $db->getOne ("customers", "count(id) as cnt");
echo "total records found: " . $res['cnt'];
$cnt = $db->getValue ("customers", "count(id)");
echo "total records found: " . $cnt;
// SELECT count(id) FROM users where agentId = 10 and active = 1
```
### Subqueries
Subquery init
Subquery init without an alias to use in inserts/updates/where Eg. (select * from users)
```php
$sq = $db->subQuery();
$sq->get ("users");
```
A subquery with an alias specified to use in JOINs . Eg. (select * from users) sq
```php
$sq = $db->subQuery("sq");
$sq->get ("users");
```
Subquery in selects:
```php
$ids = $db->subQuery ();
......@@ -333,6 +364,18 @@ $id = $db->insert ("products", $data);
// Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW());
```
Subquery in joins:
```php
$usersQ = $db->subQuery ("u");
$usersQ->where ("active", 1);
$usersQ->get ("users");
$db->join($usersQ, "p.userId=u.id", "LEFT");
$products = $db->get ("products p", null, "u.login, p.productName");
print_r ($products);
// SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id;
```
###EXISTS / NOT EXISTS condition
```php
$sub = $db->subQuery();
......
......@@ -5,6 +5,17 @@ error_reporting(E_ALL);
$db = new Mysqlidb('localhost', 'root', '', 'testdb');
if(!$db) die("Database error");
$db = new Mysqlidb(Array (
'host' => 'localhost',
'username' => 'root',
'password' => '',
'db'=> 'testdb',
'charset' => null));
if(!$db) die("Database error");
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
$db = new Mysqlidb($mysqli);
$prefix = 't_';
$db->setPrefix($prefix);
......@@ -142,6 +153,10 @@ if ($db->count != 1) {
exit;
}
$q = "drop table {$prefix}test;";
$db->rawQuery($q);
$db->orderBy("id","asc");
$users = $db->get("users");
if ($db->count != 3) {
......@@ -242,7 +257,7 @@ if ($db->count != 2) {
echo "Invalid users count on where() with between";
exit;
}
///
$db->where ("id", 2);
$db->orWhere ("customerId", 11);
$r = $db->get("users");
......@@ -250,14 +265,14 @@ if ($db->count != 2) {
echo "Invalid users count on orWhere()";
exit;
}
///
$db->where ("lastName", NULL, '<=>');
$r = $db->get("users");
if ($db->count != 1) {
echo "Invalid users count on null where()";
exit;
}
///
$db->join("users u", "p.userId=u.id", "LEFT");
$db->where("u.login",'user2');
$db->orderBy("CONCAT(u.login, u.firstName)");
......@@ -266,7 +281,7 @@ if ($db->count != 2) {
echo "Invalid products count on join ()";
exit;
}
///
$db->where("id = ? or id = ?", Array(1,2));
$res = $db->get ("users");
if ($db->count != 2) {
......@@ -274,24 +289,58 @@ if ($db->count != 2) {
exit;
}
///
$db->where("id = 1 or id = 2");
$res = $db->get ("users");
if ($db->count != 2) {
echo "Invalid users count on select with multiple params";
exit;
}
///
$usersQ = $db->subQuery();
$usersQ->where ("login", "user2");
$usersQ->getOne ("users", "id");
$db2 = $db->copy();
$db2->where ("userId", $usersQ);
$cnt = $db2->getValue ("products", "count(id)");
$db->where ("userId", $usersQ);
$cnt = $db->getValue ("products", "count(id)");
if ($cnt != 2) {
echo "Invalid select result with subquery";
exit;
}
///
$dbi_sub = $db->subQuery();
$dbi_sub->where ('active', 1);
$dbi_sub->get ('users', null, 'id');
$db->where ('id', $dbi_sub, 'IN');
$cnt = $db->copy();
$c = $cnt->getValue ('users', "COUNT(id)");
if ($c != 3) {
echo "copy with subquery count failed";
exit;
}
$data = $db->get('users');
if (count($data) != 3) {
echo "copy with subquery data count failed";
exit;
}
///
$usersQ = $db->subQuery ("u");
$usersQ->where ("active", 1);
$usersQ->get("users");
$db->join($usersQ, "p.userId=u.id", "LEFT");
$products = $db->get ("products p", null, "u.login, p.productName");
if ($products[2]['login'] != 'user1' || $products[2]['productName'] != 'product3') {
echo "invalid join with subquery";
exit;
}
if ($db->count != 5) {
echo "invalid join with subquery count";
exit;
}
///
//TODO: insert test
$db->delete("users");
$db->get("users");
......@@ -301,9 +350,6 @@ if ($db->count != 0) {
}
$db->delete("products");
$q = "drop table {$prefix}test;";
$db->rawQuery($q);
echo "All done";
//print_r($db->rawQuery("CALL simpleproc(?)",Array("test")));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment