mirror of
https://github.com/nextcloud/server.git
synced 2026-02-20 00:12:30 -05:00
Merge pull request #17413 from owncloud/public-api-querybuilder
Add public api for Doctrine QueryBuilder and ExpressionBuilder
This commit is contained in:
commit
296ed4c276
30 changed files with 4488 additions and 175 deletions
|
|
@ -23,9 +23,9 @@
|
|||
namespace OCA\Encryption;
|
||||
|
||||
|
||||
use OC\DB\Connection;
|
||||
use OC\Files\View;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\ILogger;
|
||||
|
||||
class Migration {
|
||||
|
|
@ -33,7 +33,7 @@ class Migration {
|
|||
private $moduleId;
|
||||
/** @var \OC\Files\View */
|
||||
private $view;
|
||||
/** @var \OC\DB\Connection */
|
||||
/** @var \OCP\IDBConnection */
|
||||
private $connection;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
|
@ -44,10 +44,10 @@ class Migration {
|
|||
/**
|
||||
* @param IConfig $config
|
||||
* @param View $view
|
||||
* @param Connection $connection
|
||||
* @param IDBConnection $connection
|
||||
* @param ILogger $logger
|
||||
*/
|
||||
public function __construct(IConfig $config, View $view, Connection $connection, ILogger $logger) {
|
||||
public function __construct(IConfig $config, View $view, IDBConnection $connection, ILogger $logger) {
|
||||
$this->view = $view;
|
||||
$this->view->getUpdater()->disable();
|
||||
$this->connection = $connection;
|
||||
|
|
@ -66,10 +66,10 @@ class Migration {
|
|||
* update file cache, copy unencrypted_size to the 'size' column
|
||||
*/
|
||||
private function updateFileCache() {
|
||||
$query = $this->connection->createQueryBuilder();
|
||||
$query->update('`*PREFIX*filecache`')
|
||||
->set('`size`', '`unencrypted_size`')
|
||||
->where($query->expr()->eq('`encrypted`', ':encrypted'))
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$query->update('*PREFIX*filecache')
|
||||
->set('size', 'unencrypted_size')
|
||||
->where($query->expr()->eq('encrypted', $query->createParameter('encrypted')))
|
||||
->setParameter('encrypted', 1);
|
||||
$query->execute();
|
||||
}
|
||||
|
|
@ -149,10 +149,10 @@ class Migration {
|
|||
$this->config->deleteAppValue('files_encryption', 'types');
|
||||
$this->config->deleteAppValue('files_encryption', 'enabled');
|
||||
|
||||
$oldAppValues = $this->connection->createQueryBuilder();
|
||||
$oldAppValues = $this->connection->getQueryBuilder();
|
||||
$oldAppValues->select('*')
|
||||
->from('`*PREFIX*appconfig`')
|
||||
->where($oldAppValues->expr()->eq('`appid`', ':appid'))
|
||||
->from('*PREFIX*appconfig')
|
||||
->where($oldAppValues->expr()->eq('appid', $oldAppValues->createParameter('appid')))
|
||||
->setParameter('appid', 'files_encryption');
|
||||
$appSettings = $oldAppValues->execute();
|
||||
|
||||
|
|
@ -164,10 +164,10 @@ class Migration {
|
|||
}
|
||||
}
|
||||
|
||||
$oldPreferences = $this->connection->createQueryBuilder();
|
||||
$oldPreferences = $this->connection->getQueryBuilder();
|
||||
$oldPreferences->select('*')
|
||||
->from('`*PREFIX*preferences`')
|
||||
->where($oldPreferences->expr()->eq('`appid`', ':appid'))
|
||||
->from('*PREFIX*preferences')
|
||||
->where($oldPreferences->expr()->eq('appid', $oldPreferences->createParameter('appid')))
|
||||
->setParameter('appid', 'files_encryption');
|
||||
$preferenceSettings = $oldPreferences->execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -288,16 +288,16 @@ class MigrationTest extends \Test\TestCase {
|
|||
|
||||
// delete default values set by the encryption app during initialization
|
||||
|
||||
/** @var \OC\DB\Connection $connection */
|
||||
/** @var \OCP\IDBConnection $connection */
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->delete('`*PREFIX*appconfig`')
|
||||
->where($query->expr()->eq('`appid`', ':appid'))
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->delete('*PREFIX*appconfig')
|
||||
->where($query->expr()->eq('appid', $query->createParameter('appid')))
|
||||
->setParameter('appid', 'encryption');
|
||||
$query->execute();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->delete('`*PREFIX*preferences`')
|
||||
->where($query->expr()->eq('`appid`', ':appid'))
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->delete('*PREFIX*preferences')
|
||||
->where($query->expr()->eq('appid', $query->createParameter('appid')))
|
||||
->setParameter('appid', 'encryption');
|
||||
$query->execute();
|
||||
}
|
||||
|
|
@ -308,10 +308,10 @@ class MigrationTest extends \Test\TestCase {
|
|||
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection(), $this->logger);
|
||||
$m->updateDB();
|
||||
|
||||
$this->verifyDB('`*PREFIX*appconfig`', 'files_encryption', 0);
|
||||
$this->verifyDB('`*PREFIX*preferences`', 'files_encryption', 0);
|
||||
$this->verifyDB('`*PREFIX*appconfig`', 'encryption', 3);
|
||||
$this->verifyDB('`*PREFIX*preferences`', 'encryption', 1);
|
||||
$this->verifyDB('*PREFIX*appconfig', 'files_encryption', 0);
|
||||
$this->verifyDB('*PREFIX*preferences', 'files_encryption', 0);
|
||||
$this->verifyDB('*PREFIX*appconfig', 'encryption', 3);
|
||||
$this->verifyDB('*PREFIX*preferences', 'encryption', 1);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -327,20 +327,20 @@ class MigrationTest extends \Test\TestCase {
|
|||
$m = new Migration(\OC::$server->getConfig(), new \OC\Files\View(), \OC::$server->getDatabaseConnection(), $this->logger);
|
||||
$m->updateDB();
|
||||
|
||||
$this->verifyDB('`*PREFIX*appconfig`', 'files_encryption', 0);
|
||||
$this->verifyDB('`*PREFIX*preferences`', 'files_encryption', 0);
|
||||
$this->verifyDB('`*PREFIX*appconfig`', 'encryption', 3);
|
||||
$this->verifyDB('`*PREFIX*preferences`', 'encryption', 1);
|
||||
$this->verifyDB('*PREFIX*appconfig', 'files_encryption', 0);
|
||||
$this->verifyDB('*PREFIX*preferences', 'files_encryption', 0);
|
||||
$this->verifyDB('*PREFIX*appconfig', 'encryption', 3);
|
||||
$this->verifyDB('*PREFIX*preferences', 'encryption', 1);
|
||||
|
||||
// check if the existing values where overwritten correctly
|
||||
/** @var \OC\DB\Connection $connection */
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->select('`configvalue`')
|
||||
->from('`*PREFIX*appconfig`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->select('configvalue')
|
||||
->from('*PREFIX*appconfig')
|
||||
->where($query->expr()->andX(
|
||||
$query->expr()->eq('`appid`', ':appid'),
|
||||
$query->expr()->eq('`configkey`', ':configkey')
|
||||
$query->expr()->eq('appid', $query->createParameter('appid')),
|
||||
$query->expr()->eq('configkey', $query->createParameter('configkey'))
|
||||
))
|
||||
->setParameter('appid', 'encryption')
|
||||
->setParameter('configkey', 'publicShareKeyId');
|
||||
|
|
@ -349,13 +349,13 @@ class MigrationTest extends \Test\TestCase {
|
|||
$this->assertTrue(isset($value['configvalue']));
|
||||
$this->assertSame('share_id', $value['configvalue']);
|
||||
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->select('`configvalue`')
|
||||
->from('`*PREFIX*preferences`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->select('configvalue')
|
||||
->from('*PREFIX*preferences')
|
||||
->where($query->expr()->andX(
|
||||
$query->expr()->eq('`appid`', ':appid'),
|
||||
$query->expr()->eq('`configkey`', ':configkey'),
|
||||
$query->expr()->eq('`userid`', ':userid')
|
||||
$query->expr()->eq('appid', $query->createParameter('appid')),
|
||||
$query->expr()->eq('configkey', $query->createParameter('configkey')),
|
||||
$query->expr()->eq('userid', $query->createParameter('userid'))
|
||||
))
|
||||
->setParameter('appid', 'encryption')
|
||||
->setParameter('configkey', 'recoverKeyEnabled')
|
||||
|
|
@ -368,12 +368,12 @@ class MigrationTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function verifyDB($table, $appid, $expected) {
|
||||
/** @var \OC\DB\Connection $connection */
|
||||
/** @var \OCP\IDBConnection $connection */
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->select('`appid`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->select('appid')
|
||||
->from($table)
|
||||
->where($query->expr()->eq('`appid`', ':appid'))
|
||||
->where($query->expr()->eq('appid', $query->createParameter('appid')))
|
||||
->setParameter('appid', $appid);
|
||||
$result = $query->execute();
|
||||
$values = $result->fetchAll();
|
||||
|
|
@ -392,11 +392,11 @@ class MigrationTest extends \Test\TestCase {
|
|||
|
||||
// check results
|
||||
|
||||
/** @var \OC\DB\Connection $connection */
|
||||
/** @var \OCP\IDBConnection $connection */
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from('`*PREFIX*filecache`');
|
||||
->from('*PREFIX*filecache');
|
||||
$result = $query->execute();
|
||||
$entries = $result->fetchAll();
|
||||
foreach($entries as $entry) {
|
||||
|
|
@ -411,25 +411,25 @@ class MigrationTest extends \Test\TestCase {
|
|||
}
|
||||
|
||||
public function prepareFileCache() {
|
||||
/** @var \OC\DB\Connection $connection */
|
||||
/** @var \OCP\IDBConnection $connection */
|
||||
$connection = \OC::$server->getDatabaseConnection();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->delete('`*PREFIX*filecache`');
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->delete('*PREFIX*filecache');
|
||||
$query->execute();
|
||||
$query = $connection->createQueryBuilder();
|
||||
$result = $query->select('`fileid`')
|
||||
->from('`*PREFIX*filecache`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$result = $query->select('fileid')
|
||||
->from('*PREFIX*filecache')
|
||||
->setMaxResults(1)->execute()->fetchAll();
|
||||
$this->assertEmpty($result);
|
||||
$query = $connection->createQueryBuilder();
|
||||
$query->insert('`*PREFIX*filecache`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$query->insert('*PREFIX*filecache')
|
||||
->values(
|
||||
array(
|
||||
'`storage`' => ':storage',
|
||||
'`path_hash`' => ':path_hash',
|
||||
'`encrypted`' => ':encrypted',
|
||||
'`size`' => ':size',
|
||||
'`unencrypted_size`' => ':unencrypted_size'
|
||||
'storage' => $query->createParameter('storage'),
|
||||
'path_hash' => $query->createParameter('path_hash'),
|
||||
'encrypted' => $query->createParameter('encrypted'),
|
||||
'size' => $query->createParameter('size'),
|
||||
'unencrypted_size' => $query->createParameter('unencrypted_size'),
|
||||
)
|
||||
);
|
||||
for ($i = 1; $i < 20; $i++) {
|
||||
|
|
@ -442,9 +442,9 @@ class MigrationTest extends \Test\TestCase {
|
|||
$query->execute()
|
||||
);
|
||||
}
|
||||
$query = $connection->createQueryBuilder();
|
||||
$result = $query->select('`fileid`')
|
||||
->from('`*PREFIX*filecache`')
|
||||
$query = $connection->getQueryBuilder();
|
||||
$result = $query->select('fileid')
|
||||
->from('*PREFIX*filecache')
|
||||
->execute()->fetchAll();
|
||||
$this->assertSame(19, count($result));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class CleanUp extends Command {
|
|||
/** @var IRootFolder */
|
||||
protected $rootFolder;
|
||||
|
||||
/** @var \OC\DB\Connection */
|
||||
/** @var \OCP\IDBConnection */
|
||||
protected $dbConnection;
|
||||
|
||||
/**
|
||||
|
|
@ -107,9 +107,9 @@ class CleanUp extends Command {
|
|||
\OC_Util::setupFS($uid);
|
||||
if ($this->rootFolder->nodeExists('/' . $uid . '/files_trashbin')) {
|
||||
$this->rootFolder->get('/' . $uid . '/files_trashbin')->delete();
|
||||
$query = $this->dbConnection->createQueryBuilder();
|
||||
$query->delete('`*PREFIX*files_trash`')
|
||||
->where($query->expr()->eq('`user`', ':uid'))
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->delete('*PREFIX*files_trash')
|
||||
->where($query->expr()->eq('user', $query->createParameter('uid')))
|
||||
->setParameter('uid', $uid);
|
||||
$query->execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class CleanUpTest extends TestCase {
|
|||
protected $dbConnection;
|
||||
|
||||
/** @var string */
|
||||
protected $trashTable = '`*PREFIX*files_trash`';
|
||||
protected $trashTable = '*PREFIX*files_trash';
|
||||
|
||||
/** @var string */
|
||||
protected $user0 = 'user0';
|
||||
|
|
@ -64,19 +64,22 @@ class CleanUpTest extends TestCase {
|
|||
* populate files_trash table with 10 dummy values
|
||||
*/
|
||||
public function initTable() {
|
||||
$query = $this->dbConnection->createQueryBuilder();
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$query->delete($this->trashTable)->execute();
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$query->insert($this->trashTable)
|
||||
->values(array(
|
||||
'`id`' => $query->expr()->literal('file'.$i),
|
||||
'`timestamp`' => $query->expr()->literal($i),
|
||||
'`location`' => $query->expr()->literal('.'),
|
||||
'`user`' => $query->expr()->literal('user'.$i%2)
|
||||
'id' => $query->expr()->literal('file'.$i),
|
||||
'timestamp' => $query->expr()->literal($i),
|
||||
'location' => $query->expr()->literal('.'),
|
||||
'user' => $query->expr()->literal('user'.$i%2)
|
||||
))->execute();
|
||||
}
|
||||
$getAllQuery = $this->dbConnection->createQueryBuilder();
|
||||
$result = $getAllQuery->select('`id`')->from($this->trashTable)->execute()->fetchAll();
|
||||
$getAllQuery = $this->dbConnection->getQueryBuilder();
|
||||
$result = $getAllQuery->select('id')
|
||||
->from($this->trashTable)
|
||||
->execute()
|
||||
->fetchAll();
|
||||
$this->assertSame(10, count($result));
|
||||
}
|
||||
|
||||
|
|
@ -106,8 +109,8 @@ class CleanUpTest extends TestCase {
|
|||
if ($nodeExists) {
|
||||
// if the delete operation was execute only files from user1
|
||||
// should be left.
|
||||
$query = $this->dbConnection->createQueryBuilder();
|
||||
$result = $query->select('`user`')
|
||||
$query = $this->dbConnection->getQueryBuilder();
|
||||
$result = $query->select('user')
|
||||
->from($this->trashTable)
|
||||
->execute()->fetchAll();
|
||||
$this->assertSame(5, count($result));
|
||||
|
|
@ -117,8 +120,11 @@ class CleanUpTest extends TestCase {
|
|||
} else {
|
||||
// if no delete operation was execute we should still have all 10
|
||||
// database entries
|
||||
$getAllQuery = $this->dbConnection->createQueryBuilder();
|
||||
$result = $getAllQuery->select('`id`')->from($this->trashTable)->execute()->fetchAll();
|
||||
$getAllQuery = $this->dbConnection->getQueryBuilder();
|
||||
$result = $getAllQuery->select('id')
|
||||
->from($this->trashTable)
|
||||
->execute()
|
||||
->fetchAll();
|
||||
$this->assertSame(10, count($result));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,15 @@ class Db implements IDb {
|
|||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ExpressionBuilder for the connection.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder
|
||||
*/
|
||||
public function getQueryBuilder() {
|
||||
return $this->connection->getQueryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to abstract the ownCloud database access away
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -51,6 +53,56 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a QueryBuilder for the connection.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder
|
||||
*/
|
||||
public function getQueryBuilder() {
|
||||
return new QueryBuilder($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the QueryBuilder for the connection.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Query\QueryBuilder
|
||||
* @deprecated please use $this->getQueryBuilder() instead
|
||||
*/
|
||||
public function createQueryBuilder() {
|
||||
$backtrace = $this->getCallerBacktrace();
|
||||
\OC::$server->getLogger()->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
|
||||
return parent::createQueryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ExpressionBuilder for the connection.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
|
||||
* @deprecated please use $this->getQueryBuilder()->expr() instead
|
||||
*/
|
||||
public function getExpressionBuilder() {
|
||||
$backtrace = $this->getCallerBacktrace();
|
||||
\OC::$server->getLogger()->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
|
||||
return parent::getExpressionBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file and line that called the method where `getCallerBacktrace()` was used
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCallerBacktrace() {
|
||||
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
|
||||
// 0 is the method where we use `getCallerBacktrace`
|
||||
// 1 is the target method which uses the method we want to log
|
||||
if (isset($traces[1])) {
|
||||
return $traces[1]['file'] . ':' . $traces[1]['line'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
92
lib/private/db/querybuilder/compositeexpression.php
Normal file
92
lib/private/db/querybuilder/compositeexpression.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?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\ICompositeExpression;
|
||||
|
||||
class CompositeExpression implements ICompositeExpression, \Countable {
|
||||
/** @var \Doctrine\DBAL\Query\Expression\CompositeExpression */
|
||||
protected $compositeExpression;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \Doctrine\DBAL\Query\Expression\CompositeExpression $compositeExpression
|
||||
*/
|
||||
public function __construct(\Doctrine\DBAL\Query\Expression\CompositeExpression $compositeExpression) {
|
||||
$this->compositeExpression = $compositeExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple parts to composite expression.
|
||||
*
|
||||
* @param array $parts
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function addMultiple(array $parts = array()) {
|
||||
$this->compositeExpression->addMultiple($parts);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an expression to composite expression.
|
||||
*
|
||||
* @param mixed $part
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function add($part) {
|
||||
$this->compositeExpression->add($part);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the amount of expressions on composite expression.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
return $this->compositeExpression->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this composite expression (AND/OR).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->compositeExpression->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the string representation of this composite expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->compositeExpression;
|
||||
}
|
||||
}
|
||||
312
lib/private/db/querybuilder/expressionbuilder.php
Normal file
312
lib/private/db/querybuilder/expressionbuilder.php
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
<?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 Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a conjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) AND (u.role = ?)
|
||||
* $expr->andX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function andX($x = null) {
|
||||
$arguments = func_get_args();
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], $arguments);
|
||||
return new CompositeExpression($compositeExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a disjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) OR (u.role = ?)
|
||||
* $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
*/
|
||||
public function orX($x = null) {
|
||||
$arguments = func_get_args();
|
||||
$compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], $arguments);
|
||||
return new CompositeExpression($compositeExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a comparison expression.
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param string $operator One of the ExpressionBuilder::* constants.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an equality comparison expression with the given arguments.
|
||||
*
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> = <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id = ?
|
||||
* $expr->eq('u.id', '?');
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function eq($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->eq($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a non equality comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <> <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <> 1
|
||||
* $q->where($q->expr()->neq('u.id', '1'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function neq($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->neq($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lower-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> < <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id < ?
|
||||
* $q->where($q->expr()->lt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lt($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->lt($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lower-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <= ?
|
||||
* $q->where($q->expr()->lte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lte($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->lte($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a greater-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> > <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id > ?
|
||||
* $q->where($q->expr()->gt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gt($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->gt($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a greater-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> >= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id >= ?
|
||||
* $q->where($q->expr()->gte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gte($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->gte($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an IS NULL expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be restricted by IS NULL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isNull($x) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
return $this->expressionBuilder->isNull($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an IS NOT NULL expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be restricted by IS NOT NULL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isNotNull($x) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
return $this->expressionBuilder->isNotNull($x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in LIKE() comparison.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function like($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->like($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NOT LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by NOT LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in NOT LIKE() comparison.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function notLike($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnName($y);
|
||||
return $this->expressionBuilder->notLike($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be inspected by IN() comparison.
|
||||
* @param string|array $y The placeholder or the array of values to be used by IN() comparison.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function in($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnNames($y);
|
||||
return $this->expressionBuilder->in($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NOT IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be inspected by NOT IN() comparison.
|
||||
* @param string|array $y The placeholder or the array of values to be used by NOT IN() comparison.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function notIn($x, $y) {
|
||||
$x = $this->helper->quoteColumnName($x);
|
||||
$y = $this->helper->quoteColumnNames($y);
|
||||
return $this->expressionBuilder->notIn($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes a given input parameter.
|
||||
*
|
||||
* @param mixed $input The parameter to be quoted.
|
||||
* @param string|null $type The type of the parameter.
|
||||
*
|
||||
* @return Literal
|
||||
*/
|
||||
public function literal($input, $type = null) {
|
||||
return new Literal($this->expressionBuilder->literal($input, $type));
|
||||
}
|
||||
}
|
||||
40
lib/private/db/querybuilder/literal.php
Normal file
40
lib/private/db/querybuilder/literal.php
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
40
lib/private/db/querybuilder/parameter.php
Normal file
40
lib/private/db/querybuilder/parameter.php
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
987
lib/private/db/querybuilder/querybuilder.php
Normal file
987
lib/private/db/querybuilder/querybuilder.php
Normal file
|
|
@ -0,0 +1,987 @@
|
|||
<?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\IQueryBuilder;
|
||||
use OCP\DB\QueryBuilder\IQueryFunction;
|
||||
use OCP\DB\QueryBuilder\IParameter;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
class QueryBuilder implements IQueryBuilder {
|
||||
|
||||
/** @var \OCP\IDBConnection */
|
||||
private $connection;
|
||||
|
||||
/** @var \Doctrine\DBAL\Query\QueryBuilder */
|
||||
private $queryBuilder;
|
||||
|
||||
/** @var QuoteHelper */
|
||||
private $helper;
|
||||
|
||||
/**
|
||||
* Initializes a new QueryBuilder.
|
||||
*
|
||||
* @param \OCP\IDBConnection $connection
|
||||
*/
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection);
|
||||
$this->helper = new QuoteHelper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
* This producer method is intended for convenient inline usage. Example:
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where($qb->expr()->eq('u.id', 1));
|
||||
* </code>
|
||||
*
|
||||
* For more complex expression construction, consider storing the expression
|
||||
* builder object in a local variable.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder
|
||||
*/
|
||||
public function expr() {
|
||||
return new ExpressionBuilder($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the currently built query.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->queryBuilder->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated DBAL Connection for this query builder.
|
||||
*
|
||||
* @return \OCP\IDBConnection
|
||||
*/
|
||||
public function getConnection() {
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of this query builder instance.
|
||||
*
|
||||
* @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
|
||||
*/
|
||||
public function getState() {
|
||||
return $this->queryBuilder->getState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes this query using the bound parameters and their types.
|
||||
*
|
||||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
|
||||
* for insert, update and delete statements.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Driver\Statement|int
|
||||
*/
|
||||
public function execute() {
|
||||
return $this->queryBuilder->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete SQL string formed by the current specifications of this QueryBuilder.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* echo $qb->getSQL(); // SELECT u FROM User u
|
||||
* </code>
|
||||
*
|
||||
* @return string The SQL query string.
|
||||
*/
|
||||
public function getSQL() {
|
||||
return $this->queryBuilder->getSQL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a query parameter for the query being constructed.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = :user_id')
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @param string|integer $key The parameter position or name.
|
||||
* @param mixed $value The parameter value.
|
||||
* @param string|null $type One of the PDO::PARAM_* constants.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameter($key, $value, $type = null) {
|
||||
$this->queryBuilder->setParameter($key, $value, $type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a collection of query parameters for the query being constructed.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = :user_id1 OR u.id = :user_id2')
|
||||
* ->setParameters(array(
|
||||
* ':user_id1' => 1,
|
||||
* ':user_id2' => 2
|
||||
* ));
|
||||
* </code>
|
||||
*
|
||||
* @param array $params The query parameters to set.
|
||||
* @param array $types The query parameters types to set.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setParameters(array $params, array $types = array()) {
|
||||
$this->queryBuilder->setParameters($params, $types);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all defined query parameters for the query being constructed indexed by parameter index or name.
|
||||
*
|
||||
* @return array The currently defined query parameters indexed by parameter index or name.
|
||||
*/
|
||||
public function getParameters() {
|
||||
return $this->queryBuilder->getParameters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a (previously set) query parameter of the query being constructed.
|
||||
*
|
||||
* @param mixed $key The key (index or name) of the bound parameter.
|
||||
*
|
||||
* @return mixed The value of the bound parameter.
|
||||
*/
|
||||
public function getParameter($key) {
|
||||
return $this->queryBuilder->getParameter($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
|
||||
*
|
||||
* @return array The currently defined query parameter types indexed by parameter index or name.
|
||||
*/
|
||||
public function getParameterTypes() {
|
||||
return $this->queryBuilder->getParameterTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a (previously set) query parameter type of the query being constructed.
|
||||
*
|
||||
* @param mixed $key The key (index or name) of the bound parameter type.
|
||||
*
|
||||
* @return mixed The value of the bound parameter type.
|
||||
*/
|
||||
public function getParameterType($key) {
|
||||
return $this->queryBuilder->getParameterType($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
* @param integer $firstResult The first result to return.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setFirstResult($firstResult) {
|
||||
$this->queryBuilder->setFirstResult($firstResult);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position of the first result the query object was set to retrieve (the "offset").
|
||||
* Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
|
||||
*
|
||||
* @return integer The position of the first result.
|
||||
*/
|
||||
public function getFirstResult() {
|
||||
return $this->queryBuilder->getFirstResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum number of results to retrieve (the "limit").
|
||||
*
|
||||
* NOTE: Setting max results to "0" will cause mixed behaviour. While most
|
||||
* of the databases will just return an empty result set, Oracle will return
|
||||
* all entries.
|
||||
*
|
||||
* @param integer $maxResults The maximum number of results to retrieve.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setMaxResults($maxResults) {
|
||||
$this->queryBuilder->setMaxResults($maxResults);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of results the query object was set to retrieve (the "limit").
|
||||
* Returns NULL if {@link setMaxResults} was not applied to this query builder.
|
||||
*
|
||||
* @return integer The maximum number of results.
|
||||
*/
|
||||
public function getMaxResults() {
|
||||
return $this->queryBuilder->getMaxResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies an item that is to be returned in the query result.
|
||||
* Replaces any previously specified selections, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id', 'p.id')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select The selection expressions.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function select($select = null) {
|
||||
$selects = is_array($select) ? $select : func_get_args();
|
||||
|
||||
$this->queryBuilder->select(
|
||||
$this->helper->quoteColumnNames($selects)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item that is to be returned in the query result.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id')
|
||||
* ->addSelect('p.id')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select The selection expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addSelect($select = null) {
|
||||
$selects = is_array($select) ? $select : func_get_args();
|
||||
|
||||
$this->queryBuilder->addSelect(
|
||||
$this->helper->quoteColumnNames($selects)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the query being built into a bulk delete query that ranges over
|
||||
* a certain table.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->delete('users', 'u')
|
||||
* ->where('u.id = :user_id');
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function delete($delete = null, $alias = null) {
|
||||
$this->queryBuilder->delete(
|
||||
$this->helper->quoteColumnName($delete),
|
||||
$alias
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the query being built into a bulk update query that ranges over
|
||||
* a certain table
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function update($update = null, $alias = null) {
|
||||
$this->queryBuilder->update(
|
||||
$this->helper->quoteColumnName($update),
|
||||
$alias
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the query being built into an insert query that inserts into
|
||||
* a certain table
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?',
|
||||
* 'password' => '?'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @param string $insert The table into which the rows should be inserted.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function insert($insert = null) {
|
||||
$this->queryBuilder->insert(
|
||||
$this->helper->quoteColumnName($insert)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a query root corresponding to the table identified by the
|
||||
* given alias, forming a cartesian product with any existing query roots.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id')
|
||||
* ->from('users', 'u')
|
||||
* </code>
|
||||
*
|
||||
* @param string $from The table.
|
||||
* @param string|null $alias The alias of the table.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function from($from, $alias = null) {
|
||||
$this->queryBuilder->from(
|
||||
$this->helper->quoteColumnName($from),
|
||||
$alias
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function join($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->queryBuilder->join(
|
||||
$fromAlias,
|
||||
$this->helper->quoteColumnName($join),
|
||||
$alias,
|
||||
$condition
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function innerJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->queryBuilder->innerJoin(
|
||||
$fromAlias,
|
||||
$this->helper->quoteColumnName($join),
|
||||
$alias,
|
||||
$condition
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a left join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function leftJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->queryBuilder->leftJoin(
|
||||
$fromAlias,
|
||||
$this->helper->quoteColumnName($join),
|
||||
$alias,
|
||||
$condition
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a right join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function rightJoin($fromAlias, $join, $alias, $condition = null) {
|
||||
$this->queryBuilder->rightJoin(
|
||||
$fromAlias,
|
||||
$this->helper->quoteColumnName($join),
|
||||
$alias,
|
||||
$condition
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new value for a column in a bulk update query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The column to set.
|
||||
* @param string $value The value, expression, placeholder, etc.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
$this->queryBuilder->set(
|
||||
$this->helper->quoteColumnName($key),
|
||||
$this->helper->quoteColumnName($value)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies one or more restrictions to the query result.
|
||||
* Replaces any previously specified restrictions, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = ?');
|
||||
*
|
||||
* // You can optionally programatically build and/or expressions
|
||||
* $qb = $conn->getQueryBuilder();
|
||||
*
|
||||
* $or = $qb->expr()->orx();
|
||||
* $or->add($qb->expr()->eq('u.id', 1));
|
||||
* $or->add($qb->expr()->eq('u.id', 2));
|
||||
*
|
||||
* $qb->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where($or);
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $predicates The restriction predicates.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function where($predicates) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'where'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* conjunction with any previously specified restrictions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.username LIKE ?')
|
||||
* ->andWhere('u.is_active = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The query restrictions.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*
|
||||
* @see where()
|
||||
*/
|
||||
public function andWhere($where) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'andWhere'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* disjunction with any previously specified restrictions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = 1')
|
||||
* ->orWhere('u.id = 2');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The WHERE statement.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*
|
||||
* @see where()
|
||||
*/
|
||||
public function orWhere($where) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'orWhere'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a grouping over the results of the query.
|
||||
* Replaces any previously specified groupings, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->groupBy('u.id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $groupBy The grouping expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function groupBy($groupBy) {
|
||||
$groupBys = is_array($groupBy) ? $groupBy : func_get_args();
|
||||
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'groupBy'],
|
||||
$this->helper->quoteColumnNames($groupBys)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a grouping expression to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->groupBy('u.lastLogin');
|
||||
* ->addGroupBy('u.createdAt')
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $groupBy The grouping expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addGroupBy($groupBy) {
|
||||
$groupBys = is_array($groupBy) ? $groupBy : func_get_args();
|
||||
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'addGroupBy'],
|
||||
$this->helper->quoteColumnNames($groupBys)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value for a column in an insert query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?'
|
||||
* )
|
||||
* )
|
||||
* ->setValue('password', '?');
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function setValue($column, $value) {
|
||||
$this->queryBuilder->setValue(
|
||||
$this->helper->quoteColumnName($column),
|
||||
$value
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies values for an insert query indexed by column names.
|
||||
* Replaces any previous values, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?',
|
||||
* 'password' => '?'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @param array $values The values to specify for the insert query indexed by column names.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function values(array $values) {
|
||||
$quotedValues = [];
|
||||
foreach ($values as $key => $value) {
|
||||
$quotedValues[$this->helper->quoteColumnName($key)] = $value;
|
||||
}
|
||||
|
||||
$this->queryBuilder->values($quotedValues);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a restriction over the groups of the query.
|
||||
* Replaces any previous having restrictions, if any.
|
||||
*
|
||||
* @param mixed $having The restriction over the groups.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function having($having) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'having'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* conjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having The restriction to append.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function andHaving($having) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'andHaving'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* disjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having The restriction to add.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function orHaving($having) {
|
||||
call_user_func_array(
|
||||
[$this->queryBuilder, 'orHaving'],
|
||||
func_get_args()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies an ordering for the query results.
|
||||
* Replaces any previously specified orderings, if any.
|
||||
*
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function orderBy($sort, $order = null) {
|
||||
$this->queryBuilder->orderBy(
|
||||
$this->helper->quoteColumnName($sort),
|
||||
$order
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ordering to the query results.
|
||||
*
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function addOrderBy($sort, $order = null) {
|
||||
$this->queryBuilder->addOrderBy(
|
||||
$this->helper->quoteColumnName($sort),
|
||||
$order
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a query part by its name.
|
||||
*
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getQueryPart($queryPartName) {
|
||||
return $this->queryBuilder->getQueryPart($queryPartName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all query parts.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParts() {
|
||||
return $this->queryBuilder->getQueryParts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets SQL parts.
|
||||
*
|
||||
* @param array|null $queryPartNames
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function resetQueryParts($queryPartNames = null) {
|
||||
$this->queryBuilder->resetQueryParts($queryPartNames);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a single SQL part.
|
||||
*
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*/
|
||||
public function resetQueryPart($queryPartName) {
|
||||
$this->queryBuilder->resetQueryPart($queryPartName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new named parameter and bind the value $value to it.
|
||||
*
|
||||
* This method provides a shortcut for PDOStatement::bindValue
|
||||
* when using prepared statements.
|
||||
*
|
||||
* The parameter $value specifies the value that you want to bind. If
|
||||
* $placeholder is not provided bindValue() will automatically create a
|
||||
* placeholder for you. An automatic placeholder will be of the name
|
||||
* ':dcValue1', ':dcValue2' etc.
|
||||
*
|
||||
* For more information see {@link http://php.net/pdostatement-bindparam}
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $value = 2;
|
||||
* $q->eq( 'id', $q->bindValue( $value ) );
|
||||
* $stmt = $q->executeQuery(); // executed with 'id = 2'
|
||||
* </code>
|
||||
*
|
||||
* @license New BSD License
|
||||
* @link http://www.zetacomponents.org
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $type
|
||||
* @param string $placeHolder The name to bind with. The string must start with a colon ':'.
|
||||
*
|
||||
* @return IParameter the placeholder name used.
|
||||
*/
|
||||
public function createNamedParameter($value, $type = \PDO::PARAM_STR, $placeHolder = null) {
|
||||
return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new positional parameter and bind the given value to it.
|
||||
*
|
||||
* Attention: If you are using positional parameters with the query builder you have
|
||||
* to be very careful to bind all parameters in the order they appear in the SQL
|
||||
* statement , otherwise they get bound in the wrong order which can lead to serious
|
||||
* bugs in your code.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder();
|
||||
* $qb->select('u.*')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR))
|
||||
* ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR))
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param integer $type
|
||||
*
|
||||
* @return IParameter
|
||||
*/
|
||||
public function createPositionalParameter($value, $type = \PDO::PARAM_STR) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
40
lib/private/db/querybuilder/queryfunction.php
Normal file
40
lib/private/db/querybuilder/queryfunction.php
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
75
lib/private/db/querybuilder/quotehelper.php
Normal file
75
lib/private/db/querybuilder/quotehelper.php
Normal file
|
|
@ -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 . '`';
|
||||
}
|
||||
}
|
||||
|
|
@ -103,14 +103,14 @@ class Repair extends BasicEmitter {
|
|||
public static function getRepairSteps() {
|
||||
return array(
|
||||
new RepairMimeTypes(),
|
||||
new RepairLegacyStorages(\OC::$server->getConfig(), \OC_DB::getConnection()),
|
||||
new RepairLegacyStorages(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
|
||||
new RepairConfig(),
|
||||
new AssetCache(),
|
||||
new FillETags(\OC_DB::getConnection()),
|
||||
new CleanTags(\OC_DB::getConnection()),
|
||||
new DropOldTables(\OC_DB::getConnection()),
|
||||
new FillETags(\OC::$server->getDatabaseConnection()),
|
||||
new CleanTags(\OC::$server->getDatabaseConnection()),
|
||||
new DropOldTables(\OC::$server->getDatabaseConnection()),
|
||||
new DropOldJobs(\OC::$server->getJobList()),
|
||||
new RemoveGetETagEntries(\OC_DB::getConnection()),
|
||||
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
namespace OC\Share;
|
||||
|
||||
use OCP\IUserSession;
|
||||
use OC\DB\Connection;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IConfig;
|
||||
|
||||
/**
|
||||
|
|
@ -1195,17 +1195,17 @@ class Share extends Constants {
|
|||
/**
|
||||
* Retrieve the owner of a connection
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @param IDBConnection $connection
|
||||
* @param int $shareId
|
||||
* @throws \Exception
|
||||
* @return string uid of share owner
|
||||
*/
|
||||
private static function getShareOwner(Connection $connection, $shareId) {
|
||||
$qb = $connection->createQueryBuilder();
|
||||
private static function getShareOwner(IDBConnection $connection, $shareId) {
|
||||
$qb = $connection->getQueryBuilder();
|
||||
|
||||
$qb->select('`uid_owner`')
|
||||
->from('`*PREFIX*share`')
|
||||
->where('`id` = :shareId')
|
||||
$qb->select('uid_owner')
|
||||
->from('*PREFIX*share')
|
||||
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
|
||||
->setParameter(':shareId', $shareId);
|
||||
$result = $qb->execute();
|
||||
$result = $result->fetch();
|
||||
|
|
@ -1221,15 +1221,15 @@ class Share extends Constants {
|
|||
* Set expiration date for a share
|
||||
*
|
||||
* @param IUserSession $userSession
|
||||
* @param Connection $connection
|
||||
* @param IDBConnection $connection
|
||||
* @param IConfig $config
|
||||
* @param int $shareId
|
||||
* @param string $password
|
||||
* @throws \Exception
|
||||
* @return boolean
|
||||
*/
|
||||
public static function setPassword(IUserSession $userSession,
|
||||
Connection $connection,
|
||||
public static function setPassword(IUserSession $userSession,
|
||||
IDBConnection $connection,
|
||||
IConfig $config,
|
||||
$shareId, $password) {
|
||||
$user = $userSession->getUser();
|
||||
|
|
@ -1252,10 +1252,10 @@ class Share extends Constants {
|
|||
throw new \Exception('Cannot remove password');
|
||||
}
|
||||
|
||||
$qb = $connection->createQueryBuilder();
|
||||
$qb->update('`*PREFIX*share`')
|
||||
->set('`share_with`', ':pass')
|
||||
->where('`id` = :shareId')
|
||||
$qb = $connection->getQueryBuilder();
|
||||
$qb->update('*PREFIX*share')
|
||||
->set('share_with', $qb->createParameter('pass'))
|
||||
->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
|
||||
->setParameter(':pass', is_null($password) ? null : \OC::$server->getHasher()->hash($password))
|
||||
->setParameter(':shareId', $shareId);
|
||||
|
||||
|
|
|
|||
64
lib/public/db/querybuilder/icompositeexpression.php
Normal file
64
lib/public/db/querybuilder/icompositeexpression.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* This class provides a wrapper around Doctrine's CompositeExpression
|
||||
* @since 8.2.0
|
||||
*/
|
||||
interface ICompositeExpression {
|
||||
/**
|
||||
* Adds multiple parts to composite expression.
|
||||
*
|
||||
* @param array $parts
|
||||
*
|
||||
* @return \OCP\DB\ICompositeExpression
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function addMultiple(array $parts = array());
|
||||
|
||||
/**
|
||||
* Adds an expression to composite expression.
|
||||
*
|
||||
* @param mixed $part
|
||||
*
|
||||
* @return \OCP\DB\ICompositeExpression
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function add($part);
|
||||
|
||||
/**
|
||||
* Retrieves the amount of expressions on composite expression.
|
||||
*
|
||||
* @return integer
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Returns the type of this composite expression (AND/OR).
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getType();
|
||||
}
|
||||
252
lib/public/db/querybuilder/iexpressionbuilder.php
Normal file
252
lib/public/db/querybuilder/iexpressionbuilder.php
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* This class provides a wrapper around Doctrine's ExpressionBuilder
|
||||
* @since 8.2.0
|
||||
*/
|
||||
interface IExpressionBuilder {
|
||||
/**
|
||||
* Creates a conjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) AND (u.role = ?)
|
||||
* $expr->andX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function andX($x = null);
|
||||
|
||||
/**
|
||||
* Creates a disjunction of the given boolean expressions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [php]
|
||||
* // (u.type = ?) OR (u.role = ?)
|
||||
* $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?'));
|
||||
*
|
||||
* @param mixed $x Optional clause. Defaults = null, but requires
|
||||
* at least one defined when converting to string.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\ICompositeExpression
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function orX($x = null);
|
||||
|
||||
/**
|
||||
* Creates a comparison expression.
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param string $operator One of the ExpressionBuilder::* constants.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function comparison($x, $operator, $y);
|
||||
|
||||
/**
|
||||
* Creates an equality comparison expression with the given arguments.
|
||||
*
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> = <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id = ?
|
||||
* $expr->eq('u.id', '?');
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function eq($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a non equality comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <> <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <> 1
|
||||
* $q->where($q->expr()->neq('u.id', '1'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function neq($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a lower-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> < <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id < ?
|
||||
* $q->where($q->expr()->lt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function lt($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a lower-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> <= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id <= ?
|
||||
* $q->where($q->expr()->lte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function lte($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a greater-than comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> > <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id > ?
|
||||
* $q->where($q->expr()->gt('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function gt($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a greater-than-equal comparison expression with the given arguments.
|
||||
* First argument is considered the left expression and the second is the right expression.
|
||||
* When converted to string, it will generated a <left expr> >= <right expr>. Example:
|
||||
*
|
||||
* [php]
|
||||
* // u.id >= ?
|
||||
* $q->where($q->expr()->gte('u.id', '?'));
|
||||
*
|
||||
* @param mixed $x The left expression.
|
||||
* @param mixed $y The right expression.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function gte($x, $y);
|
||||
|
||||
/**
|
||||
* Creates an IS NULL expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be restricted by IS NULL.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function isNull($x);
|
||||
|
||||
/**
|
||||
* Creates an IS NOT NULL expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be restricted by IS NOT NULL.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function isNotNull($x);
|
||||
|
||||
/**
|
||||
* Creates a LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in LIKE() comparison.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function like($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a NOT LIKE() comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x Field in string format to be inspected by NOT LIKE() comparison.
|
||||
* @param mixed $y Argument to be used in NOT LIKE() comparison.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function notLike($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be inspected by IN() comparison.
|
||||
* @param string|array $y The placeholder or the array of values to be used by IN() comparison.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function in($x, $y);
|
||||
|
||||
/**
|
||||
* Creates a NOT IN () comparison expression with the given arguments.
|
||||
*
|
||||
* @param string $x The field in string format to be inspected by NOT IN() comparison.
|
||||
* @param string|array $y The placeholder or the array of values to be used by NOT IN() comparison.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function notIn($x, $y);
|
||||
|
||||
/**
|
||||
* Quotes a given input parameter.
|
||||
*
|
||||
* @param mixed $input The parameter to be quoted.
|
||||
* @param string|null $type The type of the parameter.
|
||||
*
|
||||
* @return string
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function literal($input, $type = null);
|
||||
}
|
||||
29
lib/public/db/querybuilder/iliteral.php
Normal file
29
lib/public/db/querybuilder/iliteral.php
Normal file
|
|
@ -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();
|
||||
}
|
||||
29
lib/public/db/querybuilder/iparameter.php
Normal file
29
lib/public/db/querybuilder/iparameter.php
Normal file
|
|
@ -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();
|
||||
}
|
||||
772
lib/public/db/querybuilder/iquerybuilder.php
Normal file
772
lib/public/db/querybuilder/iquerybuilder.php
Normal file
|
|
@ -0,0 +1,772 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* This class provides a wrapper around Doctrine's QueryBuilder
|
||||
* @since 8.2.0
|
||||
*/
|
||||
interface IQueryBuilder {
|
||||
/**
|
||||
* Gets an ExpressionBuilder used for object-oriented construction of query expressions.
|
||||
* This producer method is intended for convenient inline usage. Example:
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where($qb->expr()->eq('u.id', 1));
|
||||
* </code>
|
||||
*
|
||||
* For more complex expression construction, consider storing the expression
|
||||
* builder object in a local variable.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function expr();
|
||||
|
||||
/**
|
||||
* Gets the type of the currently built query.
|
||||
*
|
||||
* @return integer
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Gets the associated DBAL Connection for this query builder.
|
||||
*
|
||||
* @return \OCP\IDBConnection
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getConnection();
|
||||
|
||||
/**
|
||||
* Gets the state of this query builder instance.
|
||||
*
|
||||
* @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getState();
|
||||
|
||||
/**
|
||||
* Executes this query using the bound parameters and their types.
|
||||
*
|
||||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
|
||||
* for insert, update and delete statements.
|
||||
*
|
||||
* @return \Doctrine\DBAL\Driver\Statement|int
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function execute();
|
||||
|
||||
/**
|
||||
* Gets the complete SQL string formed by the current specifications of this QueryBuilder.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('User', 'u')
|
||||
* echo $qb->getSQL(); // SELECT u FROM User u
|
||||
* </code>
|
||||
*
|
||||
* @return string The SQL query string.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getSQL();
|
||||
|
||||
/**
|
||||
* Sets a query parameter for the query being constructed.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = :user_id')
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @param string|integer $key The parameter position or name.
|
||||
* @param mixed $value The parameter value.
|
||||
* @param string|null $type One of the PDO::PARAM_* constants.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function setParameter($key, $value, $type = null);
|
||||
|
||||
/**
|
||||
* Sets a collection of query parameters for the query being constructed.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = :user_id1 OR u.id = :user_id2')
|
||||
* ->setParameters(array(
|
||||
* ':user_id1' => 1,
|
||||
* ':user_id2' => 2
|
||||
* ));
|
||||
* </code>
|
||||
*
|
||||
* @param array $params The query parameters to set.
|
||||
* @param array $types The query parameters types to set.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function setParameters(array $params, array $types = array());
|
||||
|
||||
/**
|
||||
* Gets all defined query parameters for the query being constructed indexed by parameter index or name.
|
||||
*
|
||||
* @return array The currently defined query parameters indexed by parameter index or name.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getParameters();
|
||||
|
||||
/**
|
||||
* Gets a (previously set) query parameter of the query being constructed.
|
||||
*
|
||||
* @param mixed $key The key (index or name) of the bound parameter.
|
||||
*
|
||||
* @return mixed The value of the bound parameter.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getParameter($key);
|
||||
|
||||
/**
|
||||
* Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
|
||||
*
|
||||
* @return array The currently defined query parameter types indexed by parameter index or name.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getParameterTypes();
|
||||
|
||||
/**
|
||||
* Gets a (previously set) query parameter type of the query being constructed.
|
||||
*
|
||||
* @param mixed $key The key (index or name) of the bound parameter type.
|
||||
*
|
||||
* @return mixed The value of the bound parameter type.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getParameterType($key);
|
||||
|
||||
/**
|
||||
* Sets the position of the first result to retrieve (the "offset").
|
||||
*
|
||||
* @param integer $firstResult The first result to return.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function setFirstResult($firstResult);
|
||||
|
||||
/**
|
||||
* Gets the position of the first result the query object was set to retrieve (the "offset").
|
||||
* Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
|
||||
*
|
||||
* @return integer The position of the first result.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getFirstResult();
|
||||
|
||||
/**
|
||||
* Sets the maximum number of results to retrieve (the "limit").
|
||||
*
|
||||
* @param integer $maxResults The maximum number of results to retrieve.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function setMaxResults($maxResults);
|
||||
|
||||
/**
|
||||
* Gets the maximum number of results the query object was set to retrieve (the "limit").
|
||||
* Returns NULL if {@link setMaxResults} was not applied to this query builder.
|
||||
*
|
||||
* @return integer The maximum number of results.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getMaxResults();
|
||||
|
||||
/**
|
||||
* Specifies an item that is to be returned in the query result.
|
||||
* Replaces any previously specified selections, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id', 'p.id')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select The selection expressions.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function select($select = null);
|
||||
|
||||
/**
|
||||
* Adds an item that is to be returned in the query result.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id')
|
||||
* ->addSelect('p.id')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $select The selection expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function addSelect($select = null);
|
||||
|
||||
/**
|
||||
* Turns the query being built into a bulk delete query that ranges over
|
||||
* a certain table.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->delete('users', 'u')
|
||||
* ->where('u.id = :user_id');
|
||||
* ->setParameter(':user_id', 1);
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function delete($delete = null, $alias = null);
|
||||
|
||||
/**
|
||||
* Turns the query being built into a bulk update query that ranges over
|
||||
* a certain table
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function update($update = null, $alias = null);
|
||||
|
||||
/**
|
||||
* Turns the query being built into an insert query that inserts into
|
||||
* a certain table
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?',
|
||||
* 'password' => '?'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @param string $insert The table into which the rows should be inserted.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function insert($insert = null);
|
||||
|
||||
/**
|
||||
* Creates and adds a query root corresponding to the table identified by the
|
||||
* given alias, forming a cartesian product with any existing query roots.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.id')
|
||||
* ->from('users', 'u')
|
||||
* </code>
|
||||
*
|
||||
* @param string $from The table.
|
||||
* @param string|null $alias The alias of the table.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function from($from, $alias = null);
|
||||
|
||||
/**
|
||||
* Creates and adds a join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function join($fromAlias, $join, $alias, $condition = null);
|
||||
|
||||
/**
|
||||
* Creates and adds a join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function innerJoin($fromAlias, $join, $alias, $condition = null);
|
||||
|
||||
/**
|
||||
* Creates and adds a left join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function leftJoin($fromAlias, $join, $alias, $condition = null);
|
||||
|
||||
/**
|
||||
* Creates and adds a right join to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param string $fromAlias The alias that points to a from clause.
|
||||
* @param string $join The table name to join.
|
||||
* @param string $alias The alias of the join table.
|
||||
* @param string $condition The condition for the join.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function rightJoin($fromAlias, $join, $alias, $condition = null);
|
||||
|
||||
/**
|
||||
* Sets a new value for a column in a bulk update query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where('u.id = ?');
|
||||
* </code>
|
||||
*
|
||||
* @param string $key The column to set.
|
||||
* @param string $value The value, expression, placeholder, etc.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function set($key, $value);
|
||||
|
||||
/**
|
||||
* Specifies one or more restrictions to the query result.
|
||||
* Replaces any previously specified restrictions, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = ?');
|
||||
*
|
||||
* // You can optionally programatically build and/or expressions
|
||||
* $qb = $conn->getQueryBuilder();
|
||||
*
|
||||
* $or = $qb->expr()->orx();
|
||||
* $or->add($qb->expr()->eq('u.id', 1));
|
||||
* $or->add($qb->expr()->eq('u.id', 2));
|
||||
*
|
||||
* $qb->update('users', 'u')
|
||||
* ->set('u.password', md5('password'))
|
||||
* ->where($or);
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $predicates The restriction predicates.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function where($predicates);
|
||||
|
||||
/**
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* conjunction with any previously specified restrictions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.username LIKE ?')
|
||||
* ->andWhere('u.is_active = 1');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The query restrictions.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*
|
||||
* @see where()
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function andWhere($where);
|
||||
|
||||
/**
|
||||
* Adds one or more restrictions to the query results, forming a logical
|
||||
* disjunction with any previously specified restrictions.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.id = 1')
|
||||
* ->orWhere('u.id = 2');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $where The WHERE statement.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
*
|
||||
* @see where()
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function orWhere($where);
|
||||
|
||||
/**
|
||||
* Specifies a grouping over the results of the query.
|
||||
* Replaces any previously specified groupings, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->groupBy('u.id');
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $groupBy The grouping expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function groupBy($groupBy);
|
||||
|
||||
/**
|
||||
* Adds a grouping expression to the query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->select('u.name')
|
||||
* ->from('users', 'u')
|
||||
* ->groupBy('u.lastLogin');
|
||||
* ->addGroupBy('u.createdAt')
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $groupBy The grouping expression.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function addGroupBy($groupBy);
|
||||
|
||||
/**
|
||||
* Sets a value for a column in an insert query.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?'
|
||||
* )
|
||||
* )
|
||||
* ->setValue('password', '?');
|
||||
* </code>
|
||||
*
|
||||
* @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\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function setValue($column, $value);
|
||||
|
||||
/**
|
||||
* Specifies values for an insert query indexed by column names.
|
||||
* Replaces any previous values, if any.
|
||||
*
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder()
|
||||
* ->insert('users')
|
||||
* ->values(
|
||||
* array(
|
||||
* 'name' => '?',
|
||||
* 'password' => '?'
|
||||
* )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @param array $values The values to specify for the insert query indexed by column names.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function values(array $values);
|
||||
|
||||
/**
|
||||
* Specifies a restriction over the groups of the query.
|
||||
* Replaces any previous having restrictions, if any.
|
||||
*
|
||||
* @param mixed $having The restriction over the groups.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function having($having);
|
||||
|
||||
/**
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* conjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having The restriction to append.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function andHaving($having);
|
||||
|
||||
/**
|
||||
* Adds a restriction over the groups of the query, forming a logical
|
||||
* disjunction with any existing having restrictions.
|
||||
*
|
||||
* @param mixed $having The restriction to add.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function orHaving($having);
|
||||
|
||||
/**
|
||||
* Specifies an ordering for the query results.
|
||||
* Replaces any previously specified orderings, if any.
|
||||
*
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function orderBy($sort, $order = null);
|
||||
|
||||
/**
|
||||
* Adds an ordering to the query results.
|
||||
*
|
||||
* @param string $sort The ordering expression.
|
||||
* @param string $order The ordering direction.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function addOrderBy($sort, $order = null);
|
||||
|
||||
/**
|
||||
* Gets a query part by its name.
|
||||
*
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return mixed
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getQueryPart($queryPartName);
|
||||
|
||||
/**
|
||||
* Gets all query parts.
|
||||
*
|
||||
* @return array
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getQueryParts();
|
||||
|
||||
/**
|
||||
* Resets SQL parts.
|
||||
*
|
||||
* @param array|null $queryPartNames
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function resetQueryParts($queryPartNames = null);
|
||||
|
||||
/**
|
||||
* Resets a single SQL part.
|
||||
*
|
||||
* @param string $queryPartName
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance.
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function resetQueryPart($queryPartName);
|
||||
|
||||
/**
|
||||
* Creates a new named parameter and bind the value $value to it.
|
||||
*
|
||||
* This method provides a shortcut for PDOStatement::bindValue
|
||||
* when using prepared statements.
|
||||
*
|
||||
* The parameter $value specifies the value that you want to bind. If
|
||||
* $placeholder is not provided bindValue() will automatically create a
|
||||
* placeholder for you. An automatic placeholder will be of the name
|
||||
* ':dcValue1', ':dcValue2' etc.
|
||||
*
|
||||
* For more information see {@link http://php.net/pdostatement-bindparam}
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $value = 2;
|
||||
* $q->eq( 'id', $q->bindValue( $value ) );
|
||||
* $stmt = $q->executeQuery(); // executed with 'id = 2'
|
||||
* </code>
|
||||
*
|
||||
* @license New BSD License
|
||||
* @link http://www.zetacomponents.org
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $type
|
||||
* @param string $placeHolder The name to bind with. The string must start with a colon ':'.
|
||||
*
|
||||
* @return IParameter
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function createNamedParameter($value, $type = \PDO::PARAM_STR, $placeHolder = null);
|
||||
|
||||
/**
|
||||
* Creates a new positional parameter and bind the given value to it.
|
||||
*
|
||||
* Attention: If you are using positional parameters with the query builder you have
|
||||
* to be very careful to bind all parameters in the order they appear in the SQL
|
||||
* statement , otherwise they get bound in the wrong order which can lead to serious
|
||||
* bugs in your code.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $qb = $conn->getQueryBuilder();
|
||||
* $qb->select('u.*')
|
||||
* ->from('users', 'u')
|
||||
* ->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR))
|
||||
* ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR))
|
||||
* </code>
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param integer $type
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
29
lib/public/db/querybuilder/iqueryfunction.php
Normal file
29
lib/public/db/querybuilder/iqueryfunction.php
Normal file
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -40,6 +40,14 @@ namespace OCP;
|
|||
* @since 6.0.0
|
||||
*/
|
||||
interface IDBConnection {
|
||||
/**
|
||||
* Gets the QueryBuilder for the connection.
|
||||
*
|
||||
* @return \OCP\DB\QueryBuilder\IQueryBuilder
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getQueryBuilder();
|
||||
|
||||
/**
|
||||
* Used to abstract the ownCloud database access away
|
||||
* @param string $sql the sql query with ? placeholder for params
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
|
||||
namespace OC\Repair;
|
||||
|
||||
use OC\DB\Connection;
|
||||
use OC\Hooks\BasicEmitter;
|
||||
use OC\RepairStep;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
/**
|
||||
* Class RepairConfig
|
||||
|
|
@ -33,13 +33,13 @@ use OC\RepairStep;
|
|||
*/
|
||||
class CleanTags extends BasicEmitter implements RepairStep {
|
||||
|
||||
/** @var Connection */
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
* @param IDBConnection $connection
|
||||
*/
|
||||
public function __construct(Connection $connection) {
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
|
|
@ -108,16 +108,16 @@ class CleanTags extends BasicEmitter implements RepairStep {
|
|||
* the entry is deleted in the $deleteTable
|
||||
*/
|
||||
protected function deleteOrphanEntries($repairInfo, $deleteTable, $deleteId, $sourceTable, $sourceId, $sourceNullColumn) {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
|
||||
$qb->select('d.`' . $deleteId . '`')
|
||||
->from('`' . $deleteTable . '`', 'd')
|
||||
->leftJoin('d', '`' . $sourceTable . '`', 's', 'd.`' . $deleteId . '` = s.`' . $sourceId . '`')
|
||||
$qb->select('d.' . $deleteId)
|
||||
->from($deleteTable, 'd')
|
||||
->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, ' s.' . $sourceId))
|
||||
->where(
|
||||
'd.`type` = ' . $qb->expr()->literal('files')
|
||||
$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
|
||||
)
|
||||
->andWhere(
|
||||
$qb->expr()->isNull('s.`' . $sourceNullColumn . '`')
|
||||
$qb->expr()->isNull('s.' . $sourceNullColumn)
|
||||
);
|
||||
$result = $qb->execute();
|
||||
|
||||
|
|
@ -129,11 +129,11 @@ class CleanTags extends BasicEmitter implements RepairStep {
|
|||
if (!empty($orphanItems)) {
|
||||
$orphanItemsBatch = array_chunk($orphanItems, 200);
|
||||
foreach ($orphanItemsBatch as $items) {
|
||||
$qb->delete('`' . $deleteTable . '`')
|
||||
$qb->delete($deleteTable)
|
||||
->where(
|
||||
'`type` = ' . $qb->expr()->literal('files')
|
||||
$qb->expr()->eq('type', $qb->expr()->literal('files'))
|
||||
)
|
||||
->andWhere($qb->expr()->in('`' . $deleteId . '`', ':ids'));
|
||||
->andWhere($qb->expr()->in($deleteId, $qb->createParameter('ids')));
|
||||
$qb->setParameter('ids', $items, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
|
||||
$qb->execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,19 +22,19 @@
|
|||
namespace OC\Repair;
|
||||
|
||||
|
||||
use OC\DB\Connection;
|
||||
use OC\Hooks\BasicEmitter;
|
||||
use OC\RepairStep;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
class DropOldTables extends BasicEmitter implements RepairStep {
|
||||
|
||||
/** @var Connection */
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
* @param IDBConnection $connection
|
||||
*/
|
||||
public function __construct(Connection $connection) {
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,16 +22,15 @@
|
|||
|
||||
namespace OC\Repair;
|
||||
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use OC\Hooks\BasicEmitter;
|
||||
|
||||
class FillETags extends BasicEmitter implements \OC\RepairStep {
|
||||
|
||||
/** @var \OC\DB\Connection */
|
||||
/** @var \OCP\IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @param \OC\DB\Connection $connection
|
||||
* @param \OCP\IDBConnection $connection
|
||||
*/
|
||||
public function __construct($connection) {
|
||||
$this->connection = $connection;
|
||||
|
|
@ -42,11 +41,11 @@ class FillETags extends BasicEmitter implements \OC\RepairStep {
|
|||
}
|
||||
|
||||
public function run() {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb->update('`*PREFIX*filecache`')
|
||||
->set('`etag`', $qb->expr()->literal('xxx'))
|
||||
->where($qb->expr()->eq('`etag`', $qb->expr()->literal('')))
|
||||
->orWhere($qb->expr()->isNull('`etag`'));
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->update('*PREFIX*filecache')
|
||||
->set('etag', $qb->expr()->literal('xxx'))
|
||||
->where($qb->expr()->eq('etag', $qb->expr()->literal('')))
|
||||
->orWhere($qb->expr()->isNull('etag'));
|
||||
|
||||
$result = $qb->execute();
|
||||
$this->emit('\OC\Repair', 'info', array("ETags have been fixed for $result files/folders."));
|
||||
|
|
|
|||
338
tests/lib/db/querybuilder/expressionbuildertest.php
Normal file
338
tests/lib/db/querybuilder/expressionbuildertest.php
Normal file
|
|
@ -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->assertEquals(
|
||||
$this->doctrineExpressionBuilder->literal($input, $type),
|
||||
$actual->__toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
999
tests/lib/db/querybuilder/querybuildertest.php
Normal file
999
tests/lib/db/querybuilder/querybuildertest.php
Normal file
|
|
@ -0,0 +1,999 @@
|
|||
<?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;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
class QueryBuilderTest extends \Test\TestCase {
|
||||
/** @var QueryBuilder */
|
||||
protected $queryBuilder;
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->connection = \OC::$server->getDatabaseConnection();
|
||||
$this->queryBuilder = new QueryBuilder($this->connection);
|
||||
}
|
||||
|
||||
protected function createTestingRows() {
|
||||
$qB = $this->connection->getQueryBuilder();
|
||||
for ($i = 1; $i < 10; $i++) {
|
||||
$qB->insert('*PREFIX*appconfig')
|
||||
->values([
|
||||
'appid' => $qB->expr()->literal('testFirstResult'),
|
||||
'configkey' => $qB->expr()->literal('testing' . $i),
|
||||
'configvalue' => $qB->expr()->literal(100 - $i),
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTestingRows(QueryBuilder $queryBuilder) {
|
||||
$queryBuilder->select('configvalue')
|
||||
->from('*PREFIX*appconfig')
|
||||
->where($queryBuilder->expr()->eq(
|
||||
'appid',
|
||||
$queryBuilder->expr()->literal('testFirstResult')
|
||||
))
|
||||
->orderBy('configkey', 'ASC');
|
||||
|
||||
$query = $queryBuilder->execute();
|
||||
$rows = [];
|
||||
while ($row = $query->fetch()) {
|
||||
$rows[] = $row['configvalue'];
|
||||
}
|
||||
$query->closeCursor();
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
protected function deleteTestingRows() {
|
||||
$qB = $this->connection->getQueryBuilder();
|
||||
|
||||
$qB->delete('*PREFIX*appconfig')
|
||||
->where($qB->expr()->eq('appid', $qB->expr()->literal('testFirstResult')))
|
||||
->execute();
|
||||
}
|
||||
|
||||
public function dataFirstResult() {
|
||||
return [
|
||||
[null, [99, 98, 97, 96, 95, 94, 93, 92, 91]],
|
||||
[0, [99, 98, 97, 96, 95, 94, 93, 92, 91]],
|
||||
[1, [98, 97, 96, 95, 94, 93, 92, 91]],
|
||||
[5, [94, 93, 92, 91]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataFirstResult
|
||||
*
|
||||
* @param int $firstResult
|
||||
* @param array $expectedSet
|
||||
*/
|
||||
public function testFirstResult($firstResult, $expectedSet) {
|
||||
$this->deleteTestingRows();
|
||||
$this->createTestingRows();
|
||||
|
||||
if ($firstResult !== null) {
|
||||
$this->queryBuilder->setFirstResult($firstResult);
|
||||
|
||||
// FIXME Remove this once Doctrine/DBAL is >2.5.1:
|
||||
// FIXME See https://github.com/doctrine/dbal/pull/782
|
||||
$this->queryBuilder->setMaxResults(100);
|
||||
}
|
||||
|
||||
$this->assertSame(
|
||||
$firstResult,
|
||||
$this->queryBuilder->getFirstResult()
|
||||
);
|
||||
|
||||
$rows = $this->getTestingRows($this->queryBuilder);
|
||||
|
||||
$this->assertCount(sizeof($expectedSet), $rows);
|
||||
$this->assertEquals($expectedSet, $rows);
|
||||
|
||||
$this->deleteTestingRows();
|
||||
}
|
||||
|
||||
public function dataMaxResults() {
|
||||
return [
|
||||
[null, [99, 98, 97, 96, 95, 94, 93, 92, 91]],
|
||||
// Limit 0 gives mixed results: either all entries or none is returned
|
||||
//[0, []],
|
||||
[1, [99]],
|
||||
[5, [99, 98, 97, 96, 95]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataMaxResults
|
||||
*
|
||||
* @param int $maxResult
|
||||
* @param array $expectedSet
|
||||
*/
|
||||
public function testMaxResults($maxResult, $expectedSet) {
|
||||
$this->deleteTestingRows();
|
||||
$this->createTestingRows();
|
||||
|
||||
if ($maxResult !== null) {
|
||||
$this->queryBuilder->setMaxResults($maxResult);
|
||||
}
|
||||
|
||||
$this->assertSame(
|
||||
$maxResult,
|
||||
$this->queryBuilder->getMaxResults()
|
||||
);
|
||||
|
||||
$rows = $this->getTestingRows($this->queryBuilder);
|
||||
|
||||
$this->assertCount(sizeof($expectedSet), $rows);
|
||||
$this->assertEquals($expectedSet, $rows);
|
||||
|
||||
$this->deleteTestingRows();
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
}
|
||||
141
tests/lib/db/querybuilder/quotehelpertest.php
Normal file
141
tests/lib/db/querybuilder/quotehelpertest.php
Normal file
|
|
@ -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 . '`';
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ class CleanTags extends \Test\TestCase {
|
|||
/** @var \OC\RepairStep */
|
||||
protected $repair;
|
||||
|
||||
/** @var \Doctrine\DBAL\Connection */
|
||||
/** @var \OCP\IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var int */
|
||||
|
|
@ -39,14 +39,14 @@ class CleanTags extends \Test\TestCase {
|
|||
}
|
||||
|
||||
protected function cleanUpTables() {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb->delete('`*PREFIX*vcategory`')
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->delete('*PREFIX*vcategory')
|
||||
->execute();
|
||||
|
||||
$qb->delete('`*PREFIX*vcategory_to_object`')
|
||||
$qb->delete('*PREFIX*vcategory_to_object')
|
||||
->execute();
|
||||
|
||||
$qb->delete('`*PREFIX*filecache`')
|
||||
$qb->delete('*PREFIX*filecache')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
|
@ -83,9 +83,9 @@ class CleanTags extends \Test\TestCase {
|
|||
* @param string $message
|
||||
*/
|
||||
protected function assertEntryCount($tableName, $expected, $message = '') {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$result = $qb->select('COUNT(*)')
|
||||
->from('`' . $tableName . '`')
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$result = $qb->select($qb->createFunction('COUNT(*)'))
|
||||
->from($tableName)
|
||||
->execute();
|
||||
|
||||
$this->assertEquals($expected, $result->fetchColumn(), $message);
|
||||
|
|
@ -99,16 +99,16 @@ class CleanTags extends \Test\TestCase {
|
|||
* @return int
|
||||
*/
|
||||
protected function addTagCategory($category, $type) {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb->insert('`*PREFIX*vcategory`')
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->insert('*PREFIX*vcategory')
|
||||
->values([
|
||||
'`uid`' => $qb->createNamedParameter('TestRepairCleanTags'),
|
||||
'`category`' => $qb->createNamedParameter($category),
|
||||
'`type`' => $qb->createNamedParameter($type),
|
||||
'uid' => $qb->createNamedParameter('TestRepairCleanTags'),
|
||||
'category' => $qb->createNamedParameter($category),
|
||||
'type' => $qb->createNamedParameter($type),
|
||||
])
|
||||
->execute();
|
||||
|
||||
return (int) $this->getLastInsertID('`*PREFIX*vcategory`', '`id`');
|
||||
return (int) $this->getLastInsertID('*PREFIX*vcategory', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,12 +118,12 @@ class CleanTags extends \Test\TestCase {
|
|||
* @param string $type
|
||||
*/
|
||||
protected function addTagEntry($objectId, $category, $type) {
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb->insert('`*PREFIX*vcategory_to_object`')
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->insert('*PREFIX*vcategory_to_object')
|
||||
->values([
|
||||
'`objid`' => $qb->createNamedParameter($objectId, \PDO::PARAM_INT),
|
||||
'`categoryid`' => $qb->createNamedParameter($category, \PDO::PARAM_INT),
|
||||
'`type`' => $qb->createNamedParameter($type),
|
||||
'objid' => $qb->createNamedParameter($objectId, \PDO::PARAM_INT),
|
||||
'categoryid' => $qb->createNamedParameter($category, \PDO::PARAM_INT),
|
||||
'type' => $qb->createNamedParameter($type),
|
||||
])
|
||||
->execute();
|
||||
}
|
||||
|
|
@ -137,25 +137,25 @@ class CleanTags extends \Test\TestCase {
|
|||
return $this->createdFile;
|
||||
}
|
||||
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
|
||||
// We create a new file entry and delete it after the test again
|
||||
$fileName = $this->getUniqueID('TestRepairCleanTags', 12);
|
||||
$qb->insert('`*PREFIX*filecache`')
|
||||
$qb->insert('*PREFIX*filecache')
|
||||
->values([
|
||||
'`path`' => $qb->createNamedParameter($fileName),
|
||||
'`path_hash`' => $qb->createNamedParameter(md5($fileName)),
|
||||
'path' => $qb->createNamedParameter($fileName),
|
||||
'path_hash' => $qb->createNamedParameter(md5($fileName)),
|
||||
])
|
||||
->execute();
|
||||
$fileName = $this->getUniqueID('TestRepairCleanTags', 12);
|
||||
$qb->insert('`*PREFIX*filecache`')
|
||||
$qb->insert('*PREFIX*filecache')
|
||||
->values([
|
||||
'`path`' => $qb->createNamedParameter($fileName),
|
||||
'`path_hash`' => $qb->createNamedParameter(md5($fileName)),
|
||||
'path' => $qb->createNamedParameter($fileName),
|
||||
'path_hash' => $qb->createNamedParameter(md5($fileName)),
|
||||
])
|
||||
->execute();
|
||||
|
||||
$this->createdFile = (int) $this->getLastInsertID('`*PREFIX*filecache`', '`fileid`');
|
||||
$this->createdFile = (int) $this->getLastInsertID('*PREFIX*filecache', 'fileid');
|
||||
return $this->createdFile;
|
||||
}
|
||||
|
||||
|
|
@ -174,8 +174,8 @@ class CleanTags extends \Test\TestCase {
|
|||
// FIXME INSTEAD HELP FIXING DOCTRINE
|
||||
// FIXME https://github.com/owncloud/core/issues/13303
|
||||
// FIXME ALSO FIX https://github.com/owncloud/core/commit/2dd85ec984c12d3be401518f22c90d2327bec07a
|
||||
$qb = $this->connection->createQueryBuilder();
|
||||
$result = $qb->select("MAX($idName)")
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$result = $qb->select($qb->createFunction('MAX(`' . $idName . '`)'))
|
||||
->from($tableName)
|
||||
->execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -1286,13 +1286,13 @@ class Test_Share extends \Test\TestCase {
|
|||
->getMock();
|
||||
|
||||
// Find the share ID in the db
|
||||
$qb = $connection->createQueryBuilder();
|
||||
$qb->select('`id`')
|
||||
->from('`*PREFIX*share`')
|
||||
->where('`item_type` = :type')
|
||||
->andWhere('`item_source` = :source')
|
||||
->andWhere('`uid_owner` = :owner')
|
||||
->andWhere('`share_type` = :share_type')
|
||||
$qb = $connection->getQueryBuilder();
|
||||
$qb->select('id')
|
||||
->from('*PREFIX*share')
|
||||
->where($qb->expr()->eq('item_type', $qb->createParameter('type')))
|
||||
->andWhere($qb->expr()->eq('item_source', $qb->createParameter('source')))
|
||||
->andWhere($qb->expr()->eq('uid_owner', $qb->createParameter('owner')))
|
||||
->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type')))
|
||||
->setParameter('type', 'test')
|
||||
->setParameter('source', 'test.txt')
|
||||
->setParameter('owner', $this->user1)
|
||||
|
|
@ -1307,10 +1307,10 @@ class Test_Share extends \Test\TestCase {
|
|||
$this->assertTrue($res);
|
||||
|
||||
// Fetch the hash from the database
|
||||
$qb = $connection->createQueryBuilder();
|
||||
$qb->select('`share_with`')
|
||||
->from('`*PREFIX*share`')
|
||||
->where('`id` = :id')
|
||||
$qb = $connection->getQueryBuilder();
|
||||
$qb->select('share_with')
|
||||
->from('*PREFIX*share')
|
||||
->where($qb->expr()->eq('id', $qb->createParameter('id')))
|
||||
->setParameter('id', $id);
|
||||
$hash = $qb->execute()->fetch()['share_with'];
|
||||
|
||||
|
|
@ -1335,10 +1335,10 @@ class Test_Share extends \Test\TestCase {
|
|||
$userSession->method('getUser')->willReturn($user);
|
||||
|
||||
|
||||
$ex = $this->getMockBuilder('\Doctrine\DBAL\Query\Expression\ExpressionBuilder')
|
||||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb = $this->getMockBuilder('\Doctrine\DBAL\Query\QueryBuilder')
|
||||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb->method('update')->will($this->returnSelf());
|
||||
|
|
@ -1360,7 +1360,7 @@ class Test_Share extends \Test\TestCase {
|
|||
$connection = $this->getMockBuilder('\OC\DB\Connection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$connection->method('createQueryBuilder')->willReturn($qb);
|
||||
$connection->method('getQueryBuilder')->willReturn($qb);
|
||||
|
||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()
|
||||
|
|
@ -1390,10 +1390,10 @@ class Test_Share extends \Test\TestCase {
|
|||
$userSession->method('getUser')->willReturn($user);
|
||||
|
||||
|
||||
$ex = $this->getMockBuilder('\Doctrine\DBAL\Query\Expression\ExpressionBuilder')
|
||||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb = $this->getMockBuilder('\Doctrine\DBAL\Query\QueryBuilder')
|
||||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb->method('update')->will($this->returnSelf());
|
||||
|
|
@ -1415,7 +1415,7 @@ class Test_Share extends \Test\TestCase {
|
|||
$connection = $this->getMockBuilder('\OC\DB\Connection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$connection->method('createQueryBuilder')->willReturn($qb);
|
||||
$connection->method('getQueryBuilder')->willReturn($qb);
|
||||
|
||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()
|
||||
|
|
@ -1443,10 +1443,10 @@ class Test_Share extends \Test\TestCase {
|
|||
$userSession->method('getUser')->willReturn($user);
|
||||
|
||||
|
||||
$ex = $this->getMockBuilder('\Doctrine\DBAL\Query\Expression\ExpressionBuilder')
|
||||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb = $this->getMockBuilder('\Doctrine\DBAL\Query\QueryBuilder')
|
||||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb->method('update')->will($this->returnSelf());
|
||||
|
|
@ -1468,7 +1468,7 @@ class Test_Share extends \Test\TestCase {
|
|||
$connection = $this->getMockBuilder('\OC\DB\Connection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$connection->method('createQueryBuilder')->willReturn($qb);
|
||||
$connection->method('getQueryBuilder')->willReturn($qb);
|
||||
|
||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()
|
||||
|
|
@ -1496,10 +1496,10 @@ class Test_Share extends \Test\TestCase {
|
|||
$userSession->method('getUser')->willReturn($user);
|
||||
|
||||
|
||||
$ex = $this->getMockBuilder('\Doctrine\DBAL\Query\Expression\ExpressionBuilder')
|
||||
$ex = $this->getMockBuilder('\OC\DB\QueryBuilder\ExpressionBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb = $this->getMockBuilder('\Doctrine\DBAL\Query\QueryBuilder')
|
||||
$qb = $this->getMockBuilder('\OC\DB\QueryBuilder\QueryBuilder')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$qb->method('update')->will($this->returnSelf());
|
||||
|
|
@ -1521,7 +1521,7 @@ class Test_Share extends \Test\TestCase {
|
|||
$connection = $this->getMockBuilder('\OC\DB\Connection')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$connection->method('createQueryBuilder')->willReturn($qb);
|
||||
$connection->method('getQueryBuilder')->willReturn($qb);
|
||||
|
||||
$config = $this->getMockBuilder('\OCP\IConfig')
|
||||
->disableOriginalConstructor()
|
||||
|
|
|
|||
Loading…
Reference in a new issue