Skip to content

Commit 9026a39

Browse files
committed
Merge pull request #198 from avbdr/master
Bugfixes an features
2 parents 433ba3b + 0b90f4c commit 9026a39

File tree

3 files changed

+152
-33
lines changed

3 files changed

+152
-33
lines changed

MysqliDb.php

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class MysqliDb
9292
protected $password;
9393
protected $db;
9494
protected $port;
95+
protected $charset;
9596

9697
/**
9798
* Is Subquery object
@@ -106,24 +107,36 @@ class MysqliDb
106107
* @param string $db
107108
* @param int $port
108109
*/
109-
public function __construct($host = NULL, $username = NULL, $password = NULL, $db = NULL, $port = NULL)
110+
public function __construct($host = NULL, $username = NULL, $password = NULL, $db = NULL, $port = NULL, $charset = 'utf8')
110111
{
111-
$this->host = $host;
112+
$isSubQuery = false;
113+
114+
// if params were passed as array
115+
if (is_array ($host)) {
116+
foreach ($host as $key => $val)
117+
$$key = $val;
118+
}
119+
// if host were set as mysqli socket
120+
if (is_object ($host))
121+
$this->_mysqli = $host;
122+
else
123+
$this->host = $host;
124+
112125
$this->username = $username;
113126
$this->password = $password;
114127
$this->db = $db;
115-
if($port == NULL)
116-
$this->port = ini_get ('mysqli.default_port');
117-
else
118-
$this->port = $port;
128+
$this->port = $port;
129+
$this->charset = $charset;
119130

120-
if ($host == null && $username == null && $db == null) {
131+
if ($isSubQuery) {
121132
$this->isSubQuery = true;
122133
return;
123134
}
124135

125136
// for subqueries we do not need database connection and redefine root instance
126-
$this->connect();
137+
if (!is_object ($host))
138+
$this->connect();
139+
127140
$this->setPrefix();
128141
self::$_instance = $this;
129142
}
@@ -137,10 +150,14 @@ public function connect()
137150
if ($this->isSubQuery)
138151
return;
139152

153+
if (empty ($this->host))
154+
die ('Mysql host is not set');
155+
140156
$this->_mysqli = new mysqli ($this->host, $this->username, $this->password, $this->db, $this->port)
141157
or die('There was a problem connecting to the database');
142158

143-
$this->_mysqli->set_charset ('utf8');
159+
if ($this->charset)
160+
$this->_mysqli->set_charset ($this->charset);
144161
}
145162
/**
146163
* A method of returning the static instance to allow access to the
@@ -427,12 +444,14 @@ public function join($joinTable, $joinCondition, $joinType = '')
427444
{
428445
$allowedTypes = array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER');
429446
$joinType = strtoupper (trim ($joinType));
430-
$joinTable = filter_var($joinTable, FILTER_SANITIZE_STRING);
431447

432448
if ($joinType && !in_array ($joinType, $allowedTypes))
433449
die ('Wrong JOIN type: '.$joinType);
434450

435-
$this->_join[$joinType . " JOIN " . self::$_prefix . $joinTable] = $joinCondition;
451+
if (!is_object ($joinTable))
452+
$joinTable = self::$_prefix . filter_var($joinTable, FILTER_SANITIZE_STRING);
453+
454+
$this->_join[] = Array ($joinType, $joinTable, $joinCondition);
436455

437456
return $this;
438457
}
@@ -587,7 +606,7 @@ protected function _buildPair ($operator, $value) {
587606
$subQuery = $value->getSubQuery ();
588607
$this->_bindParams ($subQuery['params']);
589608

590-
return " " . $operator . " (" . $subQuery['query'] . ")";
609+
return " " . $operator . " (" . $subQuery['query'] . ") " . $subQuery['alias'];
591610
}
592611

593612
/**
@@ -679,8 +698,16 @@ protected function _buildJoin () {
679698
if (empty ($this->_join))
680699
return;
681700

682-
foreach ($this->_join as $prop => $value)
683-
$this->_query .= " " . $prop . " on " . $value;
701+
foreach ($this->_join as $data) {
702+
list ($joinType, $joinTable, $joinCondition) = $data;
703+
704+
if (is_object ($joinTable))
705+
$joinStr = $this->_buildPair ("", $joinTable);
706+
else
707+
$joinStr = $joinTable;
708+
709+
$this->_query .= " " . $joinType. " JOIN " . $joinStr ." on " . $joinCondition;
710+
}
684711
}
685712

686713
/**
@@ -946,7 +973,8 @@ public function getSubQuery () {
946973

947974
array_shift ($this->_bindParams);
948975
$val = Array ('query' => $this->_query,
949-
'params' => $this->_bindParams
976+
'params' => $this->_bindParams,
977+
'alias' => $this->host
950978
);
951979
$this->reset();
952980
return $val;
@@ -1031,9 +1059,9 @@ public function func ($expr, $bindParams = null) {
10311059
/**
10321060
* Method creates new mysqlidb object for a subquery generation
10331061
*/
1034-
public static function subQuery()
1062+
public static function subQuery($subQueryAlias = "")
10351063
{
1036-
return new MysqliDb();
1064+
return new MysqliDb (Array('host' => $subQueryAlias, 'isSubQuery' => true));
10371065
}
10381066

