aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/db
diff options
context:
space:
mode:
authorJoas Schilling <nickvergessen@owncloud.com>2015-07-07 17:30:26 +0200
committerJoas Schilling <nickvergessen@owncloud.com>2015-07-21 15:25:47 +0200
commit516f7e8299c309ed909259c90c23cb0ce6a8e4f7 (patch)
tree03c08ccc855031fc81c2ef5e69b9510614b1707a /lib/private/db
parentde348180ae257017a9a2af05dac72286bf262bed (diff)
downloadnextcloud-server-516f7e8299c309ed909259c90c23cb0ce6a8e4f7.tar.gz
nextcloud-server-516f7e8299c309ed909259c90c23cb0ce6a8e4f7.zip
Add unit tests and automatic quoting
Diffstat (limited to 'lib/private/db')
-rw-r--r--lib/private/db/connection.php6
-rw-r--r--lib/private/db/querybuilder/compositeexpression.php (renamed from lib/private/db/compositeexpression.php)8
-rw-r--r--lib/private/db/querybuilder/expressionbuilder.php (renamed from lib/private/db/expressionbuilder.php)46
-rw-r--r--lib/private/db/querybuilder/literal.php40
-rw-r--r--lib/private/db/querybuilder/parameter.php40
-rw-r--r--lib/private/db/querybuilder/querybuilder.php (renamed from lib/private/db/querybuilder.php)276
-rw-r--r--lib/private/db/querybuilder/queryfunction.php40
-rw-r--r--lib/private/db/querybuilder/quotehelper.php75
8 files changed, 438 insertions, 93 deletions
diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php
index 9bb54883bf4..ae5d22bf4d8 100644
--- a/lib/private/db/connection.php
+++ b/lib/private/db/connection.php
@@ -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);
diff --git a/lib/private/db/compositeexpression.php b/lib/private/db/querybuilder/compositeexpression.php
index cc57c524369..523f397e235 100644
--- a/lib/private/db/compositeexpression.php
+++ b/lib/private/db/querybuilder/compositeexpression.php
@@ -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);
diff --git a/lib/private/db/expressionbuilder.php b/lib/private/db/querybuilder/expressionbuilder.php
index f042664d960..cd5b7fbfc54 100644
--- a/lib/private/db/expressionbuilder.php
+++ b/lib/private/db/querybuilder/expressionbuilder.php
@@ -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));
}
}
diff --git a/lib/private/db/querybuilder/literal.php b/lib/private/db/querybuilder/literal.php
new file mode 100644
index 00000000000..361b5ccf3b8
--- /dev/null
+++ b/lib/private/db/querybuilder/literal.php
@@ -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;
+ }
+}
diff --git a/lib/private/db/querybuilder/parameter.php b/lib/private/db/querybuilder/parameter.php
new file mode 100644
index 00000000000..c14b4e21925
--- /dev/null
+++ b/lib/private/db/querybuilder/parameter.php
@@ -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;
+ }
+}
diff --git a/lib/private/db/querybuilder.php b/lib/private/db/querybuilder/querybuilder.php
index 9ae07aeb0fd..fbb2b07bade 100644
--- a/lib/private/db/querybuilder.php
+++ b/lib/private/db/querybuilder/querybuilder.php
@@ -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);
@@ -253,24 +258,6 @@ class QueryBuilder implements IQueryBuilder {
}
/**
- * 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);
}
}
diff --git a/lib/private/db/querybuilder/queryfunction.php b/lib/private/db/querybuilder/queryfunction.php
new file mode 100644
index 00000000000..2a47d83b917
--- /dev/null
+++ b/lib/private/db/querybuilder/queryfunction.php
@@ -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;
+ }
+}
diff --git a/lib/private/db/querybuilder/quotehelper.php b/lib/private/db/querybuilder/quotehelper.php
new file mode 100644
index 00000000000..0735f313abc
--- /dev/null
+++ b/lib/private/db/querybuilder/quotehelper.php
@@ -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 . '`';
+ }
+}