2015-07-07 11:30:26 -04:00
< ? php
2025-06-30 09:04:05 -04:00
2025-09-08 12:01:07 -04:00
declare ( strict_types = 1 );
2015-07-07 11:30:26 -04:00
/**
2024-05-10 09:09:14 -04:00
* SPDX - FileCopyrightText : 2016 - 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - only
2015-07-07 11:30:26 -04:00
*/
namespace Test\DB\QueryBuilder ;
2026-01-23 10:55:54 -05:00
use BadMethodCallException ;
2015-07-07 11:30:26 -04:00
use Doctrine\DBAL\Query\Expression\CompositeExpression ;
2021-01-08 06:46:10 -05:00
use Doctrine\DBAL\Query\QueryException ;
2026-01-23 10:55:54 -05:00
use OC\DB\ConnectionAdapter ;
2015-07-07 11:30:26 -04:00
use OC\DB\QueryBuilder\Literal ;
use OC\DB\QueryBuilder\Parameter ;
use OC\DB\QueryBuilder\QueryBuilder ;
2016-10-28 07:48:58 -04:00
use OC\SystemConfig ;
2024-07-04 11:18:22 -04:00
use OCP\DB\IResult ;
2026-01-23 10:55:54 -05:00
use OCP\DB\QueryBuilder\ILiteral ;
use OCP\DB\QueryBuilder\IParameter ;
2024-07-04 11:18:22 -04:00
use OCP\DB\QueryBuilder\IQueryBuilder ;
2015-07-16 04:38:12 -04:00
use OCP\IDBConnection ;
2025-06-12 12:31:58 -04:00
use OCP\Server ;
2025-09-08 12:01:07 -04:00
use PHPUnit\Framework\Attributes\DataProvider ;
2026-01-23 10:55:54 -05:00
use PHPUnit\Framework\Attributes\Group ;
2025-09-08 12:01:07 -04:00
use PHPUnit\Framework\MockObject\MockObject ;
2022-03-21 06:17:14 -04:00
use Psr\Log\LoggerInterface ;
2026-01-23 10:55:54 -05:00
use function str_starts_with ;
2015-07-07 11:30:26 -04:00
2026-01-23 10:55:54 -05:00
#[Group(name: 'DB')]
2015-07-07 11:30:26 -04:00
class QueryBuilderTest extends \Test\TestCase {
2025-09-08 12:01:07 -04:00
private SystemConfig & MockObject $config ;
private LoggerInterface & MockObject $logger ;
2016-10-28 07:48:58 -04:00
2025-09-08 12:01:07 -04:00
private QueryBuilder $queryBuilder ;
private IDBConnection $connection ;
2016-10-28 07:48:58 -04:00
2019-11-21 10:40:38 -05:00
protected function setUp () : void {
2015-07-07 11:30:26 -04:00
parent :: setUp ();
2025-06-12 12:31:58 -04:00
$this -> connection = Server :: get ( IDBConnection :: class );
2016-10-28 07:48:58 -04:00
$this -> config = $this -> createMock ( SystemConfig :: class );
2022-03-21 06:17:14 -04:00
$this -> logger = $this -> createMock ( LoggerInterface :: class );
2016-10-28 07:48:58 -04:00
$this -> queryBuilder = new QueryBuilder ( $this -> connection , $this -> config , $this -> logger );
2015-07-07 11:30:26 -04:00
}
2026-01-23 10:55:54 -05:00
/**
* @ psalm - param 'testFirstResult' | 'testFirstResult1' | 'testFirstResult2' $appId
*/
protected function createTestingRows ( string $appId = 'testFirstResult' ) : void {
2015-07-20 11:09:27 -04:00
$qB = $this -> connection -> getQueryBuilder ();
for ( $i = 1 ; $i < 10 ; $i ++ ) {
$qB -> insert ( '*PREFIX*appconfig' )
-> values ([
2015-12-08 03:49:21 -05:00
'appid' => $qB -> expr () -> literal ( $appId ),
2015-07-20 11:09:27 -04:00
'configkey' => $qB -> expr () -> literal ( 'testing' . $i ),
'configvalue' => $qB -> expr () -> literal ( 100 - $i ),
])
2025-08-26 09:20:42 -04:00
-> executeStatement ();
2015-07-20 11:09:27 -04:00
}
}
2026-01-23 10:55:54 -05:00
protected function getTestingRows ( QueryBuilder $queryBuilder ) : array {
2015-07-20 11:09:27 -04:00
$queryBuilder -> select ( 'configvalue' )
-> from ( '*PREFIX*appconfig' )
-> where ( $queryBuilder -> expr () -> eq (
'appid' ,
$queryBuilder -> expr () -> literal ( 'testFirstResult' )
))
-> orderBy ( 'configkey' , 'ASC' );
2025-08-26 09:20:42 -04:00
$query = $queryBuilder -> executeQuery ();
2015-07-20 11:09:27 -04:00
$rows = [];
while ( $row = $query -> fetch ()) {
$rows [] = $row [ 'configvalue' ];
}
$query -> closeCursor ();
return $rows ;
}
2026-01-23 10:55:54 -05:00
/**
* @ psalm - param 'testFirstResult' | 'testFirstResult1' | 'testFirstResult2' $appId
*/
protected function deleteTestingRows ( string $appId = 'testFirstResult' ) : void {
2015-07-20 11:09:27 -04:00
$qB = $this -> connection -> getQueryBuilder ();
$qB -> delete ( '*PREFIX*appconfig' )
2015-12-08 03:49:21 -05:00
-> where ( $qB -> expr () -> eq ( 'appid' , $qB -> expr () -> literal ( $appId )))
2025-08-26 09:20:42 -04:00
-> executeStatement ();
2015-07-20 11:09:27 -04:00
}
2025-05-13 05:50:12 -04:00
public static function dataFirstResult () : array {
2015-07-07 11:30:26 -04:00
return [
2021-10-20 12:25:30 -04:00
[ 0 , [ 99 , 98 , 97 , 96 , 95 , 94 , 93 , 92 , 91 ]],
2015-07-20 11:09:27 -04:00
[ 0 , [ 99 , 98 , 97 , 96 , 95 , 94 , 93 , 92 , 91 ]],
[ 1 , [ 98 , 97 , 96 , 95 , 94 , 93 , 92 , 91 ]],
[ 5 , [ 94 , 93 , 92 , 91 ]],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataFirstResult')]
public function testFirstResult ( ? int $firstResult , array $expectedSet ) : void {
2015-07-20 11:09:27 -04:00
$this -> deleteTestingRows ();
$this -> createTestingRows ();
2015-07-15 09:21:02 -04:00
2015-07-07 11:30:26 -04:00
if ( $firstResult !== null ) {
$this -> queryBuilder -> setFirstResult ( $firstResult );
}
$this -> assertSame (
2021-10-20 12:25:30 -04:00
$firstResult ? ? 0 ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getFirstResult ()
);
2015-07-20 11:09:27 -04:00
$rows = $this -> getTestingRows ( $this -> queryBuilder );
2015-07-15 09:21:02 -04:00
2015-07-16 04:38:12 -04:00
$this -> assertCount ( sizeof ( $expectedSet ), $rows );
$this -> assertEquals ( $expectedSet , $rows );
2015-07-15 09:21:02 -04:00
2015-07-20 11:09:27 -04:00
$this -> deleteTestingRows ();
2015-07-07 11:30:26 -04:00
}
2025-05-13 05:50:12 -04:00
public static function dataMaxResults () : array {
2015-07-07 11:30:26 -04:00
return [
2015-07-20 11:09:27 -04:00
[ null , [ 99 , 98 , 97 , 96 , 95 , 94 , 93 , 92 , 91 ]],
2015-07-21 03:56:08 -04:00
// Limit 0 gives mixed results: either all entries or none is returned
//[0, []],
2015-07-20 11:09:27 -04:00
[ 1 , [ 99 ]],
[ 5 , [ 99 , 98 , 97 , 96 , 95 ]],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataMaxResults')]
public function testMaxResults ( ? int $maxResult , array $expectedSet ) : void {
2015-07-20 11:09:27 -04:00
$this -> deleteTestingRows ();
$this -> createTestingRows ();
2015-07-07 11:30:26 -04:00
if ( $maxResult !== null ) {
$this -> queryBuilder -> setMaxResults ( $maxResult );
}
$this -> assertSame (
$maxResult ,
$this -> queryBuilder -> getMaxResults ()
);
2015-07-20 11:09:27 -04:00
$rows = $this -> getTestingRows ( $this -> queryBuilder );
$this -> assertCount ( sizeof ( $expectedSet ), $rows );
$this -> assertEquals ( $expectedSet , $rows );
$this -> deleteTestingRows ();
2015-07-07 11:30:26 -04:00
}
2025-09-08 12:01:07 -04:00
public static function dataSelect () : array {
2015-07-07 11:30:26 -04:00
return [
// select('column1')
2015-11-09 05:50:18 -05:00
[[ 'configvalue' ], [ 'configvalue' => '99' ]],
2015-07-07 11:30:26 -04:00
// select('column1', 'column2')
2015-11-09 05:50:18 -05:00
[[ 'configvalue' , 'configkey' ], [ 'configvalue' => '99' , 'configkey' => 'testing1' ]],
2015-07-07 11:30:26 -04:00
// select(['column1', 'column2'])
2015-11-09 05:50:18 -05:00
[[[ 'configvalue' , 'configkey' ]], [ 'configvalue' => '99' , 'configkey' => 'testing1' ]],
2015-07-07 11:30:26 -04:00
// select(new Literal('column1'))
2025-09-08 12:01:07 -04:00
[[ 'l::column1' ], [], 'column1' ],
2015-07-07 11:30:26 -04:00
2025-09-08 12:01:07 -04:00
// select(new Literal('column1'), 'column2')
[[ 'l::column1' , 'configkey' ], [ 'configkey' => 'testing1' ], 'column1' ],
2015-07-07 11:30:26 -04:00
2025-09-08 12:01:07 -04:00
// select([new Literal('column1'), 'column2'])
[[[ 'l::column1' , 'configkey' ]], [ 'configkey' => 'testing1' ], 'column1' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataSelect')]
2025-09-08 12:01:07 -04:00
public function testSelect ( array $selectArguments , array $expected , string $expectedLiteral = '' ) : void {
2015-11-09 05:50:18 -05:00
$this -> deleteTestingRows ();
$this -> createTestingRows ();
2025-09-08 12:01:07 -04:00
array_walk_recursive (
$selectArguments ,
2025-09-27 12:35:17 -04:00
function ( string & $arg ) : void {
2026-01-23 10:55:54 -05:00
if ( str_starts_with ( $arg , 'l::' )) {
2025-09-08 12:01:07 -04:00
$arg = $this -> queryBuilder -> expr () -> literal ( substr ( $arg , 3 ));
}
},
2015-07-07 11:30:26 -04:00
);
2025-09-08 12:01:07 -04:00
$this -> queryBuilder -> select ( ... $selectArguments );
2015-07-07 11:30:26 -04:00
2015-11-09 05:50:18 -05:00
$this -> queryBuilder -> from ( '*PREFIX*appconfig' )
-> where ( $this -> queryBuilder -> expr () -> eq (
'appid' ,
$this -> queryBuilder -> expr () -> literal ( 'testFirstResult' )
))
-> orderBy ( 'configkey' , 'ASC' )
-> setMaxResults ( 1 );
2015-07-07 11:30:26 -04:00
2025-08-26 09:20:42 -04:00
$query = $this -> queryBuilder -> executeQuery ();
2015-11-09 05:50:18 -05:00
$row = $query -> fetch ();
$query -> closeCursor ();
foreach ( $expected as $key => $value ) {
$this -> assertArrayHasKey ( $key , $row );
$this -> assertEquals ( $value , $row [ $key ]);
unset ( $row [ $key ]);
}
if ( $expectedLiteral ) {
$this -> assertEquals ([ $expectedLiteral ], array_values ( $row ));
} else {
$this -> assertEmpty ( $row );
}
$this -> deleteTestingRows ();
}
2025-09-08 12:01:07 -04:00
public static function dataSelectAlias () : array {
2015-11-09 05:50:18 -05:00
return [
[ 'configvalue' , 'cv' , [ 'cv' => '99' ]],
2025-09-08 12:01:07 -04:00
[ 'l::column1' , 'thing' , [ 'thing' => 'column1' ]],
2015-11-09 05:50:18 -05:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataSelectAlias')]
2025-09-08 12:01:07 -04:00
public function testSelectAlias ( string $select , string $alias , array $expected ) : void {
if ( str_starts_with ( $select , 'l::' )) {
$select = $this -> queryBuilder -> expr () -> literal ( substr ( $select , 3 ));
}
2015-11-09 05:50:18 -05:00
$this -> deleteTestingRows ();
$this -> createTestingRows ();
$this -> queryBuilder -> selectAlias ( $select , $alias );
2026-01-23 10:55:54 -05:00
$this -> queryBuilder -> from ( 'appconfig' )
2015-11-09 05:50:18 -05:00
-> where ( $this -> queryBuilder -> expr () -> eq (
'appid' ,
$this -> queryBuilder -> expr () -> literal ( 'testFirstResult' )
))
-> orderBy ( 'configkey' , 'ASC' )
-> setMaxResults ( 1 );
2025-08-26 09:20:42 -04:00
$query = $this -> queryBuilder -> executeQuery ();
2015-11-09 05:50:18 -05:00
$row = $query -> fetch ();
$query -> closeCursor ();
$this -> assertEquals (
$expected ,
$row
2015-07-07 11:30:26 -04:00
);
2015-11-09 05:50:18 -05:00
$this -> deleteTestingRows ();
2015-07-07 11:30:26 -04:00
}
2024-09-15 16:32:31 -04:00
public function testSelectDistinct () : void {
2015-12-08 03:49:21 -05:00
$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' );
2025-08-26 09:20:42 -04:00
$query = $this -> queryBuilder -> executeQuery ();
2015-12-08 03:49:21 -05:00
$rows = $query -> fetchAll ();
$query -> closeCursor ();
$this -> assertEquals (
[[ 'appid' => 'testFirstResult2' ], [ 'appid' => 'testFirstResult1' ]],
$rows
);
$this -> deleteTestingRows ( 'testFirstResult1' );
$this -> deleteTestingRows ( 'testFirstResult2' );
}
2024-09-15 16:32:31 -04:00
public function testSelectDistinctMultiple () : void {
2020-11-09 11:43:29 -05:00
$this -> deleteTestingRows ( 'testFirstResult1' );
$this -> deleteTestingRows ( 'testFirstResult2' );
$this -> createTestingRows ( 'testFirstResult1' );
$this -> createTestingRows ( 'testFirstResult2' );
$this -> queryBuilder -> selectDistinct ([ 'appid' , 'configkey' ]);
$this -> queryBuilder -> from ( '*PREFIX*appconfig' )
-> where ( $this -> queryBuilder -> expr () -> eq (
'appid' ,
$this -> queryBuilder -> expr () -> literal ( 'testFirstResult1' )
))
2024-01-25 00:44:11 -05:00
-> orderBy ( 'configkey' , 'ASC' );
2020-11-09 11:43:29 -05:00
2025-08-26 09:20:42 -04:00
$query = $this -> queryBuilder -> executeQuery ();
2020-11-09 11:43:29 -05:00
$rows = $query -> fetchAll ();
$query -> closeCursor ();
$this -> assertEquals (
[
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing1' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing2' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing3' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing4' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing5' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing6' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing7' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing8' ],
[ 'appid' => 'testFirstResult1' , 'configkey' => 'testing9' ],
],
$rows
);
$this -> deleteTestingRows ( 'testFirstResult1' );
$this -> deleteTestingRows ( 'testFirstResult2' );
}
2025-09-08 12:01:07 -04:00
public static function dataAddSelect () : array {
2015-07-07 11:30:26 -04:00
return [
// addSelect('column1')
2015-11-09 05:50:18 -05:00
[[ 'configvalue' ], [ 'appid' => 'testFirstResult' , 'configvalue' => '99' ]],
2015-07-07 11:30:26 -04:00
// addSelect('column1', 'column2')
2015-11-09 05:50:18 -05:00
[[ 'configvalue' , 'configkey' ], [ 'appid' => 'testFirstResult' , 'configvalue' => '99' , 'configkey' => 'testing1' ]],
2015-07-07 11:30:26 -04:00
// addSelect(['column1', 'column2'])
2015-11-09 05:50:18 -05:00
[[[ 'configvalue' , 'configkey' ]], [ 'appid' => 'testFirstResult' , 'configvalue' => '99' , 'configkey' => 'testing1' ]],
2015-07-07 11:30:26 -04:00
// select(new Literal('column1'))
2025-09-08 12:01:07 -04:00
[[ 'l::column1' ], [ 'appid' => 'testFirstResult' ], 'column1' ],
2015-07-07 11:30:26 -04:00
2025-09-08 12:01:07 -04:00
// select(new Literal('column1'), 'column2')
[[ 'l::column1' , 'configkey' ], [ 'appid' => 'testFirstResult' , 'configkey' => 'testing1' ], 'column1' ],
2015-07-07 11:30:26 -04:00
2025-09-08 12:01:07 -04:00
// select([new Literal('column1'), 'column2'])
[[[ 'l::column1' , 'configkey' ]], [ 'appid' => 'testFirstResult' , 'configkey' => 'testing1' ], 'column1' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataAddSelect')]
2025-09-08 12:01:07 -04:00
public function testAddSelect ( array $selectArguments , array $expected , string $expectedLiteral = '' ) : void {
2015-11-09 05:50:18 -05:00
$this -> deleteTestingRows ();
$this -> createTestingRows ();
2025-09-08 12:01:07 -04:00
array_walk_recursive (
$selectArguments ,
2025-09-27 12:35:17 -04:00
function ( string & $arg ) : void {
2026-01-23 10:55:54 -05:00
if ( str_starts_with ( $arg , 'l::' )) {
2025-09-08 12:01:07 -04:00
$arg = $this -> queryBuilder -> expr () -> literal ( substr ( $arg , 3 ));
}
},
);
2015-11-09 05:50:18 -05:00
$this -> queryBuilder -> select ( 'appid' );
2015-07-07 11:30:26 -04:00
call_user_func_array (
[ $this -> queryBuilder , 'addSelect' ],
$selectArguments
);
2015-11-09 05:50:18 -05:00
$this -> queryBuilder -> from ( '*PREFIX*appconfig' )
-> where ( $this -> queryBuilder -> expr () -> eq (
'appid' ,
$this -> queryBuilder -> expr () -> literal ( 'testFirstResult' )
))
-> orderBy ( 'configkey' , 'ASC' )
-> setMaxResults ( 1 );
2015-07-07 11:30:26 -04:00
2025-08-26 09:20:42 -04:00
$query = $this -> queryBuilder -> executeQuery ();
2015-11-09 05:50:18 -05:00
$row = $query -> fetch ();
$query -> closeCursor ();
foreach ( $expected as $key => $value ) {
$this -> assertArrayHasKey ( $key , $row );
$this -> assertEquals ( $value , $row [ $key ]);
unset ( $row [ $key ]);
}
if ( $expectedLiteral ) {
$this -> assertEquals ([ $expectedLiteral ], array_values ( $row ));
} else {
$this -> assertEmpty ( $row );
}
$this -> deleteTestingRows ();
2015-07-07 11:30:26 -04:00
}
2025-05-13 05:50:12 -04:00
public static function dataDelete () : array {
2015-07-07 11:30:26 -04:00
return [
2015-08-10 10:20:42 -04:00
[ 'data' , null , [ 'table' => '`*PREFIX*data`' , 'alias' => null ], '`*PREFIX*data`' ],
[ 'data' , 't' , [ 'table' => '`*PREFIX*data`' , 'alias' => 't' ], '`*PREFIX*data` t' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataDelete')]
public function testDelete ( string $tableName , ? string $tableAlias , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> delete ( $tableName , $tableAlias );
$this -> assertSame (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'from' )
);
$this -> assertSame (
'DELETE FROM ' . $expectedQuery ,
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataUpdate () : array {
2015-07-07 11:30:26 -04:00
return [
2015-08-10 10:20:42 -04:00
[ 'data' , null , [ 'table' => '`*PREFIX*data`' , 'alias' => null ], '`*PREFIX*data`' ],
[ 'data' , 't' , [ 'table' => '`*PREFIX*data`' , 'alias' => 't' ], '`*PREFIX*data` t' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataUpdate')]
public function testUpdate ( string $tableName , ? string $tableAlias , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> update ( $tableName , $tableAlias );
$this -> assertSame (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'from' )
);
$this -> assertSame (
'UPDATE ' . $expectedQuery . ' SET ' ,
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataInsert () : array {
2015-07-07 11:30:26 -04:00
return [
2015-08-10 10:20:42 -04:00
[ 'data' , [ 'table' => '`*PREFIX*data`' ], '`*PREFIX*data`' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataInsert')]
public function testInsert ( string $tableName , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> insert ( $tableName );
$this -> assertSame (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'from' )
);
$this -> assertSame (
'INSERT INTO ' . $expectedQuery . ' () VALUES()' ,
$this -> queryBuilder -> getSQL ()
);
}
2025-09-08 12:01:07 -04:00
public static function dataFrom () : array {
2015-07-07 11:30:26 -04:00
return [
2025-09-08 12:01:07 -04:00
[ 'function' , 'q' , null , null , [
2022-01-11 11:31:32 -05:00
[ 'table' => '(SELECT * FROM `*PREFIX*test`)' , 'alias' => '`q`' ]
], '(SELECT * FROM `*PREFIX*test`) `q`' ],
2015-08-10 10:20:42 -04:00
[ 'data' , null , null , null , [[ 'table' => '`*PREFIX*data`' , 'alias' => null ]], '`*PREFIX*data`' ],
2017-07-24 06:01:35 -04:00
[ 'data' , 't' , null , null , [[ 'table' => '`*PREFIX*data`' , 'alias' => '`t`' ]], '`*PREFIX*data` `t`' ],
2015-07-07 11:30:26 -04:00
[ 'data1' , null , 'data2' , null , [
2015-08-10 10:20:42 -04:00
[ 'table' => '`*PREFIX*data1`' , 'alias' => null ],
[ 'table' => '`*PREFIX*data2`' , 'alias' => null ]
], '`*PREFIX*data1`, `*PREFIX*data2`' ],
2015-07-07 11:30:26 -04:00
[ 'data' , 't1' , 'data' , 't2' , [
2017-07-24 06:01:35 -04:00
[ 'table' => '`*PREFIX*data`' , 'alias' => '`t1`' ],
[ 'table' => '`*PREFIX*data`' , 'alias' => '`t2`' ]
], '`*PREFIX*data` `t1`, `*PREFIX*data` `t2`' ],
2015-07-07 11:30:26 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataFrom')]
2025-09-08 12:01:07 -04:00
public function testFrom ( string $table1Name , ? string $table1Alias , ? string $table2Name , ? string $table2Alias , array $expectedQueryPart , string $expectedQuery ) : void {
$config = $this -> createMock ( SystemConfig :: class );
$logger = $this -> createMock ( LoggerInterface :: class );
$queryBuilder = new QueryBuilder ( Server :: get ( IDBConnection :: class ), $config , $logger );
if ( $table1Name === 'function' ) {
$table1Name = $queryBuilder -> createFunction ( '(' . $queryBuilder -> select ( '*' ) -> from ( 'test' ) -> getSQL () . ')' );
}
2015-07-07 11:30:26 -04:00
$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 ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataJoin () : array {
2015-07-07 11:30:26 -04:00
return [
[
'd1' , 'data2' , null , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'inner' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => null , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` '
2015-07-07 11:30:26 -04:00
],
[
'd1' , 'data2' , 'd2' , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'inner' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` `d2`'
2015-07-07 11:30:26 -04:00
],
[
2017-07-24 06:01:35 -04:00
'd1' , 'data2' , 'd2' , '`d1`.`field1` = `d2`.`field2`' ,
[ '`d1`' => [[ 'joinType' => 'inner' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => '`d1`.`field1` = `d2`.`field2`' ]]],
'`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
2015-07-07 11:30:26 -04:00
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataJoin')]
public function testJoin ( string $fromAlias , string $tableName , ? string $tableAlias , ? string $condition , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 ()
);
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataJoin')]
public function testInnerJoin ( string $fromAlias , string $tableName , ? string $tableAlias , ? string $condition , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataLeftJoin () : array {
2015-07-07 11:30:26 -04:00
return [
[
'd1' , 'data2' , null , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'left' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => null , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` '
2015-07-07 11:30:26 -04:00
],
[
'd1' , 'data2' , 'd2' , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'left' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` `d2`'
2015-07-07 11:30:26 -04:00
],
[
2017-07-24 06:01:35 -04:00
'd1' , 'data2' , 'd2' , '`d1`.`field1` = `d2`.`field2`' ,
[ '`d1`' => [[ 'joinType' => 'left' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => '`d1`.`field1` = `d2`.`field2`' ]]],
'`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
2015-07-07 11:30:26 -04:00
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataLeftJoin')]
public function testLeftJoin ( string $fromAlias , string $tableName , ? string $tableAlias , ? string $condition , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataRightJoin () : array {
2015-07-07 11:30:26 -04:00
return [
[
'd1' , 'data2' , null , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'right' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => null , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` '
2015-07-07 11:30:26 -04:00
],
[
'd1' , 'data2' , 'd2' , null ,
2017-07-24 06:01:35 -04:00
[ '`d1`' => [[ 'joinType' => 'right' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => null ]]],
2020-06-08 02:01:44 -04:00
'`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` `d2`'
2015-07-07 11:30:26 -04:00
],
[
2017-07-24 06:01:35 -04:00
'd1' , 'data2' , 'd2' , '`d1`.`field1` = `d2`.`field2`' ,
[ '`d1`' => [[ 'joinType' => 'right' , 'joinTable' => '`*PREFIX*data2`' , 'joinAlias' => '`d2`' , 'joinCondition' => '`d1`.`field1` = `d2`.`field2`' ]]],
'`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
2015-07-07 11:30:26 -04:00
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataRightJoin')]
public function testRightJoin ( string $fromAlias , string $tableName , ? string $tableAlias , ? string $condition , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataSet () : array {
2015-07-07 11:30:26 -04:00
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' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataSet')]
public function testSet ( string $partOne1 , string | ILiteral | IParameter $partOne2 , ? string $partTwo1 , ? ILiteral $partTwo2 , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 (
2015-08-10 10:20:42 -04:00
'UPDATE `*PREFIX*data` SET ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataWhere () : array {
2015-07-07 11:30:26 -04:00
return [
[[ 'where1' ], new CompositeExpression ( 'AND' , [ 'where1' ]), 'where1' ],
[[ 'where1' , 'where2' ], new CompositeExpression ( 'AND' , [ 'where1' , 'where2' ]), '(where1) AND (where2)' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataWhere')]
public function testWhere ( array $whereArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> select ( 'column' );
call_user_func_array (
[ $this -> queryBuilder , 'where' ],
$whereArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'where' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT `column` WHERE ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataWhere')]
public function testAndWhere ( array $whereArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> select ( 'column' );
call_user_func_array (
[ $this -> queryBuilder , 'andWhere' ],
$whereArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'where' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT `column` WHERE ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataOrWhere () : array {
2015-07-07 11:30:26 -04:00
return [
[[ 'where1' ], new CompositeExpression ( 'OR' , [ 'where1' ]), 'where1' ],
[[ 'where1' , 'where2' ], new CompositeExpression ( 'OR' , [ 'where1' , 'where2' ]), '(where1) OR (where2)' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataOrWhere')]
public function testOrWhere ( array $whereArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> select ( 'column' );
call_user_func_array (
[ $this -> queryBuilder , 'orWhere' ],
$whereArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'where' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT `column` WHERE ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataGroupBy () : array {
2015-07-07 11:30:26 -04:00
return [
[[ 'column1' ], [ '`column1`' ], '`column1`' ],
[[ 'column1' , 'column2' ], [ '`column1`' , '`column2`' ], '`column1`, `column2`' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataGroupBy')]
public function testGroupBy ( array $groupByArguments , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> select ( 'column' );
call_user_func_array (
[ $this -> queryBuilder , 'groupBy' ],
$groupByArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'groupBy' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT `column` GROUP BY ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataAddGroupBy () : array {
2015-07-07 11:30:26 -04:00
return [
[[ 'column2' ], [ '`column1`' , '`column2`' ], '`column1`, `column2`' ],
[[ 'column2' , 'column3' ], [ '`column1`' , '`column2`' , '`column3`' ], '`column1`, `column2`, `column3`' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataAddGroupBy')]
public function testAddGroupBy ( array $groupByArguments , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$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 (
2016-09-30 07:31:39 -04:00
'SELECT `column` GROUP BY ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataSetValue () : array {
2015-07-07 11:30:26 -04:00
return [
[ 'column' , 'value' , [ '`column`' => 'value' ], '(`column`) VALUES(value)' ],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataSetValue')]
public function testSetValue ( string $column , string $value , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> insert ( 'data' );
$this -> queryBuilder -> setValue ( $column , $value );
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'values' )
);
$this -> assertSame (
2015-08-10 10:20:42 -04:00
'INSERT INTO `*PREFIX*data` ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataSetValue')]
public function testValues ( string $column , string $value , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> insert ( 'data' );
$this -> queryBuilder -> values ([
$column => $value ,
]);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'values' )
);
$this -> assertSame (
2015-08-10 10:20:42 -04:00
'INSERT INTO `*PREFIX*data` ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataHaving () : array {
2015-07-07 11:30:26 -04:00
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)'
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataHaving')]
public function testHaving ( array $havingArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
call_user_func_array (
[ $this -> queryBuilder , 'having' ],
$havingArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'having' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataAndHaving () : array {
2015-07-07 11:30:26 -04:00
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))'
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataAndHaving')]
public function testAndHaving ( array $havingArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> having ( 'condition1' );
call_user_func_array (
[ $this -> queryBuilder , 'andHaving' ],
$havingArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'having' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataOrHaving () : array {
2015-07-07 11:30:26 -04:00
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))'
],
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataOrHaving')]
public function testOrHaving ( array $havingArguments , CompositeExpression $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> having ( 'condition1' );
call_user_func_array (
[ $this -> queryBuilder , 'orHaving' ],
$havingArguments
);
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'having' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataOrderBy () : array {
2015-07-07 11:30:26 -04:00
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' ],
];
}
/**
2026-01-23 10:55:54 -05:00
* @ param string | 'ASC' | 'DESC' | null $order
2015-07-07 11:30:26 -04:00
*/
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataOrderBy')]
public function testOrderBy ( string $sort , ? string $order , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> orderBy ( $sort , $order );
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'orderBy' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2025-05-13 05:50:12 -04:00
public static function dataAddOrderBy () : array {
2015-07-07 11:30:26 -04:00
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' ],
];
}
/**
2026-01-23 10:55:54 -05:00
* @ param string | 'ASC' | 'DESC' | null $order2
* @ param string | 'ASC' | 'DESC' | null $order1
2015-07-07 11:30:26 -04:00
*/
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataAddOrderBy')]
public function testAddOrderBy ( string $sort2 , ? string $order2 , ? string $order1 , array $expectedQueryPart , string $expectedQuery ) : void {
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> orderBy ( 'column1' , $order1 );
$this -> queryBuilder -> addOrderBy ( $sort2 , $order2 );
$this -> assertEquals (
$expectedQueryPart ,
$this -> queryBuilder -> getQueryPart ( 'orderBy' )
);
$this -> assertSame (
2016-09-30 07:31:39 -04:00
'SELECT ' . $expectedQuery ,
2015-07-07 11:30:26 -04:00
$this -> queryBuilder -> getSQL ()
);
}
2015-08-10 10:20:42 -04:00
2024-09-15 16:32:31 -04:00
public function testGetLastInsertId () : void {
2015-12-08 03:40:20 -05:00
$qB = $this -> connection -> getQueryBuilder ();
try {
$qB -> getLastInsertId ();
$this -> fail ( 'getLastInsertId() should throw an exception, when being called before insert()' );
2026-01-23 10:55:54 -05:00
} catch ( BadMethodCallException ) {
2018-01-25 05:23:12 -05:00
$this -> addToAssertionCount ( 1 );
2015-12-08 03:40:20 -05:00
}
2015-12-09 03:43:23 -05:00
$qB -> insert ( 'properties' )
2015-12-08 03:40:20 -05:00
-> values ([
2015-12-09 03:43:23 -05:00
'userid' => $qB -> expr () -> literal ( 'testFirstResult' ),
'propertypath' => $qB -> expr () -> literal ( 'testing' ),
'propertyname' => $qB -> expr () -> literal ( 'testing' ),
'propertyvalue' => $qB -> expr () -> literal ( 'testing' ),
2015-12-08 03:40:20 -05:00
])
2025-08-26 09:20:42 -04:00
-> executeStatement ();
2015-12-08 03:40:20 -05:00
$actual = $qB -> getLastInsertId ();
2015-12-09 03:43:23 -05:00
$this -> assertEquals ( $this -> connection -> lastInsertId ( '*PREFIX*properties' ), $actual );
$qB -> delete ( 'properties' )
-> where ( $qB -> expr () -> eq ( 'userid' , $qB -> expr () -> literal ( 'testFirstResult' )))
2025-08-26 09:20:42 -04:00
-> executeStatement ();
2015-12-09 03:43:23 -05:00
try {
$qB -> getLastInsertId ();
$this -> fail ( 'getLastInsertId() should throw an exception, when being called after delete()' );
2026-01-23 10:55:54 -05:00
} catch ( BadMethodCallException ) {
2018-01-25 05:23:12 -05:00
$this -> addToAssertionCount ( 1 );
2015-12-09 03:43:23 -05:00
}
2015-12-08 03:40:20 -05:00
}
2025-09-08 12:01:07 -04:00
public static function dataGetTableName () : array {
2015-08-10 10:20:42 -04:00
return [
[ '*PREFIX*table' , null , '`*PREFIX*table`' ],
[ '*PREFIX*table' , true , '`*PREFIX*table`' ],
[ '*PREFIX*table' , false , '`*PREFIX*table`' ],
[ 'table' , null , '`*PREFIX*table`' ],
[ 'table' , true , '`*PREFIX*table`' ],
[ 'table' , false , '`table`' ],
2022-01-11 10:20:13 -05:00
2025-09-08 12:01:07 -04:00
[ 'function' , null , '(SELECT * FROM `*PREFIX*table`)' ],
[ 'function' , true , '(SELECT * FROM `*PREFIX*table`)' ],
[ 'function' , false , '(SELECT * FROM `*PREFIX*table`)' ],
2015-08-10 10:20:42 -04:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataGetTableName')]
2025-09-08 12:01:07 -04:00
public function testGetTableName ( string $tableName , ? bool $automatic , string $expected ) : void {
if ( $tableName === 'function' ) {
$tableName = $this -> queryBuilder -> createFunction ( '(' . $this -> queryBuilder -> select ( '*' ) -> from ( 'table' ) -> getSQL () . ')' );
}
2015-08-10 10:20:42 -04:00
if ( $automatic !== null ) {
$this -> queryBuilder -> automaticTablePrefix ( $automatic );
}
$this -> assertSame (
$expected ,
2015-12-08 03:57:38 -05:00
$this -> queryBuilder -> getTableName ( $tableName )
);
}
2025-05-13 05:50:12 -04:00
public static function dataGetColumnName () : array {
2015-12-08 03:57:38 -05:00
return [
[ 'column' , '' , '`column`' ],
2017-03-30 05:07:16 -04:00
[ 'column' , 'a' , '`a`.`column`' ],
2015-12-08 03:57:38 -05:00
];
}
2026-01-23 10:55:54 -05:00
#[DataProvider(methodName: 'dataGetColumnName')]
public function testGetColumnName ( string $column , string $prefix , string $expected ) : void {
2015-12-08 03:57:38 -05:00
$this -> assertSame (
$expected ,
$this -> queryBuilder -> getColumnName ( $column , $prefix )
2015-08-10 10:20:42 -04:00
);
}
2016-11-02 16:10:51 -04:00
2026-01-23 10:55:54 -05:00
private function getConnection () : ConnectionAdapter & MockObject {
$connection = $this -> createMock ( ConnectionAdapter :: class );
2024-07-04 11:18:22 -04:00
$connection -> method ( 'executeStatement' )
-> willReturn ( 3 );
$connection -> method ( 'executeQuery' )
-> willReturn ( $this -> createMock ( IResult :: class ));
return $connection ;
}
2024-09-15 16:32:31 -04:00
public function testExecuteWithoutLogger () : void {
2016-11-02 16:10:51 -04:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
2026-01-23 10:55:54 -05:00
$queryBuilder
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: INSERT );
2016-11-02 16:10:51 -04:00
$queryBuilder
2024-07-04 11:18:22 -04:00
-> method ( 'getSQL' )
-> willReturn ( '' );
2021-01-08 06:46:10 -05:00
$queryBuilder
-> method ( 'getParameters' )
-> willReturn ([]);
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([]);
2016-11-02 16:10:51 -04:00
$this -> logger
-> expects ( $this -> never ())
-> method ( 'debug' );
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( false );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> assertEquals ( 3 , $this -> queryBuilder -> executeStatement ());
2016-11-02 16:10:51 -04:00
}
2024-09-15 16:32:31 -04:00
public function testExecuteWithLoggerAndNamedArray () : void {
2016-11-02 16:10:51 -04:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
2026-01-23 10:55:54 -05:00
$queryBuilder
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: INSERT );
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getParameters' )
-> willReturn ([
'foo' => 'bar' ,
'key' => 'value' ,
]);
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([
'foo' => IQueryBuilder :: PARAM_STR ,
'key' => IQueryBuilder :: PARAM_STR ,
]);
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getSQL' )
2024-07-04 11:18:22 -04:00
-> willReturn ( 'UPDATE FOO SET bar = 1 WHERE BAR = ?' );
2016-11-02 16:10:51 -04:00
$this -> logger
-> expects ( $this -> once ())
-> method ( 'debug' )
-> with (
'DB QueryBuilder: \'{query}\' with parameters: {params}' ,
[
2024-07-04 11:18:22 -04:00
'query' => 'UPDATE FOO SET bar = 1 WHERE BAR = ?' ,
2016-11-02 16:10:51 -04:00
'params' => 'foo => \'bar\', key => \'value\'' ,
'app' => 'core' ,
]
);
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( true );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> assertEquals ( 3 , $this -> queryBuilder -> executeStatement ());
2016-11-02 16:10:51 -04:00
}
2024-09-15 16:32:31 -04:00
public function testExecuteWithLoggerAndUnnamedArray () : void {
2016-11-02 16:10:51 -04:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
2026-01-23 10:55:54 -05:00
$queryBuilder
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: INSERT );
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getParameters' )
-> willReturn ([ 'Bar' ]);
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([ IQueryBuilder :: PARAM_STR ]);
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getSQL' )
2024-07-04 11:18:22 -04:00
-> willReturn ( 'UPDATE FOO SET bar = false WHERE BAR = ?' );
2016-11-02 16:10:51 -04:00
$this -> logger
-> expects ( $this -> once ())
-> method ( 'debug' )
-> with (
'DB QueryBuilder: \'{query}\' with parameters: {params}' ,
[
2024-07-04 11:18:22 -04:00
'query' => 'UPDATE FOO SET bar = false WHERE BAR = ?' ,
2016-11-02 16:10:51 -04:00
'params' => '0 => \'Bar\'' ,
'app' => 'core' ,
]
);
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( true );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> assertEquals ( 3 , $this -> queryBuilder -> executeStatement ());
2016-11-02 16:10:51 -04:00
}
2024-09-15 16:32:31 -04:00
public function testExecuteWithLoggerAndNoParams () : void {
2016-11-02 16:10:51 -04:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
2026-01-23 10:55:54 -05:00
$queryBuilder
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: INSERT );
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getParameters' )
-> willReturn ([]);
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([]);
2016-11-02 16:10:51 -04:00
$queryBuilder
2021-01-08 06:46:10 -05:00
-> expects ( $this -> any ())
2016-11-02 16:10:51 -04:00
-> method ( 'getSQL' )
2024-07-04 11:18:22 -04:00
-> willReturn ( 'UPDATE FOO SET bar = false WHERE BAR = ?' );
2016-11-02 16:10:51 -04:00
$this -> logger
-> expects ( $this -> once ())
-> method ( 'debug' )
-> with (
'DB QueryBuilder: \'{query}\'' ,
[
2024-07-04 11:18:22 -04:00
'query' => 'UPDATE FOO SET bar = false WHERE BAR = ?' ,
2016-11-02 16:10:51 -04:00
'app' => 'core' ,
]
);
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( true );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> assertEquals ( 3 , $this -> queryBuilder -> executeStatement ());
2016-11-02 16:10:51 -04:00
}
2021-01-08 06:46:10 -05:00
2024-09-15 16:32:31 -04:00
public function testExecuteWithParameterTooLarge () : void {
2021-01-08 06:46:10 -05:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
$p = array_fill ( 0 , 1001 , 'foo' );
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getParameters' )
-> willReturn ([ $p ]);
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([ IQueryBuilder :: PARAM_STR_ARRAY ]);
2025-08-26 09:20:42 -04:00
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: SELECT );
2021-01-08 06:46:10 -05:00
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getSQL' )
-> willReturn ( 'SELECT * FROM FOO WHERE BAR IN (?)' );
$this -> logger
-> expects ( $this -> once ())
2022-03-21 06:17:14 -04:00
-> method ( 'error' )
2025-06-12 12:31:58 -04:00
-> willReturnCallback ( function ( $message , $parameters ) : void {
2022-03-21 06:17:14 -04:00
$this -> assertInstanceOf ( QueryException :: class , $parameters [ 'exception' ]);
2021-01-08 06:46:10 -05:00
$this -> assertSame (
'More than 1000 expressions in a list are not allowed on Oracle.' ,
2022-03-21 06:17:14 -04:00
$message
2021-01-08 06:46:10 -05:00
);
});
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( false );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> queryBuilder -> executeQuery ();
2021-01-08 06:46:10 -05:00
}
2024-09-15 16:32:31 -04:00
public function testExecuteWithParametersTooMany () : void {
2021-01-08 06:46:10 -05:00
$queryBuilder = $this -> createMock ( \Doctrine\DBAL\Query\QueryBuilder :: class );
$p = array_fill ( 0 , 999 , 'foo' );
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getParameters' )
-> willReturn ( array_fill ( 0 , 66 , $p ));
2024-07-04 11:18:22 -04:00
$queryBuilder
-> method ( 'getParameterTypes' )
-> willReturn ([ IQueryBuilder :: PARAM_STR_ARRAY ]);
2025-08-26 09:20:42 -04:00
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getType' )
-> willReturn ( \Doctrine\DBAL\Query\QueryBuilder :: SELECT );
2021-01-08 06:46:10 -05:00
$queryBuilder
-> expects ( $this -> any ())
-> method ( 'getSQL' )
-> willReturn ( 'SELECT * FROM FOO WHERE BAR IN (?) OR BAR IN (?)' );
$this -> logger
-> expects ( $this -> once ())
2022-03-21 06:17:14 -04:00
-> method ( 'error' )
2025-06-12 12:31:58 -04:00
-> willReturnCallback ( function ( $message , $parameters ) : void {
2022-03-21 06:17:14 -04:00
$this -> assertInstanceOf ( QueryException :: class , $parameters [ 'exception' ]);
2021-01-08 06:46:10 -05:00
$this -> assertSame (
'The number of parameters must not exceed 65535. Restriction by PostgreSQL.' ,
2022-03-21 06:17:14 -04:00
$message
2021-01-08 06:46:10 -05:00
);
});
$this -> config
-> expects ( $this -> once ())
-> method ( 'getValue' )
-> with ( 'log_query' , false )
-> willReturn ( false );
$this -> invokePrivate ( $this -> queryBuilder , 'queryBuilder' , [ $queryBuilder ]);
2024-07-04 11:18:22 -04:00
$this -> invokePrivate ( $this -> queryBuilder , 'connection' , [ $this -> getConnection ()]);
2025-08-26 09:20:42 -04:00
$this -> queryBuilder -> executeQuery ();
2021-01-08 06:46:10 -05:00
}
2015-07-07 11:30:26 -04:00
}