@@ -48,7 +48,7 @@ class Db implements IDb { | |||
/** | |||
* Gets the ExpressionBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IExpressionBuilder | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
*/ | |||
public function getExpressionBuilder() { | |||
return $this->connection->getExpressionBuilder(); | |||
@@ -57,7 +57,7 @@ class Db implements IDb { | |||
/** | |||
* Gets the ExpressionBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IQueryBuilder | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder | |||
*/ | |||
public function getQueryBuilder() { | |||
return $this->connection->getQueryBuilder(); |
@@ -29,6 +29,8 @@ use Doctrine\DBAL\Driver; | |||
use Doctrine\DBAL\Configuration; | |||
use Doctrine\DBAL\Cache\QueryCacheProfile; | |||
use Doctrine\Common\EventManager; | |||
use OC\DB\QueryBuilder\ExpressionBuilder; | |||
use OC\DB\QueryBuilder\QueryBuilder; | |||
use OCP\IDBConnection; | |||
class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { | |||
@@ -54,7 +56,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { | |||
/** | |||
* Gets the ExpressionBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IExpressionBuilder | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
*/ | |||
public function getExpressionBuilder() { | |||
return new ExpressionBuilder($this); | |||
@@ -63,7 +65,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { | |||
/** | |||
* Gets the QueryBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IQueryBuilder | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder | |||
*/ | |||
public function getQueryBuilder() { | |||
return new QueryBuilder($this); |
@@ -19,9 +19,9 @@ | |||
* | |||
*/ | |||
namespace OC\DB; | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\ICompositeExpression; | |||
use OCP\DB\QueryBuilder\ICompositeExpression; | |||
class CompositeExpression implements ICompositeExpression, \Countable { | |||
/** @var \Doctrine\DBAL\Query\Expression\CompositeExpression */ | |||
@@ -41,7 +41,7 @@ class CompositeExpression implements ICompositeExpression, \Countable { | |||
* | |||
* @param array $parts | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
*/ | |||
public function addMultiple(array $parts = array()) { | |||
$this->compositeExpression->addMultiple($parts); | |||
@@ -54,7 +54,7 @@ class CompositeExpression implements ICompositeExpression, \Countable { | |||
* | |||
* @param mixed $part | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
*/ | |||
public function add($part) { | |||
$this->compositeExpression->add($part); |
@@ -19,22 +19,26 @@ | |||
* | |||
*/ | |||
namespace OC\DB; | |||
namespace OC\DB\QueryBuilder; | |||
use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder; | |||
use OCP\DB\IExpressionBuilder; | |||
use OCP\DB\QueryBuilder\IExpressionBuilder; | |||
use OCP\IDBConnection; | |||
class ExpressionBuilder implements IExpressionBuilder { | |||
/** @var \Doctrine\DBAL\Query\Expression\ExpressionBuilder */ | |||
private $expressionBuilder; | |||
/** @var QuoteHelper */ | |||
private $helper; | |||
/** | |||
* Initializes a new <tt>ExpressionBuilder</tt>. | |||
* | |||
* @param \OCP\IDBConnection $connection | |||
*/ | |||
public function __construct(IDBConnection $connection) { | |||
$this->helper = new QuoteHelper(); | |||
$this->expressionBuilder = new DoctrineExpressionBuilder($connection); | |||
} | |||
@@ -50,10 +54,11 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @param mixed $x Optional clause. Defaults = null, but requires | |||
* at least one defined when converting to string. | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
*/ | |||
public function andX($x = null) { | |||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], func_get_args()); | |||
$arguments = func_get_args(); | |||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], $arguments); | |||
return new CompositeExpression($compositeExpression); | |||
} | |||
@@ -69,10 +74,11 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @param mixed $x Optional clause. Defaults = null, but requires | |||
* at least one defined when converting to string. | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
*/ | |||
public function orX($x = null) { | |||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], func_get_args()); | |||
$arguments = func_get_args(); | |||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], $arguments); | |||
return new CompositeExpression($compositeExpression); | |||
} | |||
@@ -86,6 +92,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function comparison($x, $operator, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->comparison($x, $operator, $y); | |||
} | |||
@@ -105,6 +113,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function eq($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->eq($x, $y); | |||
} | |||
@@ -123,6 +133,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function neq($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->neq($x, $y); | |||
} | |||
@@ -141,6 +153,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function lt($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->lt($x, $y); | |||
} | |||
@@ -159,6 +173,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function lte($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->lte($x, $y); | |||
} | |||
@@ -177,6 +193,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function gt($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->gt($x, $y); | |||
} | |||
@@ -195,6 +213,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function gte($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->gte($x, $y); | |||
} | |||
@@ -206,6 +226,7 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function isNull($x) { | |||
$x = $this->helper->quoteColumnName($x); | |||
return $this->expressionBuilder->isNull($x); | |||
} | |||
@@ -217,6 +238,7 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function isNotNull($x) { | |||
$x = $this->helper->quoteColumnName($x); | |||
return $this->expressionBuilder->isNotNull($x); | |||
} | |||
@@ -229,6 +251,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function like($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->like($x, $y); | |||
} | |||
@@ -241,6 +265,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function notLike($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnName($y); | |||
return $this->expressionBuilder->notLike($x, $y); | |||
} | |||
@@ -253,6 +279,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function in($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnNames($y); | |||
return $this->expressionBuilder->in($x, $y); | |||
} | |||
@@ -265,6 +293,8 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @return string | |||
*/ | |||
public function notIn($x, $y) { | |||
$x = $this->helper->quoteColumnName($x); | |||
$y = $this->helper->quoteColumnNames($y); | |||
return $this->expressionBuilder->notIn($x, $y); | |||
} | |||
@@ -274,9 +304,9 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
* @param mixed $input The parameter to be quoted. | |||
* @param string|null $type The type of the parameter. | |||
* | |||
* @return string | |||
* @return Literal | |||
*/ | |||
public function literal($input, $type = null) { | |||
return $this->expressionBuilder->literal($input, $type); | |||
return new Literal($this->expressionBuilder->literal($input, $type)); | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\QueryBuilder\ILiteral; | |||
class Literal implements ILiteral{ | |||
/** @var mixed */ | |||
protected $literal; | |||
public function __construct($literal) { | |||
$this->literal = $literal; | |||
} | |||
/** | |||
* @return string | |||
*/ | |||
public function __toString() { | |||
return (string) $this->literal; | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\QueryBuilder\IParameter; | |||
class Parameter implements IParameter { | |||
/** @var mixed */ | |||
protected $name; | |||
public function __construct($name) { | |||
$this->name = $name; | |||
} | |||
/** | |||
* @return string | |||
*/ | |||
public function __toString() { | |||
return (string) $this->name; | |||
} | |||
} |
@@ -19,9 +19,11 @@ | |||
* | |||
*/ | |||
namespace OC\DB; | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\IQueryBuilder; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\DB\QueryBuilder\IQueryFunction; | |||
use OCP\DB\QueryBuilder\IParameter; | |||
use OCP\IDBConnection; | |||
class QueryBuilder implements IQueryBuilder { | |||
@@ -32,15 +34,18 @@ class QueryBuilder implements IQueryBuilder { | |||
/** @var \Doctrine\DBAL\Query\QueryBuilder */ | |||
private $queryBuilder; | |||
/** @var QuoteHelper */ | |||
private $helper; | |||
/** | |||
* Initializes a new <tt>QueryBuilder</tt>. | |||
* | |||
* @var \OCP\IDBConnection | |||
*/ | |||
public function __construct(IDBConnection $connection) | |||
{ | |||
public function __construct(IDBConnection $connection) { | |||
$this->connection = $connection; | |||
$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection); | |||
$this->helper = new QuoteHelper(); | |||
} | |||
/** | |||
@@ -57,7 +62,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* For more complex expression construction, consider storing the expression | |||
* builder object in a local variable. | |||
* | |||
* @return \OCP\DB\IExpressionBuilder | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
*/ | |||
public function expr() { | |||
return $this->connection->getExpressionBuilder(); | |||
@@ -133,7 +138,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param mixed $value The parameter value. | |||
* @param string|null $type One of the PDO::PARAM_* constants. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function setParameter($key, $value, $type = null) { | |||
$this->queryBuilder->setParameter($key, $value, $type); | |||
@@ -158,7 +163,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param array $params The query parameters to set. | |||
* @param array $types The query parameters types to set. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function setParameters(array $params, array $types = array()) { | |||
$this->queryBuilder->setParameters($params, $types); | |||
@@ -211,7 +216,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param integer $firstResult The first result to return. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function setFirstResult($firstResult) { | |||
$this->queryBuilder->setFirstResult($firstResult); | |||
@@ -234,7 +239,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param integer $maxResults The maximum number of results to retrieve. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function setMaxResults($maxResults) { | |||
$this->queryBuilder->setMaxResults($maxResults); | |||
@@ -252,24 +257,6 @@ class QueryBuilder implements IQueryBuilder { | |||
return $this->queryBuilder->getMaxResults(); | |||
} | |||
/** | |||
* Either appends to or replaces a single, generic query part. | |||
* | |||
* The available parts are: 'select', 'from', 'set', 'where', | |||
* 'groupBy', 'having' and 'orderBy'. | |||
* | |||
* @param string $sqlPartName | |||
* @param string $sqlPart | |||
* @param boolean $append | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function add($sqlPartName, $sqlPart, $append = false) { | |||
$this->queryBuilder->add($sqlPartName, $sqlPart, $append); | |||
return $this; | |||
} | |||
/** | |||
* Specifies an item that is to be returned in the query result. | |||
* Replaces any previously specified selections, if any. | |||
@@ -283,10 +270,14 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $select The selection expressions. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function select($select = null) { | |||
$this->queryBuilder->select($select); | |||
$selects = is_array($select) ? $select : func_get_args(); | |||
$this->queryBuilder->select( | |||
$this->helper->quoteColumnNames($selects) | |||
); | |||
return $this; | |||
} | |||
@@ -304,10 +295,14 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $select The selection expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function addSelect($select = null) { | |||
$this->queryBuilder->addSelect($select); | |||
$selects = is_array($select) ? $select : func_get_args(); | |||
$this->queryBuilder->addSelect( | |||
$this->helper->quoteColumnNames($selects) | |||
); | |||
return $this; | |||
} | |||
@@ -326,10 +321,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $delete The table whose rows are subject to the deletion. | |||
* @param string $alias The table alias used in the constructed query. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function delete($delete = null, $alias = null) { | |||
$this->queryBuilder->delete($delete, $alias); | |||
$this->queryBuilder->delete( | |||
$this->helper->quoteColumnName($delete), | |||
$alias | |||
); | |||
return $this; | |||
} | |||
@@ -348,10 +346,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $update The table whose rows are subject to the update. | |||
* @param string $alias The table alias used in the constructed query. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function update($update = null, $alias = null) { | |||
$this->queryBuilder->update($update, $alias); | |||
$this->queryBuilder->update( | |||
$this->helper->quoteColumnName($update), | |||
$alias | |||
); | |||
return $this; | |||
} | |||
@@ -373,10 +374,12 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param string $insert The table into which the rows should be inserted. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function insert($insert = null) { | |||
$this->queryBuilder->insert($insert); | |||
$this->queryBuilder->insert( | |||
$this->helper->quoteColumnName($insert) | |||
); | |||
return $this; | |||
} | |||
@@ -394,10 +397,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $from The table. | |||
* @param string|null $alias The alias of the table. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function from($from, $alias = null) { | |||
$this->queryBuilder->from($from, $alias); | |||
$this->queryBuilder->from( | |||
$this->helper->quoteColumnName($from), | |||
$alias | |||
); | |||
return $this; | |||
} | |||
@@ -417,10 +423,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function join($fromAlias, $join, $alias, $condition = null) { | |||
$this->queryBuilder->join($fromAlias, $join, $alias, $condition); | |||
$this->queryBuilder->join( | |||
$fromAlias, | |||
$this->helper->quoteColumnName($join), | |||
$alias, | |||
$condition | |||
); | |||
return $this; | |||
} | |||
@@ -440,10 +451,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function innerJoin($fromAlias, $join, $alias, $condition = null) { | |||
$this->queryBuilder->innerJoin($fromAlias, $join, $alias, $condition); | |||
$this->queryBuilder->innerJoin( | |||
$fromAlias, | |||
$this->helper->quoteColumnName($join), | |||
$alias, | |||
$condition | |||
); | |||
return $this; | |||
} | |||
@@ -463,10 +479,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function leftJoin($fromAlias, $join, $alias, $condition = null) { | |||
$this->queryBuilder->leftJoin($fromAlias, $join, $alias, $condition); | |||
$this->queryBuilder->leftJoin( | |||
$fromAlias, | |||
$this->helper->quoteColumnName($join), | |||
$alias, | |||
$condition | |||
); | |||
return $this; | |||
} | |||
@@ -486,10 +507,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function rightJoin($fromAlias, $join, $alias, $condition = null) { | |||
$this->queryBuilder->rightJoin($fromAlias, $join, $alias, $condition); | |||
$this->queryBuilder->rightJoin( | |||
$fromAlias, | |||
$this->helper->quoteColumnName($join), | |||
$alias, | |||
$condition | |||
); | |||
return $this; | |||
} | |||
@@ -507,10 +533,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $key The column to set. | |||
* @param string $value The value, expression, placeholder, etc. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function set($key, $value) { | |||
$this->queryBuilder->set($key, $value); | |||
$this->queryBuilder->set( | |||
$this->helper->quoteColumnName($key), | |||
$this->helper->quoteColumnName($value) | |||
); | |||
return $this; | |||
} | |||
@@ -539,10 +568,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $predicates The restriction predicates. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function where($predicates) { | |||
call_user_func_array([$this->queryBuilder, 'where'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'where'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -561,12 +593,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $where The query restrictions. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* | |||
* @see where() | |||
*/ | |||
public function andWhere($where) { | |||
call_user_func_array([$this->queryBuilder, 'andWhere'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'andWhere'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -585,12 +620,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $where The WHERE statement. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* | |||
* @see where() | |||
*/ | |||
public function orWhere($where) { | |||
call_user_func_array([$this->queryBuilder, 'orWhere'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'orWhere'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -608,10 +646,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $groupBy The grouping expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function groupBy($groupBy) { | |||
call_user_func_array([$this->queryBuilder, 'groupBy'], func_get_args()); | |||
$groupBys = is_array($groupBy) ? $groupBy : func_get_args(); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'groupBy'], | |||
$this->helper->quoteColumnNames($groupBys) | |||
); | |||
return $this; | |||
} | |||
@@ -629,10 +672,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $groupBy The grouping expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function addGroupBy($groupBy) { | |||
call_user_func_array([$this->queryBuilder, 'addGroupBy'], func_get_args()); | |||
$groupBys = is_array($groupBy) ? $groupBy : func_get_args(); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'addGroupBy'], | |||
$this->helper->quoteColumnNames($groupBys) | |||
); | |||
return $this; | |||
} | |||
@@ -654,10 +702,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $column The column into which the value should be inserted. | |||
* @param string $value The value that should be inserted into the column. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function setValue($column, $value) { | |||
$this->queryBuilder->setValue($column, $value); | |||
$this->queryBuilder->setValue( | |||
$this->helper->quoteColumnName($column), | |||
$value | |||
); | |||
return $this; | |||
} | |||
@@ -679,10 +730,15 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param array $values The values to specify for the insert query indexed by column names. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function values(array $values) { | |||
$this->queryBuilder->values($values); | |||
$quotedValues = []; | |||
foreach ($values as $key => $value) { | |||
$quotedValues[$this->helper->quoteColumnName($key)] = $value; | |||
} | |||
$this->queryBuilder->values($quotedValues); | |||
return $this; | |||
} | |||
@@ -693,10 +749,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction over the groups. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function having($having) { | |||
call_user_func_array([$this->queryBuilder, 'having'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'having'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -707,10 +766,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction to append. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function andHaving($having) { | |||
call_user_func_array([$this->queryBuilder, 'andHaving'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'andHaving'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -721,10 +783,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction to add. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function orHaving($having) { | |||
call_user_func_array([$this->queryBuilder, 'orHaving'], func_get_args()); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'orHaving'], | |||
func_get_args() | |||
); | |||
return $this; | |||
} | |||
@@ -736,10 +801,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $sort The ordering expression. | |||
* @param string $order The ordering direction. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function orderBy($sort, $order = null) { | |||
$this->queryBuilder->orderBy($sort, $order); | |||
$this->queryBuilder->orderBy( | |||
$this->helper->quoteColumnName($sort), | |||
$order | |||
); | |||
return $this; | |||
} | |||
@@ -750,10 +818,13 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param string $sort The ordering expression. | |||
* @param string $order The ordering direction. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function addOrderBy($sort, $order = null) { | |||
$this->queryBuilder->addOrderBy($sort, $order); | |||
$this->queryBuilder->addOrderBy( | |||
$this->helper->quoteColumnName($sort), | |||
$order | |||
); | |||
return $this; | |||
} | |||
@@ -783,7 +854,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param array|null $queryPartNames | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function resetQueryParts($queryPartNames = null) { | |||
$this->queryBuilder->resetQueryParts($queryPartNames); | |||
@@ -796,7 +867,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* | |||
* @param string $queryPartName | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
*/ | |||
public function resetQueryPart($queryPartName) { | |||
$this->queryBuilder->resetQueryPart($queryPartName); | |||
@@ -831,10 +902,10 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param mixed $type | |||
* @param string $placeHolder The name to bind with. The string must start with a colon ':'. | |||
* | |||
* @return string the placeholder name used. | |||
* @return IParameter the placeholder name used. | |||
*/ | |||
public function createNamedParameter($value, $type = \PDO::PARAM_STR, $placeHolder = null) { | |||
return $this->queryBuilder->createNamedParameter($value, $type, $placeHolder); | |||
return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder)); | |||
} | |||
/** | |||
@@ -857,9 +928,56 @@ class QueryBuilder implements IQueryBuilder { | |||
* @param mixed $value | |||
* @param integer $type | |||
* | |||
* @return string | |||
* @return IParameter | |||
*/ | |||
public function createPositionalParameter($value, $type = \PDO::PARAM_STR) { | |||
return $this->queryBuilder->createPositionalParameter($value, $type); | |||
return new Parameter($this->queryBuilder->createPositionalParameter($value, $type)); | |||
} | |||
/** | |||
* Creates a new parameter | |||
* | |||
* Example: | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select('u.*') | |||
* ->from('users', 'u') | |||
* ->where('u.username = ' . $qb->createParameter('name')) | |||
* ->setParameter('name', 'Bar', PDO::PARAM_STR)) | |||
* </code> | |||
* | |||
* @param string $name | |||
* | |||
* @return IParameter | |||
*/ | |||
public function createParameter($name) { | |||
return new Parameter(':' . $name); | |||
} | |||
/** | |||
* Creates a new function | |||
* | |||
* Attention: Column names inside the call have to be quoted before hand | |||
* | |||
* Example: | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select($qb->createFunction('COUNT(*)')) | |||
* ->from('users', 'u') | |||
* echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u | |||
* </code> | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select($qb->createFunction('COUNT(`column`)')) | |||
* ->from('users', 'u') | |||
* echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u | |||
* </code> | |||
* | |||
* @param string $call | |||
* | |||
* @return IQueryFunction | |||
*/ | |||
public function createFunction($call) { | |||
return new QueryFunction($call); | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\QueryBuilder\IQueryFunction; | |||
class QueryFunction implements IQueryFunction { | |||
/** @var string */ | |||
protected $function; | |||
public function __construct($function) { | |||
$this->function = $function; | |||
} | |||
/** | |||
* @return string | |||
*/ | |||
public function __toString() { | |||
return (string) $this->function; | |||
} | |||
} |
@@ -0,0 +1,75 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\DB\QueryBuilder; | |||
use OCP\DB\QueryBuilder\ILiteral; | |||
use OCP\DB\QueryBuilder\IParameter; | |||
use OCP\DB\QueryBuilder\IQueryFunction; | |||
class QuoteHelper { | |||
/** | |||
* @param array|string|ILiteral|IParameter|IQueryFunction $strings string, Literal or Parameter | |||
* @return array|string | |||
*/ | |||
public function quoteColumnNames($strings) { | |||
if (!is_array($strings)) { | |||
return $this->quoteColumnName($strings); | |||
} | |||
$return = []; | |||
foreach ($strings as $string) { | |||
$return[] = $this->quoteColumnName($string); | |||
} | |||
return $return; | |||
} | |||
/** | |||
* @param string|ILiteral|IParameter|IQueryFunction $string string, Literal or Parameter | |||
* @return string | |||
*/ | |||
public function quoteColumnName($string) { | |||
if ($string instanceof IParameter || $string instanceof ILiteral || $string instanceof IQueryFunction) { | |||
return (string) $string; | |||
} | |||
if ($string === null || $string === '*') { | |||
return $string; | |||
} | |||
if (!is_string($string)) { | |||
throw new \InvalidArgumentException('Only strings, Literals and Parameters are allowed'); | |||
} | |||
if (substr_count($string, '.')) { | |||
list($alias, $columnName) = explode('.', $string); | |||
if ($columnName === '*') { | |||
return $string; | |||
} | |||
return $alias . '.`' . $columnName . '`'; | |||
} | |||
return '`' . $string . '`'; | |||
} | |||
} |
@@ -19,7 +19,7 @@ | |||
* | |||
*/ | |||
namespace OCP\DB; | |||
namespace OCP\DB\QueryBuilder; | |||
/** | |||
* This class provides a wrapper around Doctrine's CompositeExpression |
@@ -19,7 +19,7 @@ | |||
* | |||
*/ | |||
namespace OCP\DB; | |||
namespace OCP\DB\QueryBuilder; | |||
/** | |||
* This class provides a wrapper around Doctrine's ExpressionBuilder | |||
@@ -38,7 +38,7 @@ interface IExpressionBuilder { | |||
* @param mixed $x Optional clause. Defaults = null, but requires | |||
* at least one defined when converting to string. | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
* @since 8.2.0 | |||
*/ | |||
public function andX($x = null); | |||
@@ -55,7 +55,7 @@ interface IExpressionBuilder { | |||
* @param mixed $x Optional clause. Defaults = null, but requires | |||
* at least one defined when converting to string. | |||
* | |||
* @return \OCP\DB\ICompositeExpression | |||
* @return \OCP\DB\QueryBuilder\ICompositeExpression | |||
* @since 8.2.0 | |||
*/ | |||
public function orX($x = null); |
@@ -0,0 +1,29 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCP\DB\QueryBuilder; | |||
interface ILiteral { | |||
/** | |||
* @return string | |||
* @since 8.2.0 | |||
*/ | |||
public function __toString(); | |||
} |
@@ -0,0 +1,29 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCP\DB\QueryBuilder; | |||
interface IParameter { | |||
/** | |||
* @return string | |||
* @since 8.2.0 | |||
*/ | |||
public function __toString(); | |||
} |
@@ -19,7 +19,7 @@ | |||
* | |||
*/ | |||
namespace OCP\DB; | |||
namespace OCP\DB\QueryBuilder; | |||
/** | |||
* This class provides a wrapper around Doctrine's QueryBuilder | |||
@@ -40,7 +40,7 @@ interface IQueryBuilder { | |||
* For more complex expression construction, consider storing the expression | |||
* builder object in a local variable. | |||
* | |||
* @return \OCP\DB\IExpressionBuilder | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
* @since 8.2.0 | |||
*/ | |||
public function expr(); | |||
@@ -110,7 +110,7 @@ interface IQueryBuilder { | |||
* @param mixed $value The parameter value. | |||
* @param string|null $type One of the PDO::PARAM_* constants. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function setParameter($key, $value, $type = null); | |||
@@ -132,7 +132,7 @@ interface IQueryBuilder { | |||
* @param array $params The query parameters to set. | |||
* @param array $types The query parameters types to set. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function setParameters(array $params, array $types = array()); | |||
@@ -178,7 +178,7 @@ interface IQueryBuilder { | |||
* | |||
* @param integer $firstResult The first result to return. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function setFirstResult($firstResult); | |||
@@ -197,7 +197,7 @@ interface IQueryBuilder { | |||
* | |||
* @param integer $maxResults The maximum number of results to retrieve. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function setMaxResults($maxResults); | |||
@@ -211,21 +211,6 @@ interface IQueryBuilder { | |||
*/ | |||
public function getMaxResults(); | |||
/** | |||
* Either appends to or replaces a single, generic query part. | |||
* | |||
* The available parts are: 'select', 'from', 'set', 'where', | |||
* 'groupBy', 'having' and 'orderBy'. | |||
* | |||
* @param string $sqlPartName | |||
* @param string $sqlPart | |||
* @param boolean $append | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function add($sqlPartName, $sqlPart, $append = false); | |||
/** | |||
* Specifies an item that is to be returned in the query result. | |||
* Replaces any previously specified selections, if any. | |||
@@ -239,7 +224,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $select The selection expressions. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function select($select = null); | |||
@@ -257,7 +242,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $select The selection expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function addSelect($select = null); | |||
@@ -276,7 +261,7 @@ interface IQueryBuilder { | |||
* @param string $delete The table whose rows are subject to the deletion. | |||
* @param string $alias The table alias used in the constructed query. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function delete($delete = null, $alias = null); | |||
@@ -295,7 +280,7 @@ interface IQueryBuilder { | |||
* @param string $update The table whose rows are subject to the update. | |||
* @param string $alias The table alias used in the constructed query. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function update($update = null, $alias = null); | |||
@@ -317,7 +302,7 @@ interface IQueryBuilder { | |||
* | |||
* @param string $insert The table into which the rows should be inserted. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function insert($insert = null); | |||
@@ -335,7 +320,7 @@ interface IQueryBuilder { | |||
* @param string $from The table. | |||
* @param string|null $alias The alias of the table. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function from($from, $alias = null); | |||
@@ -355,7 +340,7 @@ interface IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function join($fromAlias, $join, $alias, $condition = null); | |||
@@ -375,7 +360,7 @@ interface IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function innerJoin($fromAlias, $join, $alias, $condition = null); | |||
@@ -395,7 +380,7 @@ interface IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function leftJoin($fromAlias, $join, $alias, $condition = null); | |||
@@ -415,7 +400,7 @@ interface IQueryBuilder { | |||
* @param string $alias The alias of the join table. | |||
* @param string $condition The condition for the join. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function rightJoin($fromAlias, $join, $alias, $condition = null); | |||
@@ -433,7 +418,7 @@ interface IQueryBuilder { | |||
* @param string $key The column to set. | |||
* @param string $value The value, expression, placeholder, etc. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function set($key, $value); | |||
@@ -462,7 +447,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $predicates The restriction predicates. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function where($predicates); | |||
@@ -481,7 +466,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $where The query restrictions. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* | |||
* @see where() | |||
* @since 8.2.0 | |||
@@ -502,7 +487,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $where The WHERE statement. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* | |||
* @see where() | |||
* @since 8.2.0 | |||
@@ -522,7 +507,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $groupBy The grouping expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function groupBy($groupBy); | |||
@@ -540,7 +525,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $groupBy The grouping expression. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function addGroupBy($groupBy); | |||
@@ -562,7 +547,7 @@ interface IQueryBuilder { | |||
* @param string $column The column into which the value should be inserted. | |||
* @param string $value The value that should be inserted into the column. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function setValue($column, $value); | |||
@@ -584,7 +569,7 @@ interface IQueryBuilder { | |||
* | |||
* @param array $values The values to specify for the insert query indexed by column names. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function values(array $values); | |||
@@ -595,7 +580,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction over the groups. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function having($having); | |||
@@ -606,7 +591,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction to append. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function andHaving($having); | |||
@@ -617,7 +602,7 @@ interface IQueryBuilder { | |||
* | |||
* @param mixed $having The restriction to add. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function orHaving($having); | |||
@@ -629,7 +614,7 @@ interface IQueryBuilder { | |||
* @param string $sort The ordering expression. | |||
* @param string $order The ordering direction. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function orderBy($sort, $order = null); | |||
@@ -640,7 +625,7 @@ interface IQueryBuilder { | |||
* @param string $sort The ordering expression. | |||
* @param string $order The ordering direction. | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function addOrderBy($sort, $order = null); | |||
@@ -668,7 +653,7 @@ interface IQueryBuilder { | |||
* | |||
* @param array|null $queryPartNames | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function resetQueryParts($queryPartNames = null); | |||
@@ -678,7 +663,7 @@ interface IQueryBuilder { | |||
* | |||
* @param string $queryPartName | |||
* | |||
* @return \OCP\DB\IQueryBuilder This QueryBuilder instance. | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. | |||
* @since 8.2.0 | |||
*/ | |||
public function resetQueryPart($queryPartName); | |||
@@ -710,7 +695,7 @@ interface IQueryBuilder { | |||
* @param mixed $type | |||
* @param string $placeHolder The name to bind with. The string must start with a colon ':'. | |||
* | |||
* @return string the placeholder name used. | |||
* @return IParameter | |||
* @since 8.2.0 | |||
*/ | |||
public function createNamedParameter($value, $type = \PDO::PARAM_STR, $placeHolder = null); | |||
@@ -735,8 +720,53 @@ interface IQueryBuilder { | |||
* @param mixed $value | |||
* @param integer $type | |||
* | |||
* @return string | |||
* @return IParameter | |||
* @since 8.2.0 | |||
*/ | |||
public function createPositionalParameter($value, $type = \PDO::PARAM_STR); | |||
/** | |||
* Creates a new parameter | |||
* | |||
* Example: | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select('u.*') | |||
* ->from('users', 'u') | |||
* ->where('u.username = ' . $qb->createParameter('name')) | |||
* ->setParameter('name', 'Bar', PDO::PARAM_STR)) | |||
* </code> | |||
* | |||
* @param string $name | |||
* | |||
* @return IParameter | |||
* @since 8.2.0 | |||
*/ | |||
public function createParameter($name); | |||
/** | |||
* Creates a new function | |||
* | |||
* Attention: Column names inside the call have to be quoted before hand | |||
* | |||
* Example: | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select($qb->createFunction('COUNT(*)')) | |||
* ->from('users', 'u') | |||
* echo $qb->getSQL(); // SELECT COUNT(*) FROM `users` u | |||
* </code> | |||
* <code> | |||
* $qb = $conn->getQueryBuilder(); | |||
* $qb->select($qb->createFunction('COUNT(`column`)')) | |||
* ->from('users', 'u') | |||
* echo $qb->getSQL(); // SELECT COUNT(`column`) FROM `users` u | |||
* </code> | |||
* | |||
* @param string $call | |||
* | |||
* @return IQueryFunction | |||
* @since 8.2.0 | |||
*/ | |||
public function createFunction($call); | |||
} |
@@ -0,0 +1,29 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCP\DB\QueryBuilder; | |||
interface IQueryFunction { | |||
/** | |||
* @return string | |||
* @since 8.2.0 | |||
*/ | |||
public function __toString(); | |||
} |
@@ -43,7 +43,7 @@ interface IDBConnection { | |||
/** | |||
* Gets the ExpressionBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IExpressionBuilder | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
* @since 8.2.0 | |||
*/ | |||
public function getExpressionBuilder(); | |||
@@ -51,7 +51,7 @@ interface IDBConnection { | |||
/** | |||
* Gets the QueryBuilder for the connection. | |||
* | |||
* @return \OCP\DB\IQueryBuilder | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder | |||
* @since 8.2.0 | |||
*/ | |||
public function getQueryBuilder(); |
@@ -0,0 +1,338 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace Test\DB\QueryBuilder; | |||
use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder; | |||
use OC\DB\QueryBuilder\ExpressionBuilder; | |||
class ExpressionBuilderTest extends \Test\TestCase { | |||
/** @var ExpressionBuilder */ | |||
protected $expressionBuilder; | |||
/** @var DoctrineExpressionBuilder */ | |||
protected $doctrineExpressionBuilder; | |||
protected function setUp() { | |||
parent::setUp(); | |||
$connection = \OC::$server->getDatabaseConnection(); | |||
$this->expressionBuilder = new ExpressionBuilder($connection); | |||
$this->doctrineExpressionBuilder = new DoctrineExpressionBuilder($connection); | |||
} | |||
public function dataComparison() { | |||
$valueSets = $this->dataComparisons(); | |||
$comparisonOperators = ['=', '<>', '<', '>', '<=', '>=']; | |||
$testSets = []; | |||
foreach ($comparisonOperators as $operator) { | |||
foreach ($valueSets as $values) { | |||
$testSets[] = array_merge([$operator], $values); | |||
} | |||
} | |||
return $testSets; | |||
} | |||
/** | |||
* @dataProvider dataComparison | |||
* | |||
* @param string $comparison | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testComparison($comparison, $input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->comparison($doctrineInput1, $comparison, $doctrineInput2), | |||
$this->expressionBuilder->comparison($ocInput1, $comparison, $ocInput2) | |||
); | |||
} | |||
public function dataComparisons() { | |||
return [ | |||
['value', false, 'value', false], | |||
['value', false, 'value', true], | |||
['value', true, 'value', false], | |||
['value', true, 'value', true], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testEquals($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->eq($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->eq($ocInput1, $ocInput2) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testNotEquals($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->neq($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->neq($ocInput1, $ocInput2) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testLowerThan($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->lt($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->lt($ocInput1, $ocInput2) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testLowerThanEquals($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->lte($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->lte($ocInput1, $ocInput2) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testGreaterThan($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->gt($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->gt($ocInput1, $ocInput2) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataComparisons | |||
* | |||
* @param mixed $input1 | |||
* @param bool $isInput1Literal | |||
* @param mixed $input2 | |||
* @param bool $isInput2Literal | |||
*/ | |||
public function testGreaterThanEquals($input1, $isInput1Literal, $input2, $isInput2Literal) { | |||
list($doctrineInput1, $ocInput1) = $this->helpWithLiteral($input1, $isInput1Literal); | |||
list($doctrineInput2, $ocInput2) = $this->helpWithLiteral($input2, $isInput2Literal); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->gte($doctrineInput1, $doctrineInput2), | |||
$this->expressionBuilder->gte($ocInput1, $ocInput2) | |||
); | |||
} | |||
public function testIsNull() { | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->isNull('`test`'), | |||
$this->expressionBuilder->isNull('test') | |||
); | |||
} | |||
public function testIsNotNull() { | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->isNotNull('`test`'), | |||
$this->expressionBuilder->isNotNull('test') | |||
); | |||
} | |||
public function dataLike() { | |||
return [ | |||
['value', false], | |||
['value', true], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataLike | |||
* | |||
* @param mixed $input | |||
* @param bool $isLiteral | |||
*/ | |||
public function testLike($input, $isLiteral) { | |||
list($doctrineInput, $ocInput) = $this->helpWithLiteral($input, $isLiteral); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->like('`test`', $doctrineInput), | |||
$this->expressionBuilder->like('test', $ocInput) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataLike | |||
* | |||
* @param mixed $input | |||
* @param bool $isLiteral | |||
*/ | |||
public function testNotLike($input, $isLiteral) { | |||
list($doctrineInput, $ocInput) = $this->helpWithLiteral($input, $isLiteral); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->notLike('`test`', $doctrineInput), | |||
$this->expressionBuilder->notLike('test', $ocInput) | |||
); | |||
} | |||
public function dataIn() { | |||
return [ | |||
['value', false], | |||
['value', true], | |||
[['value'], false], | |||
[['value'], true], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataIn | |||
* | |||
* @param mixed $input | |||
* @param bool $isLiteral | |||
*/ | |||
public function testIn($input, $isLiteral) { | |||
list($doctrineInput, $ocInput) = $this->helpWithLiteral($input, $isLiteral); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->in('`test`', $doctrineInput), | |||
$this->expressionBuilder->in('test', $ocInput) | |||
); | |||
} | |||
/** | |||
* @dataProvider dataIn | |||
* | |||
* @param mixed $input | |||
* @param bool $isLiteral | |||
*/ | |||
public function testNotIn($input, $isLiteral) { | |||
list($doctrineInput, $ocInput) = $this->helpWithLiteral($input, $isLiteral); | |||
$this->assertEquals( | |||
$this->doctrineExpressionBuilder->notIn('`test`', $doctrineInput), | |||
$this->expressionBuilder->notIn('test', $ocInput) | |||
); | |||
} | |||
protected function helpWithLiteral($input, $isLiteral) { | |||
if ($isLiteral) { | |||
if (is_array($input)) { | |||
$doctrineInput = array_map(function ($ident) { | |||
return $this->doctrineExpressionBuilder->literal($ident); | |||
}, $input); | |||
$ocInput = array_map(function ($ident) { | |||
return $this->expressionBuilder->literal($ident); | |||
}, $input); | |||
} else { | |||
$doctrineInput = $this->doctrineExpressionBuilder->literal($input); | |||
$ocInput = $this->expressionBuilder->literal($input); | |||
} | |||
} else { | |||
if (is_array($input)) { | |||
$doctrineInput = array_map(function ($input) { | |||
return '`' . $input . '`'; | |||
}, $input); | |||
$ocInput = $input; | |||
} else { | |||
$doctrineInput = '`' . $input . '`'; | |||
$ocInput = $input; | |||
} | |||
} | |||
return [$doctrineInput, $ocInput]; | |||
} | |||
public function dataLiteral() { | |||
return [ | |||
['value', null], | |||
['1', null], | |||
[1, null], | |||
[1, 'string'], | |||
[1, 'integer'], | |||
[1, \PDO::PARAM_INT], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataLiteral | |||
* | |||
* @param mixed $input | |||
* @param string|null $type | |||
*/ | |||
public function testLiteral($input, $type) { | |||
/** @var \OC\DB\QueryBuilder\Literal $actual */ | |||
$actual = $this->expressionBuilder->literal($input, $type); | |||
$this->assertInstanceOf('\OC\DB\QueryBuilder\Literal', $actual); | |||
$this->assertSame( | |||
$this->doctrineExpressionBuilder->literal($input, $type), | |||
$actual->__toString() | |||
); | |||
} | |||
} |
@@ -0,0 +1,941 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace Test\DB\QueryBuilder; | |||
use Doctrine\DBAL\Query\Expression\CompositeExpression; | |||
use OC\DB\QueryBuilder\Literal; | |||
use OC\DB\QueryBuilder\Parameter; | |||
use OC\DB\QueryBuilder\QueryBuilder; | |||
class QueryBuilderTest extends \Test\TestCase { | |||
/** @var QueryBuilder */ | |||
protected $queryBuilder; | |||
protected function setUp() { | |||
parent::setUp(); | |||
$connection = \OC::$server->getDatabaseConnection(); | |||
$this->queryBuilder = new QueryBuilder($connection); | |||
} | |||
public function dataFirstResult() { | |||
return [ | |||
[null, ''], | |||
[0, ' OFFSET 0'], | |||
[1, ' OFFSET 1'], | |||
[5, ' OFFSET 5'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataFirstResult | |||
* | |||
* @param int $firstResult | |||
* @param string $expectedOffset | |||
*/ | |||
public function testFirstResult($firstResult, $expectedOffset) { | |||
if ($firstResult !== null) { | |||
$this->queryBuilder->setFirstResult($firstResult); | |||
} | |||
$this->assertSame( | |||
$firstResult, | |||
$this->queryBuilder->getFirstResult() | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedOffset, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataMaxResults() { | |||
return [ | |||
[null, ''], | |||
[0, ' LIMIT 0'], | |||
[1, ' LIMIT 1'], | |||
[5, ' LIMIT 5'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataMaxResults | |||
* | |||
* @param int $maxResult | |||
* @param string $expectedLimit | |||
*/ | |||
public function testMaxResults($maxResult, $expectedLimit) { | |||
if ($maxResult !== null) { | |||
$this->queryBuilder->setMaxResults($maxResult); | |||
} | |||
$this->assertSame( | |||
$maxResult, | |||
$this->queryBuilder->getMaxResults() | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedLimit, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataSelect() { | |||
return [ | |||
// select('column1') | |||
[['column1'], ['`column1`'], '`column1`'], | |||
// select('column1', 'column2') | |||
[['column1', 'column2'], ['`column1`', '`column2`'], '`column1`, `column2`'], | |||
// select(['column1', 'column2']) | |||
[[['column1', 'column2']], ['`column1`', '`column2`'], '`column1`, `column2`'], | |||
// select(new Literal('column1')) | |||
[[new Literal('column1')], ['column1'], 'column1'], | |||
// select('column1', 'column2') | |||
[[new Literal('column1'), 'column2'], ['column1', '`column2`'], 'column1, `column2`'], | |||
// select(['column1', 'column2']) | |||
[[[new Literal('column1'), 'column2']], ['column1', '`column2`'], 'column1, `column2`'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataSelect | |||
* | |||
* @param array $selectArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedSelect | |||
*/ | |||
public function testSelect($selectArguments, $expectedQueryPart, $expectedSelect) { | |||
call_user_func_array( | |||
[$this->queryBuilder, 'select'], | |||
$selectArguments | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('select') | |||
); | |||
$this->assertSame( | |||
'SELECT ' . $expectedSelect . ' FROM ', | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataAddSelect() { | |||
return [ | |||
// addSelect('column1') | |||
[['column1'], ['`column`', '`column1`'], '`column`, `column1`'], | |||
// addSelect('column1', 'column2') | |||
[['column1', 'column2'], ['`column`', '`column1`', '`column2`'], '`column`, `column1`, `column2`'], | |||
// addSelect(['column1', 'column2']) | |||
[[['column1', 'column2']], ['`column`', '`column1`', '`column2`'], '`column`, `column1`, `column2`'], | |||
// select(new Literal('column1')) | |||
[[new Literal('column1')], ['`column`', 'column1'], '`column`, column1'], | |||
// select('column1', 'column2') | |||
[[new Literal('column1'), 'column2'], ['`column`', 'column1', '`column2`'], '`column`, column1, `column2`'], | |||
// select(['column1', 'column2']) | |||
[[[new Literal('column1'), 'column2']], ['`column`', 'column1', '`column2`'], '`column`, column1, `column2`'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataAddSelect | |||
* | |||
* @param array $selectArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedSelect | |||
*/ | |||
public function testAddSelect($selectArguments, $expectedQueryPart, $expectedSelect) { | |||
$this->queryBuilder->select('column'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'addSelect'], | |||
$selectArguments | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('select') | |||
); | |||
$this->assertSame( | |||
'SELECT ' . $expectedSelect . ' FROM ', | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataDelete() { | |||
return [ | |||
['data', null, ['table' => '`data`', 'alias' => null], '`data`'], | |||
['data', 't', ['table' => '`data`', 'alias' => 't'], '`data` t'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataDelete | |||
* | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testDelete($tableName, $tableAlias, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->delete($tableName, $tableAlias); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('from') | |||
); | |||
$this->assertSame( | |||
'DELETE FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataUpdate() { | |||
return [ | |||
['data', null, ['table' => '`data`', 'alias' => null], '`data`'], | |||
['data', 't', ['table' => '`data`', 'alias' => 't'], '`data` t'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataUpdate | |||
* | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testUpdate($tableName, $tableAlias, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->update($tableName, $tableAlias); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('from') | |||
); | |||
$this->assertSame( | |||
'UPDATE ' . $expectedQuery . ' SET ', | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataInsert() { | |||
return [ | |||
['data', ['table' => '`data`'], '`data`'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataInsert | |||
* | |||
* @param string $tableName | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testInsert($tableName, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->insert($tableName); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('from') | |||
); | |||
$this->assertSame( | |||
'INSERT INTO ' . $expectedQuery . ' () VALUES()', | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataFrom() { | |||
return [ | |||
['data', null, null, null, [['table' => '`data`', 'alias' => null]], '`data`'], | |||
['data', 't', null, null, [['table' => '`data`', 'alias' => 't']], '`data` t'], | |||
['data1', null, 'data2', null, [ | |||
['table' => '`data1`', 'alias' => null], | |||
['table' => '`data2`', 'alias' => null] | |||
], '`data1`, `data2`'], | |||
['data', 't1', 'data', 't2', [ | |||
['table' => '`data`', 'alias' => 't1'], | |||
['table' => '`data`', 'alias' => 't2'] | |||
], '`data` t1, `data` t2'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataFrom | |||
* | |||
* @param string $table1Name | |||
* @param string $table1Alias | |||
* @param string $table2Name | |||
* @param string $table2Alias | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testFrom($table1Name, $table1Alias, $table2Name, $table2Alias, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->from($table1Name, $table1Alias); | |||
if ($table2Name !== null) { | |||
$this->queryBuilder->from($table2Name, $table2Alias); | |||
} | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('from') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataJoin() { | |||
return [ | |||
[ | |||
'd1', 'data2', null, null, | |||
['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]], | |||
'`data1` d1 INNER JOIN `data2` ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', null, | |||
['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]], | |||
'`data1` d1 INNER JOIN `data2` d2 ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`', | |||
['d1' => [['joinType' => 'inner', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]], | |||
'`data1` d1 INNER JOIN `data2` d2 ON d1.`field1` = d2.`field2`' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataJoin | |||
* | |||
* @param string $fromAlias | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param string $condition | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->from('data1', 'd1'); | |||
$this->queryBuilder->join( | |||
$fromAlias, | |||
$tableName, | |||
$tableAlias, | |||
$condition | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('join') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
/** | |||
* @dataProvider dataJoin | |||
* | |||
* @param string $fromAlias | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param string $condition | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testInnerJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->from('data1', 'd1'); | |||
$this->queryBuilder->innerJoin( | |||
$fromAlias, | |||
$tableName, | |||
$tableAlias, | |||
$condition | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('join') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataLeftJoin() { | |||
return [ | |||
[ | |||
'd1', 'data2', null, null, | |||
['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]], | |||
'`data1` d1 LEFT JOIN `data2` ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', null, | |||
['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]], | |||
'`data1` d1 LEFT JOIN `data2` d2 ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`', | |||
['d1' => [['joinType' => 'left', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]], | |||
'`data1` d1 LEFT JOIN `data2` d2 ON d1.`field1` = d2.`field2`' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataLeftJoin | |||
* | |||
* @param string $fromAlias | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param string $condition | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testLeftJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->from('data1', 'd1'); | |||
$this->queryBuilder->leftJoin( | |||
$fromAlias, | |||
$tableName, | |||
$tableAlias, | |||
$condition | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('join') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataRightJoin() { | |||
return [ | |||
[ | |||
'd1', 'data2', null, null, | |||
['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => null, 'joinCondition' => null]]], | |||
'`data1` d1 RIGHT JOIN `data2` ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', null, | |||
['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => null]]], | |||
'`data1` d1 RIGHT JOIN `data2` d2 ON ' | |||
], | |||
[ | |||
'd1', 'data2', 'd2', 'd1.`field1` = d2.`field2`', | |||
['d1' => [['joinType' => 'right', 'joinTable' => '`data2`', 'joinAlias' => 'd2', 'joinCondition' => 'd1.`field1` = d2.`field2`']]], | |||
'`data1` d1 RIGHT JOIN `data2` d2 ON d1.`field1` = d2.`field2`' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataRightJoin | |||
* | |||
* @param string $fromAlias | |||
* @param string $tableName | |||
* @param string $tableAlias | |||
* @param string $condition | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testRightJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->from('data1', 'd1'); | |||
$this->queryBuilder->rightJoin( | |||
$fromAlias, | |||
$tableName, | |||
$tableAlias, | |||
$condition | |||
); | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('join') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataSet() { | |||
return [ | |||
['column1', new Literal('value'), null, null, ['`column1` = value'], '`column1` = value'], | |||
['column1', new Parameter(':param'), null, null, ['`column1` = :param'], '`column1` = :param'], | |||
['column1', 'column2', null, null, ['`column1` = `column2`'], '`column1` = `column2`'], | |||
['column1', 'column2', 'column3', new Literal('value'), ['`column1` = `column2`', '`column3` = value'], '`column1` = `column2`, `column3` = value'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataSet | |||
* | |||
* @param string $partOne1 | |||
* @param string $partOne2 | |||
* @param string $partTwo1 | |||
* @param string $partTwo2 | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testSet($partOne1, $partOne2, $partTwo1, $partTwo2, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->update('data'); | |||
$this->queryBuilder->set($partOne1, $partOne2); | |||
if ($partTwo1 !== null) { | |||
$this->queryBuilder->set($partTwo1, $partTwo2); | |||
} | |||
$this->assertSame( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('set') | |||
); | |||
$this->assertSame( | |||
'UPDATE `data` SET ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataWhere() { | |||
return [ | |||
[['where1'], new CompositeExpression('AND', ['where1']), 'where1'], | |||
[['where1', 'where2'], new CompositeExpression('AND', ['where1', 'where2']), '(where1) AND (where2)'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataWhere | |||
* | |||
* @param array $whereArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testWhere($whereArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->select('column'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'where'], | |||
$whereArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('where') | |||
); | |||
$this->assertSame( | |||
'SELECT `column` FROM WHERE ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
/** | |||
* @dataProvider dataWhere | |||
* | |||
* @param array $whereArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testAndWhere($whereArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->select('column'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'andWhere'], | |||
$whereArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('where') | |||
); | |||
$this->assertSame( | |||
'SELECT `column` FROM WHERE ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataOrWhere() { | |||
return [ | |||
[['where1'], new CompositeExpression('OR', ['where1']), 'where1'], | |||
[['where1', 'where2'], new CompositeExpression('OR', ['where1', 'where2']), '(where1) OR (where2)'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataOrWhere | |||
* | |||
* @param array $whereArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testOrWhere($whereArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->select('column'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'orWhere'], | |||
$whereArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('where') | |||
); | |||
$this->assertSame( | |||
'SELECT `column` FROM WHERE ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataGroupBy() { | |||
return [ | |||
[['column1'], ['`column1`'], '`column1`'], | |||
[['column1', 'column2'], ['`column1`', '`column2`'], '`column1`, `column2`'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataGroupBy | |||
* | |||
* @param array $groupByArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testGroupBy($groupByArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->select('column'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'groupBy'], | |||
$groupByArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('groupBy') | |||
); | |||
$this->assertSame( | |||
'SELECT `column` FROM GROUP BY ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataAddGroupBy() { | |||
return [ | |||
[['column2'], ['`column1`', '`column2`'], '`column1`, `column2`'], | |||
[['column2', 'column3'], ['`column1`', '`column2`', '`column3`'], '`column1`, `column2`, `column3`'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataAddGroupBy | |||
* | |||
* @param array $groupByArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testAddGroupBy($groupByArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->select('column'); | |||
$this->queryBuilder->groupBy('column1'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'addGroupBy'], | |||
$groupByArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('groupBy') | |||
); | |||
$this->assertSame( | |||
'SELECT `column` FROM GROUP BY ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataSetValue() { | |||
return [ | |||
['column', 'value', ['`column`' => 'value'], '(`column`) VALUES(value)'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataSetValue | |||
* | |||
* @param string $column | |||
* @param string $value | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testSetValue($column, $value, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->insert('data'); | |||
$this->queryBuilder->setValue($column, $value); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('values') | |||
); | |||
$this->assertSame( | |||
'INSERT INTO `data` ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
/** | |||
* @dataProvider dataSetValue | |||
* | |||
* @param string $column | |||
* @param string $value | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testValues($column, $value, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->insert('data'); | |||
$this->queryBuilder->values([ | |||
$column => $value, | |||
]); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('values') | |||
); | |||
$this->assertSame( | |||
'INSERT INTO `data` ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataHaving() { | |||
return [ | |||
[['condition1'], new CompositeExpression('AND', ['condition1']), 'HAVING condition1'], | |||
[['condition1', 'condition2'], new CompositeExpression('AND', ['condition1', 'condition2']), 'HAVING (condition1) AND (condition2)'], | |||
[ | |||
[new CompositeExpression('OR', ['condition1', 'condition2'])], | |||
new CompositeExpression('OR', ['condition1', 'condition2']), | |||
'HAVING (condition1) OR (condition2)' | |||
], | |||
[ | |||
[new CompositeExpression('AND', ['condition1', 'condition2'])], | |||
new CompositeExpression('AND', ['condition1', 'condition2']), | |||
'HAVING (condition1) AND (condition2)' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataHaving | |||
* | |||
* @param array $havingArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testHaving($havingArguments, $expectedQueryPart, $expectedQuery) { | |||
call_user_func_array( | |||
[$this->queryBuilder, 'having'], | |||
$havingArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('having') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataAndHaving() { | |||
return [ | |||
[['condition2'], new CompositeExpression('AND', ['condition1', 'condition2']), 'HAVING (condition1) AND (condition2)'], | |||
[['condition2', 'condition3'], new CompositeExpression('AND', ['condition1', 'condition2', 'condition3']), 'HAVING (condition1) AND (condition2) AND (condition3)'], | |||
[ | |||
[new CompositeExpression('OR', ['condition2', 'condition3'])], | |||
new CompositeExpression('AND', ['condition1', new CompositeExpression('OR', ['condition2', 'condition3'])]), | |||
'HAVING (condition1) AND ((condition2) OR (condition3))' | |||
], | |||
[ | |||
[new CompositeExpression('AND', ['condition2', 'condition3'])], | |||
new CompositeExpression('AND', ['condition1', new CompositeExpression('AND', ['condition2', 'condition3'])]), | |||
'HAVING (condition1) AND ((condition2) AND (condition3))' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataAndHaving | |||
* | |||
* @param array $havingArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testAndHaving($havingArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->having('condition1'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'andHaving'], | |||
$havingArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('having') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataOrHaving() { | |||
return [ | |||
[['condition2'], new CompositeExpression('OR', ['condition1', 'condition2']), 'HAVING (condition1) OR (condition2)'], | |||
[['condition2', 'condition3'], new CompositeExpression('OR', ['condition1', 'condition2', 'condition3']), 'HAVING (condition1) OR (condition2) OR (condition3)'], | |||
[ | |||
[new CompositeExpression('OR', ['condition2', 'condition3'])], | |||
new CompositeExpression('OR', ['condition1', new CompositeExpression('OR', ['condition2', 'condition3'])]), | |||
'HAVING (condition1) OR ((condition2) OR (condition3))' | |||
], | |||
[ | |||
[new CompositeExpression('AND', ['condition2', 'condition3'])], | |||
new CompositeExpression('OR', ['condition1', new CompositeExpression('AND', ['condition2', 'condition3'])]), | |||
'HAVING (condition1) OR ((condition2) AND (condition3))' | |||
], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataOrHaving | |||
* | |||
* @param array $havingArguments | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testOrHaving($havingArguments, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->having('condition1'); | |||
call_user_func_array( | |||
[$this->queryBuilder, 'orHaving'], | |||
$havingArguments | |||
); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('having') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataOrderBy() { | |||
return [ | |||
['column', null, ['`column` ASC'], 'ORDER BY `column` ASC'], | |||
['column', 'ASC', ['`column` ASC'], 'ORDER BY `column` ASC'], | |||
['column', 'DESC', ['`column` DESC'], 'ORDER BY `column` DESC'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataOrderBy | |||
* | |||
* @param string $sort | |||
* @param string $order | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testOrderBy($sort, $order, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->orderBy($sort, $order); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('orderBy') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
public function dataAddOrderBy() { | |||
return [ | |||
['column2', null, null, ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'], | |||
['column2', null, 'ASC', ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'], | |||
['column2', null, 'DESC', ['`column1` DESC', '`column2` ASC'], 'ORDER BY `column1` DESC, `column2` ASC'], | |||
['column2', 'ASC', null, ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'], | |||
['column2', 'ASC', 'ASC', ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'], | |||
['column2', 'ASC', 'DESC', ['`column1` DESC', '`column2` ASC'], 'ORDER BY `column1` DESC, `column2` ASC'], | |||
['column2', 'DESC', null, ['`column1` ASC', '`column2` DESC'], 'ORDER BY `column1` ASC, `column2` DESC'], | |||
['column2', 'DESC', 'ASC', ['`column1` ASC', '`column2` DESC'], 'ORDER BY `column1` ASC, `column2` DESC'], | |||
['column2', 'DESC', 'DESC', ['`column1` DESC', '`column2` DESC'], 'ORDER BY `column1` DESC, `column2` DESC'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataAddOrderBy | |||
* | |||
* @param string $sort2 | |||
* @param string $order2 | |||
* @param string $order1 | |||
* @param array $expectedQueryPart | |||
* @param string $expectedQuery | |||
*/ | |||
public function testAddOrderBy($sort2, $order2, $order1, $expectedQueryPart, $expectedQuery) { | |||
$this->queryBuilder->orderBy('column1', $order1); | |||
$this->queryBuilder->addOrderBy($sort2, $order2); | |||
$this->assertEquals( | |||
$expectedQueryPart, | |||
$this->queryBuilder->getQueryPart('orderBy') | |||
); | |||
$this->assertSame( | |||
'SELECT FROM ' . $expectedQuery, | |||
$this->queryBuilder->getSQL() | |||
); | |||
} | |||
} |
@@ -0,0 +1,141 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* | |||
* @copyright Copyright (c) 2015, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace Test\DB\QueryBuilder; | |||
use OC\DB\QueryBuilder\Literal; | |||
use OC\DB\QueryBuilder\Parameter; | |||
use OC\DB\QueryBuilder\QuoteHelper; | |||
use OCP\DB\QueryBuilder\ILiteral; | |||
use OCP\DB\QueryBuilder\IParameter; | |||
class QuoteHelperTest extends \Test\TestCase { | |||
/** @var QuoteHelper */ | |||
protected $helper; | |||
protected function setUp() { | |||
parent::setUp(); | |||
$this->helper = new QuoteHelper(); | |||
} | |||
public function dataQuoteColumnName() { | |||
return [ | |||
['column', '`column`'], | |||
[new Literal('literal'), 'literal'], | |||
[new Literal(1), '1'], | |||
[new Parameter(':param'), ':param'], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataQuoteColumnName | |||
* @param mixed $input | |||
* @param string $expected | |||
*/ | |||
public function testQuoteColumnName($input, $expected) { | |||
$this->assertSame( | |||
$expected, | |||
$this->helper->quoteColumnName($input) | |||
); | |||
} | |||
public function dataQuoteColumnNames() { | |||
return [ | |||
// Single case | |||
['d.column', 'd.`column`'], | |||
['column', '`column`'], | |||
[new Literal('literal'), 'literal'], | |||
[new Literal(1), '1'], | |||
[new Parameter(':param'), ':param'], | |||
// Array case | |||
[['column'], ['`column`']], | |||
[[new Literal('literal')], ['literal']], | |||
[[new Literal(1)], ['1']], | |||
[[new Parameter(':param')], [':param']], | |||
// Array mixed cases | |||
[['column1', 'column2'], ['`column1`', '`column2`']], | |||
[['column', new Literal('literal')], ['`column`', 'literal']], | |||
[['column', new Literal(1)], ['`column`', '1']], | |||
[['column', new Parameter(':param')], ['`column`', ':param']], | |||
]; | |||
} | |||
/** | |||
* @dataProvider dataQuoteColumnNames | |||
* @param mixed $input | |||
* @param string $expected | |||
*/ | |||
public function testQuoteColumnNames($input, $expected) { | |||
$this->assertSame( | |||
$expected, | |||
$this->helper->quoteColumnNames($input) | |||
); | |||
} | |||
/** | |||
* @param array|string|ILiteral|IParameter $strings string, Literal or Parameter | |||
* @return array|string | |||
*/ | |||
public function quoteColumnNames($strings) { | |||
if (!is_array($strings)) { | |||
return $this->quoteColumnName($strings); | |||
} | |||
$return = []; | |||
foreach ($strings as $string) { | |||
$return[] = $this->quoteColumnName($string); | |||
} | |||
return $return; | |||
} | |||
/** | |||
* @param string|ILiteral|IParameter $string string, Literal or Parameter | |||
* @return string | |||
*/ | |||
public function quoteColumnName($string) { | |||
if ($string instanceof IParameter) { | |||
return $string->getName(); | |||
} | |||
if ($string instanceof ILiteral) { | |||
return $string->getLiteral(); | |||
} | |||
if ($string === null) { | |||
return $string; | |||
} | |||
if (!is_string($string)) { | |||
throw new \InvalidArgumentException('Only strings, Literals and Parameters are allowed'); | |||
} | |||
if (substr_count($string, '.')) { | |||
list($alias, $columnName) = explode('.', $string); | |||
return '`' . $alias . '`.`' . $columnName . '`'; | |||
} | |||
return '`' . $string . '`'; | |||
} | |||
} |
@@ -1335,10 +1335,10 @@ class Test_Share extends \Test\TestCase { | |||
$userSession->method('getUser')->willReturn($user); | |||
$ex = $this->getMockBuilder('\OC\DB\ExpressionBuilder') | |||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder') | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb->method('update')->will($this->returnSelf()); | |||
@@ -1390,10 +1390,10 @@ class Test_Share extends \Test\TestCase { | |||
$userSession->method('getUser')->willReturn($user); | |||
$ex = $this->getMockBuilder('\OC\DB\ExpressionBuilder') | |||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder') | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb->method('update')->will($this->returnSelf()); | |||
@@ -1443,10 +1443,10 @@ class Test_Share extends \Test\TestCase { | |||
$userSession->method('getUser')->willReturn($user); | |||
$ex = $this->getMockBuilder('\OC\DB\ExpressionBuilder') | |||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder') | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb->method('update')->will($this->returnSelf()); | |||
@@ -1496,10 +1496,10 @@ class Test_Share extends \Test\TestCase { | |||
$userSession->method('getUser')->willReturn($user); | |||
$ex = $this->getMockBuilder('\OC\DB\ExpressionBuilder') | |||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder') | |||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$qb->method('update')->will($this->returnSelf()); |