Merge pull request #21030 from owncloud/querybuilder-new-features
Querybuilder new features
This commit is contained in:
commit
45fe8271ab
|
@ -324,6 +324,28 @@ class QueryBuilder implements IQueryBuilder {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies an item that is to be returned uniquely in the query result.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* $qb = $conn->getQueryBuilder()
|
||||||
|
* ->selectDistinct('type')
|
||||||
|
* ->from('users');
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @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.
|
* Adds an item that is to be returned in the query result.
|
||||||
*
|
*
|
||||||
|
@ -1024,14 +1046,46 @@ class QueryBuilder implements IQueryBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used to get the id of the last inserted element
|
||||||
|
* @return int
|
||||||
|
* @throws \BadMethodCallException When being called before an insert query has been run.
|
||||||
|
*/
|
||||||
|
public function getLastInsertId() {
|
||||||
|
$from = $this->getQueryPart('from');
|
||||||
|
|
||||||
|
if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::INSERT && !empty($from)) {
|
||||||
|
return (int) $this->connection->lastInsertId($from['table']);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \BadMethodCallException('Invalid call to getLastInsertId without using insert() before.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the table name quoted and with database prefix as needed by the implementation
|
||||||
|
*
|
||||||
* @param string $table
|
* @param string $table
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getTableName($table) {
|
public function getTableName($table) {
|
||||||
if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) {
|
if ($this->automaticTablePrefix === false || strpos($table, '*PREFIX*') === 0) {
|
||||||
return $this->helper->quoteColumnName($table);
|
return $this->helper->quoteColumnName($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->helper->quoteColumnName('*PREFIX*' . $table);
|
return $this->helper->quoteColumnName('*PREFIX*' . $table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the column name quoted and with table alias prefix as needed by the implementation
|
||||||
|
*
|
||||||
|
* @param string $column
|
||||||
|
* @param string $tableAlias
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getColumnName($column, $tableAlias = '') {
|
||||||
|
if ($tableAlias !== '') {
|
||||||
|
$tableAlias .= '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->helper->quoteColumnName($tableAlias . $column);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ class QuoteHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (substr_count($string, '.')) {
|
if (substr_count($string, '.')) {
|
||||||
list($alias, $columnName) = explode('.', $string);
|
list($alias, $columnName) = explode('.', $string, 2);
|
||||||
|
|
||||||
if ($columnName === '*') {
|
if ($columnName === '*') {
|
||||||
return $string;
|
return $string;
|
||||||
|
|
|
@ -256,6 +256,22 @@ interface IQueryBuilder {
|
||||||
*/
|
*/
|
||||||
public function selectAlias($select, $alias);
|
public function selectAlias($select, $alias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies an item that is to be returned uniquely in the query result.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* $qb = $conn->getQueryBuilder()
|
||||||
|
* ->selectDistinct('type')
|
||||||
|
* ->from('users');
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @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.
|
* Adds an item that is to be returned in the query result.
|
||||||
*
|
*
|
||||||
|
@ -796,4 +812,31 @@ interface IQueryBuilder {
|
||||||
* @since 8.2.0
|
* @since 8.2.0
|
||||||
*/
|
*/
|
||||||
public function createFunction($call);
|
public function createFunction($call);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to get the id of the last inserted element
|
||||||
|
* @return int
|
||||||
|
* @throws \BadMethodCallException When being called before an insert query has been run.
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getLastInsertId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the table name quoted and with database prefix as needed by the implementation
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getTableName($table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the column name quoted and with table alias prefix as needed by the implementation
|
||||||
|
*
|
||||||
|
* @param string $column
|
||||||
|
* @param string $tableAlias
|
||||||
|
* @return string
|
||||||
|
* @since 9.0.0
|
||||||
|
*/
|
||||||
|
public function getColumnName($column, $tableAlias = '');
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,12 +48,12 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
$this->queryBuilder = new QueryBuilder($this->connection);
|
$this->queryBuilder = new QueryBuilder($this->connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function createTestingRows() {
|
protected function createTestingRows($appId = 'testFirstResult') {
|
||||||
$qB = $this->connection->getQueryBuilder();
|
$qB = $this->connection->getQueryBuilder();
|
||||||
for ($i = 1; $i < 10; $i++) {
|
for ($i = 1; $i < 10; $i++) {
|
||||||
$qB->insert('*PREFIX*appconfig')
|
$qB->insert('*PREFIX*appconfig')
|
||||||
->values([
|
->values([
|
||||||
'appid' => $qB->expr()->literal('testFirstResult'),
|
'appid' => $qB->expr()->literal($appId),
|
||||||
'configkey' => $qB->expr()->literal('testing' . $i),
|
'configkey' => $qB->expr()->literal('testing' . $i),
|
||||||
'configvalue' => $qB->expr()->literal(100 - $i),
|
'configvalue' => $qB->expr()->literal(100 - $i),
|
||||||
])
|
])
|
||||||
|
@ -80,11 +80,11 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function deleteTestingRows() {
|
protected function deleteTestingRows($appId = 'testFirstResult') {
|
||||||
$qB = $this->connection->getQueryBuilder();
|
$qB = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
$qB->delete('*PREFIX*appconfig')
|
$qB->delete('*PREFIX*appconfig')
|
||||||
->where($qB->expr()->eq('appid', $qB->expr()->literal('testFirstResult')))
|
->where($qB->expr()->eq('appid', $qB->expr()->literal($appId)))
|
||||||
->execute();
|
->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +272,34 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
$this->deleteTestingRows();
|
$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() {
|
public function dataAddSelect() {
|
||||||
$queryBuilder = new QueryBuilder(\OC::$server->getDatabaseConnection());
|
$queryBuilder = new QueryBuilder(\OC::$server->getDatabaseConnection());
|
||||||
return [
|
return [
|
||||||
|
@ -1086,6 +1114,31 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetLastInsertId() {
|
||||||
|
$qB = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$qB->getLastInsertId();
|
||||||
|
$this->fail('getLastInsertId() should throw an exception, when being called before insert()');
|
||||||
|
} catch (\BadMethodCallException $e) {
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qB->insert('appconfig')
|
||||||
|
->values([
|
||||||
|
'appid' => $qB->expr()->literal('testFirstResult'),
|
||||||
|
'configkey' => $qB->expr()->literal('testing' . 50),
|
||||||
|
'configvalue' => $qB->expr()->literal(100 - 50),
|
||||||
|
])
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$actual = $qB->getLastInsertId();
|
||||||
|
|
||||||
|
$this->assertNotNull($actual);
|
||||||
|
$this->assertInternalType('int', $actual);
|
||||||
|
$this->assertEquals($this->connection->lastInsertId('*PREFIX*appconfig'), $actual);
|
||||||
|
}
|
||||||
|
|
||||||
public function dataGetTableName() {
|
public function dataGetTableName() {
|
||||||
return [
|
return [
|
||||||
['*PREFIX*table', null, '`*PREFIX*table`'],
|
['*PREFIX*table', null, '`*PREFIX*table`'],
|
||||||
|
@ -1112,7 +1165,27 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
|
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
$expected,
|
$expected,
|
||||||
$this->invokePrivate($this->queryBuilder, 'getTableName', [$tableName])
|
$this->queryBuilder->getTableName($tableName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataGetColumnName() {
|
||||||
|
return [
|
||||||
|
['column', '', '`column`'],
|
||||||
|
['column', 'a', 'a.`column`'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataGetColumnName
|
||||||
|
* @param string $column
|
||||||
|
* @param string $prefix
|
||||||
|
* @param string $expected
|
||||||
|
*/
|
||||||
|
public function testGetColumnName($column, $prefix, $expected) {
|
||||||
|
$this->assertSame(
|
||||||
|
$expected,
|
||||||
|
$this->queryBuilder->getColumnName($column, $prefix)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue