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

Implement subquery support in joins

parent 6ca835bb
......@@ -117,7 +117,7 @@ class MysqliDb
else
$this->port = $port;
if ($host == null && $username == null && $db == null) {
if ($username == null && $db == null) {
$this->isSubQuery = true;
return;
}
......@@ -427,12 +427,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 +589,7 @@ class MysqliDb
$subQuery = $value->getSubQuery ();
$this->_bindParams ($subQuery['params']);
return " " . $operator . " (" . $subQuery['query'] . ")";
return " " . $operator . " (" . $subQuery['query'] . ") " . $subQuery['alias'];
}
/**
......@@ -679,8 +681,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 +956,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 +1042,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 ($subQueryAlias);
}
/**
......
......@@ -307,6 +307,20 @@ echo "total records found: " . $cnt;
```
### 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 +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());
```
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();
......
......@@ -292,6 +292,23 @@ if ($cnt != 2) {
echo "Invalid select result with subquery";
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");
......
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