Commit 6d29fa7e authored by Alexander Butenko's avatar Alexander Butenko

Implement subquery support in joins

parent 6ca835bb
...@@ -117,7 +117,7 @@ class MysqliDb ...@@ -117,7 +117,7 @@ class MysqliDb
else else
$this->port = $port; $this->port = $port;
if ($host == null && $username == null && $db == null) { if ($username == null && $db == null) {
$this->isSubQuery = true; $this->isSubQuery = true;
return; return;
} }
...@@ -427,12 +427,14 @@ class MysqliDb ...@@ -427,12 +427,14 @@ class MysqliDb
{ {
$allowedTypes = array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'); $allowedTypes = array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER');
$joinType = strtoupper (trim ($joinType)); $joinType = strtoupper (trim ($joinType));
$joinTable = filter_var($joinTable, FILTER_SANITIZE_STRING);
if ($joinType && !in_array ($joinType, $allowedTypes)) if ($joinType && !in_array ($joinType, $allowedTypes))
die ('Wrong JOIN type: '.$joinType); 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; return $this;
} }
...@@ -587,7 +589,7 @@ class MysqliDb ...@@ -587,7 +589,7 @@ class MysqliDb
$subQuery = $value->getSubQuery (); $subQuery = $value->getSubQuery ();
$this->_bindParams ($subQuery['params']); $this->_bindParams ($subQuery['params']);
return " " . $operator . " (" . $subQuery['query'] . ")"; return " " . $operator . " (" . $subQuery['query'] . ") " . $subQuery['alias'];
} }
/** /**
...@@ -679,8 +681,16 @@ class MysqliDb ...@@ -679,8 +681,16 @@ class MysqliDb
if (empty ($this->_join)) if (empty ($this->_join))
return; return;
foreach ($this->_join as $prop => $value) foreach ($this->_join as $data) {
$this->_query .= " " . $prop . " on " . $value; 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 +956,8 @@ class MysqliDb ...@@ -946,7 +956,8 @@ class MysqliDb
array_shift ($this->_bindParams); array_shift ($this->_bindParams);
$val = Array ('query' => $this->_query, $val = Array ('query' => $this->_query,
'params' => $this->_bindParams 'params' => $this->_bindParams,
'alias' => $this->host
); );
$this->reset(); $this->reset();
return $val; return $val;
...@@ -1031,9 +1042,9 @@ class MysqliDb ...@@ -1031,9 +1042,9 @@ class MysqliDb
/** /**
* Method creates new mysqlidb object for a subquery generation * Method creates new mysqlidb object for a subquery generation
*/ */
public static function subQuery() public static function subQuery($subQueryAlias = "")
{ {
return new MysqliDb(); return new MysqliDb ($subQueryAlias);
} }
/** /**
......
...@@ -307,6 +307,20 @@ echo "total records found: " . $cnt; ...@@ -307,6 +307,20 @@ echo "total records found: " . $cnt;
``` ```
### Subqueries ### 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: Subquery in selects:
```php ```php
$ids = $db->subQuery (); $ids = $db->subQuery ();
...@@ -333,6 +347,18 @@ $id = $db->insert ("products", $data); ...@@ -333,6 +347,18 @@ $id = $db->insert ("products", $data);
// Gives INSERT INTO PRODUCTS (productName, userId, lastUpdated) values ("test product", (SELECT name FROM users WHERE id = 6), NOW()); // 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 ###EXISTS / NOT EXISTS condition
```php ```php
$sub = $db->subQuery(); $sub = $db->subQuery();
......
...@@ -292,6 +292,23 @@ if ($cnt != 2) { ...@@ -292,6 +292,23 @@ if ($cnt != 2) {
echo "Invalid select result with subquery"; echo "Invalid select result with subquery";
exit; 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 //TODO: insert test
$db->delete("users"); $db->delete("users");
$db->get("users"); $db->get("users");
......
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