10391067
/**
@@ -1043,7 +1071,9 @@ public static function subQuery()
10431071
*/
10441072
public function copy ()
10451073
{
1046-
return clone $this;
1074+
$copy = unserialize (serialize ($this));
1075+
$copy->_mysqli = $this->_mysqli;
1076+
return $copy;
10471077
}
10481078

10491079
/**

readme.md

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,29 @@ To utilize this class, first import MysqliDb.php into your project, and require
2525
require_once ('MysqliDb.php');
2626
```
2727

28-
After that, create a new instance of the class.
29-
28+
Simple initialization with utf8 charset by default:
3029
```php
3130
$db = new MysqliDb ('host', 'username', 'password', 'databaseName');
3231
```
3332

33+
Advanced initialization. If no charset should be set charset, set it to null
34+
```php
35+
$db = new Mysqlidb (Array (
36+
'host' => 'host',
37+
'username' => 'username',
38+
'password' => 'password',
39+
'db'=> 'databaseName',
40+
'port' => 3306,
41+
'charset' => 'utf8'));
42+
```
43+
port and charset params are optional.
44+
45+
Reuse already connected mysqli:
46+
```php
47+
$mysqli = new mysqli ('host', 'username', 'password', 'databaseName');
48+
$db = new Mysqlidb ($mysqli);
49+
```
50+
3451
Its also possible to set a table prefix:
3552
```php
3653
$db->setPrefix ('my_');
@@ -301,12 +318,26 @@ $customers = $db->copy ();
301318
$res = $customers->get ("customers", Array (10, 10));
302319
// SELECT * FROM customers where agentId = 10 and active = 1 limit 10, 10
303320

304-
$res = $db->getOne ("customers", "count(id) as cnt");
305-
echo "total records found: " . $res['cnt'];
321+
$cnt = $db->getValue ("customers", "count(id)");
322+
echo "total records found: " . $cnt;
306323
// SELECT count(id) FROM users where agentId = 10 and active = 1
307324
```
308325

309326
### Subqueries
327+
Subquery init
328+
329+
Subquery init without an alias to use in inserts/updates/where Eg. (select * from users)
330+
```php
331+
$sq = $db->subQuery();
332+
$sq->get ("users");
333+
```
334+
335+
A subquery with an alias specified to use in JOINs . Eg. (select * from users) sq
336+
```php
337+
$sq = $db->subQuery("sq");
338+
$sq->get ("users");
339+
```
340+
310341
Subquery in selects:
311342
```php
312343
$ids = $db->subQuery ();
@@ -333,6 +364,18 @@ $id = $db->insert ("products", $data);
333364
// Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW());
334365
```
335366

367+
Subquery in joins:
368+
```php
369+
$usersQ = $db->subQuery ("u");
370+
$usersQ->where ("active", 1);
371+
$usersQ->get ("users");
372+
373+
$db->join($usersQ, "p.userId=u.id", "LEFT");
374+
$products = $db->get ("products p", null, "u.login, p.productName");
375+
print_r ($products);
376+
// SELECT u.login, p.productName FROM products p LEFT JOIN (SELECT * FROM t_users WHERE active = 1) u on p.userId=u.id;
377+
```
378+
336379
###EXISTS / NOT EXISTS condition
337380
```php
338381
$sub = $db->subQuery();

tests.php

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@
55
$db = new Mysqlidb('localhost', 'root', '', 'testdb');
66
if(!$db) die("Database error");
77

8+
$db = new Mysqlidb(Array (
9+
'host' => 'localhost',
10+
'username' => 'root',
11+
'password' => '',
12+
'db'=> 'testdb',
13+
'charset' => null));
14+
if(!$db) die("Database error");
15+
16+
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
17+
$db = new Mysqlidb($mysqli);
18+
819
$prefix = 't_';
920
$db->setPrefix($prefix);
1021

@@ -142,6 +153,10 @@ function createTable ($name, $data) {
142153
exit;
143154
}
144155

156+
$q = "drop table {$prefix}test;";
157+
$db->rawQuery($q);
158+
159+
145160
$db->orderBy("id","asc");
146161
$users = $db->get("users");
147162
if ($db->count != 3) {
@@ -242,22 +257,22 @@ function createTable ($name, $data) {
242257
echo "Invalid users count on where() with between";
243258
exit;
244259
}
245-
260+
///
246261
$db->where ("id", 2);
247262
$db->orWhere ("customerId", 11);
248263
$r = $db->get("users");
249264
if ($db->count != 2) {
250265
echo "Invalid users count on orWhere()";
251266
exit;
252267
}
253-
268+
///
254269
$db->where ("lastName", NULL, '<=>');
255270
$r = $db->get("users");
256271
if ($db->count != 1) {
257272
echo "Invalid users count on null where()";
258273
exit;
259274
}
260-
275+
///
261276
$db->join("users u", "p.userId=u.id", "LEFT");
262277
$db->where("u.login",'user2');
263278
$db->orderBy("CONCAT(u.login, u.firstName)");
@@ -266,32 +281,66 @@ function createTable ($name, $data) {
266281
echo "Invalid products count on join ()";
267282
exit;
268283
}
269-
284+
///
270285
$db->where("id = ? or id = ?", Array(1,2));
271286
$res = $db->get ("users");
272287
if ($db->count != 2) {
273288
echo "Invalid users count on select with multiple params";
274289
exit;
275290
}
276291

292+
///
277293
$db->where("id = 1 or id = 2");
278294
$res = $db->get ("users");
279295
if ($db->count != 2) {
280296
echo "Invalid users count on select with multiple params";
281297
exit;
282298
}
283-
299+
///
284300
$usersQ = $db->subQuery();
285301
$usersQ->where ("login", "user2");
286302
$usersQ->getOne ("users", "id");
287303

288-
$db2 = $db->copy();
289-
$db2->where ("userId", $usersQ);
290-
$cnt = $db2->getValue ("products", "count(id)");
304+
$db->where ("userId", $usersQ);
305+
$cnt = $db->getValue ("products", "count(id)");
291306
if ($cnt != 2) {
292307
echo "Invalid select result with subquery";
293308
exit;
294309
}
310+
///
311+
$dbi_sub = $db->subQuery();
312+
$dbi_sub->where ('active', 1);
313+
$dbi_sub->get ('users', null, 'id');
314+
315+
$db->where ('id', $dbi_sub, 'IN');
316+
317+
$cnt = $db->copy();
318+
$c = $cnt->getValue ('users', "COUNT(id)");
319+
if ($c != 3) {
320+
echo "copy with subquery count failed";
321+
exit;
322+
}
323+
$data = $db->get('users');
324+
if (count($data) != 3) {
325+
echo "copy with subquery data count failed";
326+
exit;
327+
}
328+
///
329+
$usersQ = $db->subQuery ("u");
330+
$usersQ->where ("active", 1);
331+
$usersQ->get("users");
332+
333+
$db->join($usersQ, "p.userId=u.id", "LEFT");
334+
$products = $db->get ("products p", null, "u.login, p.productName");
335+
if ($products[2]['login'] != 'user1' || $products[2]['productName'] != 'product3') {
336+
echo "invalid join with subquery";
337+
exit;
338+
}
339+
if ($db->count != 5) {
340+
echo "invalid join with subquery count";
341+
exit;
342+
}
343+
///
295344
//TODO: insert test
296345
$db->delete("users");
297346
$db->get("users");
@@ -301,9 +350,6 @@ function createTable ($name, $data) {
301350
}
302351
$db->delete("products");
303352

304-
$q = "drop table {$prefix}test;";
305-
$db->rawQuery($q);
306-
307353
echo "All done";
308354

309355
//print_r($db->rawQuery("CALL simpleproc(?)",Array("test")));

0 commit comments

Comments
 (0)