diff --git a/lib/private/db/querybuilder/querybuilder.php b/lib/private/db/querybuilder/querybuilder.php index e70733b550..b874f5c991 100644 --- a/lib/private/db/querybuilder/querybuilder.php +++ b/lib/private/db/querybuilder/querybuilder.php @@ -324,6 +324,28 @@ class QueryBuilder implements IQueryBuilder { return $this; } + /** + * Specifies an item that is to be returned uniquely in the query result. + * + * + * $qb = $conn->getQueryBuilder() + * ->selectDistinct('type') + * ->from('users'); + * + * + * @param mixed $select The selection expressions. + * + * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. + */ + public function selectDistinct($select) { + + $this->queryBuilder->addSelect( + 'DISTINCT ' . $this->helper->quoteColumnName($select) + ); + + return $this; + } + /** * Adds an item that is to be returned in the query result. * diff --git a/lib/public/db/querybuilder/iquerybuilder.php b/lib/public/db/querybuilder/iquerybuilder.php index e3105cf134..1ff1077d53 100644 --- a/lib/public/db/querybuilder/iquerybuilder.php +++ b/lib/public/db/querybuilder/iquerybuilder.php @@ -256,6 +256,22 @@ interface IQueryBuilder { */ public function selectAlias($select, $alias); + /** + * Specifies an item that is to be returned uniquely in the query result. + * + * + * $qb = $conn->getQueryBuilder() + * ->selectDistinct('type') + * ->from('users'); + * + * + * @param mixed $select The selection expressions. + * + * @return \OCP\DB\QueryBuilder\IQueryBuilder This QueryBuilder instance. + * @since 9.0.0 + */ + public function selectDistinct($select); + /** * Adds an item that is to be returned in the query result. * diff --git a/tests/lib/db/querybuilder/querybuildertest.php b/tests/lib/db/querybuilder/querybuildertest.php index 828a860ee8..b52fbd7c28 100644 --- a/tests/lib/db/querybuilder/querybuildertest.php +++ b/tests/lib/db/querybuilder/querybuildertest.php @@ -48,12 +48,12 @@ class QueryBuilderTest extends \Test\TestCase { $this->queryBuilder = new QueryBuilder($this->connection); } - protected function createTestingRows() { + protected function createTestingRows($appId = 'testFirstResult') { $qB = $this->connection->getQueryBuilder(); for ($i = 1; $i < 10; $i++) { $qB->insert('*PREFIX*appconfig') ->values([ - 'appid' => $qB->expr()->literal('testFirstResult'), + 'appid' => $qB->expr()->literal($appId), 'configkey' => $qB->expr()->literal('testing' . $i), 'configvalue' => $qB->expr()->literal(100 - $i), ]) @@ -80,11 +80,11 @@ class QueryBuilderTest extends \Test\TestCase { return $rows; } - protected function deleteTestingRows() { + protected function deleteTestingRows($appId = 'testFirstResult') { $qB = $this->connection->getQueryBuilder(); $qB->delete('*PREFIX*appconfig') - ->where($qB->expr()->eq('appid', $qB->expr()->literal('testFirstResult'))) + ->where($qB->expr()->eq('appid', $qB->expr()->literal($appId))) ->execute(); } @@ -272,6 +272,34 @@ class QueryBuilderTest extends \Test\TestCase { $this->deleteTestingRows(); } + public function testSelectDistinct() { + $this->deleteTestingRows('testFirstResult1'); + $this->deleteTestingRows('testFirstResult2'); + $this->createTestingRows('testFirstResult1'); + $this->createTestingRows('testFirstResult2'); + + $this->queryBuilder->selectDistinct('appid'); + + $this->queryBuilder->from('*PREFIX*appconfig') + ->where($this->queryBuilder->expr()->in( + 'appid', + [$this->queryBuilder->expr()->literal('testFirstResult1'), $this->queryBuilder->expr()->literal('testFirstResult2')] + )) + ->orderBy('appid', 'DESC'); + + $query = $this->queryBuilder->execute(); + $rows = $query->fetchAll(); + $query->closeCursor(); + + $this->assertEquals( + [['appid' => 'testFirstResult2'], ['appid' => 'testFirstResult1']], + $rows + ); + + $this->deleteTestingRows('testFirstResult1'); + $this->deleteTestingRows('testFirstResult2'); + } + public function dataAddSelect() { $queryBuilder = new QueryBuilder(\OC::$server->getDatabaseConnection()); return [