Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions src/Query/Sql/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ class Base extends BaseQuery
*/
protected $table = null;

/**
* Function to check if sub queries have been generated correctly, to avoid translation errors
*
* @return bool
*/
protected function isValid()
{
return (bool)!empty($this->table);
}

/**
* Inherit property values from parent query
*
Expand All @@ -42,7 +52,27 @@ protected function inheritFromParent(BaseQuery $parent)
$this->table = $parent->table;
}
}


/**
* Process a subquery generator callback
*
* @param callable $generator
* @return void
*/
protected function generateSubQuery($generator, $object = null)
{
// create new query object
$subquery = is_null($object)? new Select : $object;

// run the closure callback on the sub query
$generator($subquery);
if (!$subquery->isValid()) {
throw new Exception('Subquery generator did not generate a valid subquery.');
}

return $subquery;
}

/**
* Create a new select query builder
*
Expand All @@ -57,6 +87,11 @@ protected function inheritFromParent(BaseQuery $parent)
*/
public function table($table, $alias = null)
{
if (empty($table) && !is_numeric($table))
{
throw new Exception('Table name cannot be empty.');
}

$database = null;

// Check if the table is an object, this means
Expand All @@ -81,11 +116,7 @@ public function table($table, $alias = null)
$alias = key($table);
$table = reset($table);

// create new query object
$subquery = new Select;

// run the closure callback on the sub query
call_user_func_array($table, array(&$subquery));
$subquery = $this->generateSubQuery($table);

// set the table
// IMPORTANT: Only if we have a closure as table
Expand Down
40 changes: 27 additions & 13 deletions src/Query/Sql/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,19 @@ class Select extends SelectBase implements FetchableInterface
*/
protected $forwardKey = false;

/**
* Function to check if sub queries have been generated correctly, to avoid translation errors
*
* @return bool
*/
protected function isValid()
{
return (bool)!empty($this->table);
}

/**
* Inherit property values from parent query
*
*
* @param BaseQuery $parent
* @return void
*/
Expand Down Expand Up @@ -340,18 +350,22 @@ public function join($table, $localKey, $operator = null, $referenceKey = null,
throw new Exception('Invalid join type "'.$type.'" given. Available type: inner, left, right, outer');
}

// to make nested joins possible you can pass an closure
// wich will create a new query where you can add your nested wheres
if (is_object($localKey) && ($localKey instanceof \Closure))
{
// create new query object
$subquery = new SelectJoin;

// run the closure callback on the sub query
call_user_func_array($localKey, array(&$subquery));

// add the join
$this->joins[] = array($type, $table, $subquery); return $this;
if (is_object($localKey)) {
// to make nested joins possible you can pass a closure
// which will create a new query where you can add your nested wheres
if ($localKey instanceof \Closure) {
$localKey = $this->generateSubQuery($localKey, new SelectJoin);
}
// also allow using a manually constructed SelectJoin object
if ($localKey instanceof SelectJoin) {
$this->joins[] = [$type, $table, $localKey];
return $this;
}
// continue, because localKey could be an expression object
}

if (is_null($operator) || is_null($referenceKey)) {
throw new Exception('When using non nested join conditions, an operator and a reference key is required.');
}

$this->joins[] = array($type, $table, $localKey, $operator, $referenceKey); return $this;
Expand Down
27 changes: 16 additions & 11 deletions src/Query/Sql/SelectBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ class SelectBase extends Base
*/
protected $limit = null;

/**
* Function to check if sub queries have been generated correctly, to avoid translation errors
*
* @return bool
*/
protected function isValid()
{
return (bool)!empty($this->wheres);
}

/**
* Returns an string argument as parsed array if possible
*
Expand Down Expand Up @@ -126,17 +136,12 @@ public function where($column, $param1 = null, $param2 = null, $type = 'and')
$this->wheres[] = array($type, $subquery); return $this;
}

// to make nested wheres possible you can pass an closure
// wich will create a new query where you can add your nested wheres
if (is_object($column) && ($column instanceof \Closure))
{
// create new query object
$subquery = new SelectBase;

// run the closure callback on the sub query
call_user_func_array($column, array( &$subquery ));

$this->wheres[] = array($type, $subquery); return $this;
// to make nested wheres possible you can pass a closure
// which will create a new query where you can add your nested wheres
if (is_object($column) && ($column instanceof \Closure)) {
$subquery = $this->generateSubQuery($column, new SelectBase);
$this->wheres[] = [$type, $subquery];
return $this;
}

// when param2 is null we replace param2 with param one as the
Expand Down
10 changes: 10 additions & 0 deletions src/Query/Sql/SelectJoin.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ class SelectJoin extends SelectBase
*/
protected $wheres = array();

/**
* Function to check if sub queries have been generated correctly, to avoid translation errors
*
* @return bool
*/
protected function isValid()
{
return (bool)!empty($this->ons);
}

/**
* Add an on condition to the join object
*
Expand Down
24 changes: 12 additions & 12 deletions src/Translator/Mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ class Mysql implements TranslatorInterface
*/
protected $attributes = array();

/**
* Function to escape identifier names (columns and tables)
* Doubles backticks, removes null bytes
* https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
*
* @var string
*/
public function escapeIdentifier($identifier)
{
return '`'.str_replace(['`',"\0"],['``',''],$identifier).'`';
}

/**
* Translate the given query object and return the results as
* argument array
Expand Down Expand Up @@ -243,6 +231,18 @@ protected function escape($string)
return $this->escapeIdentifier($string);
}

/**
* Function to escape identifier names (columns and tables)
* Doubles backticks, removes null bytes
* https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
*
* @var string
*/
public function escapeIdentifier($identifier)
{
return '`' . str_replace(['`', "\0"], ['``',''], $identifier) . '`';
}

/**
* Escapes an sql function object
*
Expand Down