2018-11-22 18:55:57 +00:00
< ? php
/** @ license MIT
* Copyright 2017 J . King , Dustin Wilson et al .
* See LICENSE and AUTHORS files for details */
declare ( strict_types = 1 );
2021-04-14 15:17:01 +00:00
2018-11-22 18:55:57 +00:00
namespace JKingWeb\Arsse\TestCase\Db ;
use JKingWeb\Arsse\Db\Statement ;
use JKingWeb\Arsse\Db\Result ;
abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
2018-12-20 23:06:28 +00:00
protected static $insertDefaultValues = " INSERT INTO arsse_test default values " ;
2018-11-27 19:26:33 +00:00
protected static $interface ;
2018-11-22 18:55:57 +00:00
protected $drv ;
protected $create ;
protected $lock ;
protected $setVersion ;
2018-11-27 19:26:33 +00:00
protected static $conf = [
2020-03-01 20:16:50 +00:00
'dbTimeoutExec' => 0.5 ,
'dbTimeoutLock' => 0.001 ,
2018-11-22 18:55:57 +00:00
'dbSQLite3Timeout' => 0 ,
2018-11-27 19:26:33 +00:00
//'dbSQLite3File' => "(temporary file)",
2018-11-22 18:55:57 +00:00
];
2018-11-27 19:26:33 +00:00
2019-10-16 18:42:43 +00:00
public static function setUpBeforeClass () : void {
2018-11-27 19:26:33 +00:00
// establish a clean baseline
static :: clearData ();
static :: setConf ( static :: $conf );
2019-01-12 17:43:06 +00:00
static :: $interface = static :: dbInterface ();
2018-11-27 19:26:33 +00:00
}
2020-03-01 20:16:50 +00:00
2019-10-16 18:42:43 +00:00
public function setUp () : void {
2021-02-27 20:24:02 +00:00
parent :: setUp ();
2018-11-27 19:26:33 +00:00
self :: setConf ( static :: $conf );
if ( ! static :: $interface ) {
$this -> markTestSkipped ( static :: $implementation . " database driver not available " );
2018-11-22 18:55:57 +00:00
}
2018-11-27 19:26:33 +00:00
// completely clear the database and ensure the schema version can easily be altered
2019-01-12 17:43:06 +00:00
static :: dbRaze ( static :: $interface , [
2018-12-20 23:06:28 +00:00
" CREATE TABLE arsse_meta( \" key \" varchar(255) primary key not null, value text) " ,
" INSERT INTO arsse_meta( \" key \" ,value) values('schema_version','0') " ,
2018-11-27 19:26:33 +00:00
]);
// construct a fresh driver for each test
2019-01-12 17:43:06 +00:00
$this -> drv = new static :: $dbDriverClass ;
2018-11-22 18:55:57 +00:00
}
2019-10-16 18:42:43 +00:00
public function tearDown () : void {
2018-11-27 19:26:33 +00:00
// deconstruct the driver
2018-11-22 18:55:57 +00:00
unset ( $this -> drv );
2021-02-27 20:24:02 +00:00
parent :: tearDown ();
2018-11-22 18:55:57 +00:00
}
2019-10-16 18:42:43 +00:00
public static function tearDownAfterClass () : void {
2018-12-10 18:17:04 +00:00
if ( static :: $interface ) {
// completely clear the database
2019-01-12 17:43:06 +00:00
static :: dbRaze ( static :: $interface );
2018-12-10 18:17:04 +00:00
}
2018-12-06 22:46:00 +00:00
static :: $interface = null ;
2021-02-27 20:24:02 +00:00
self :: clearData ( true );
2018-11-27 19:26:33 +00:00
}
protected function exec ( $q ) : bool {
2018-11-22 18:55:57 +00:00
// PDO implementation
2018-11-27 19:26:33 +00:00
$q = ( ! is_array ( $q )) ? [ $q ] : $q ;
foreach ( $q as $query ) {
static :: $interface -> exec (( string ) $query );
}
2018-11-22 18:55:57 +00:00
return true ;
}
protected function query ( string $q ) {
// PDO implementation
2018-11-27 19:26:33 +00:00
return static :: $interface -> query ( $q ) -> fetchColumn ();
2018-11-22 18:55:57 +00:00
}
2018-12-05 22:28:11 +00:00
# TESTS
2020-03-01 20:16:50 +00:00
2020-01-20 18:52:48 +00:00
public function testFetchDriverName () : void {
2018-11-22 18:55:57 +00:00
$class = get_class ( $this -> drv );
$this -> assertTrue ( strlen ( $class :: driverName ()) > 0 );
}
2020-03-01 20:16:50 +00:00
2020-01-20 18:52:48 +00:00
public function testFetchSchemaId () : void {
2018-11-28 15:46:23 +00:00
$class = get_class ( $this -> drv );
$this -> assertTrue ( strlen ( $class :: schemaID ()) > 0 );
}
2018-11-22 18:55:57 +00:00
2020-01-20 18:52:48 +00:00
public function testCheckCharacterSetAcceptability () : void {
2018-11-22 18:55:57 +00:00
$this -> assertTrue ( $this -> drv -> charsetAcceptable ());
}
2020-01-20 18:52:48 +00:00
public function testExecAValidStatement () : void {
2018-11-22 18:55:57 +00:00
$this -> assertTrue ( $this -> drv -> exec ( $this -> create ));
}
2020-01-20 18:52:48 +00:00
public function testExecAnInvalidStatement () : void {
2018-11-22 18:55:57 +00:00
$this -> assertException ( " engineErrorGeneral " , " Db " );
$this -> drv -> exec ( " And the meek shall inherit the earth... " );
}
2020-01-20 18:52:48 +00:00
public function testExecMultipleStatements () : void {
2018-11-22 18:55:57 +00:00
$this -> assertTrue ( $this -> drv -> exec ( " $this->create ; INSERT INTO arsse_test(id) values(2112) " ));
$this -> assertEquals ( 2112 , $this -> query ( " SELECT id from arsse_test " ));
}
2020-01-20 18:52:48 +00:00
public function testExecTimeout () : void {
2018-11-22 18:55:57 +00:00
$this -> exec ( $this -> create );
$this -> exec ( $this -> lock );
$this -> assertException ( " general " , " Db " , " ExceptionTimeout " );
2018-12-20 23:06:28 +00:00
$this -> drv -> exec ( " INSERT INTO arsse_meta( \" key \" , value) values('lock', '1') " );
2018-11-22 18:55:57 +00:00
}
2020-01-20 18:52:48 +00:00
public function testExecConstraintViolation () : void {
2018-11-22 18:55:57 +00:00
$this -> drv -> exec ( " CREATE TABLE arsse_test(id varchar(255) not null) " );
$this -> assertException ( " constraintViolation " , " Db " , " ExceptionInput " );
2018-12-20 23:06:28 +00:00
$this -> drv -> exec ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
}
2020-01-20 18:52:48 +00:00
public function testExecTypeViolation () : void {
2018-11-22 18:55:57 +00:00
$this -> drv -> exec ( $this -> create );
$this -> assertException ( " typeViolation " , " Db " , " ExceptionInput " );
$this -> drv -> exec ( " INSERT INTO arsse_test(id) values('ook') " );
}
2020-01-20 18:52:48 +00:00
public function testMakeAValidQuery () : void {
2018-11-22 18:55:57 +00:00
$this -> assertInstanceOf ( Result :: class , $this -> drv -> query ( " SELECT 1 " ));
}
2020-01-20 18:52:48 +00:00
public function testMakeAnInvalidQuery () : void {
2018-11-22 18:55:57 +00:00
$this -> assertException ( " engineErrorGeneral " , " Db " );
$this -> drv -> query ( " Apollo was astonished; Dionysus thought me mad " );
}
2020-01-20 18:52:48 +00:00
public function testQueryConstraintViolation () : void {
2018-11-22 18:55:57 +00:00
$this -> drv -> exec ( " CREATE TABLE arsse_test(id integer not null) " );
$this -> assertException ( " constraintViolation " , " Db " , " ExceptionInput " );
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
}
2020-01-20 18:52:48 +00:00
public function testQueryTypeViolation () : void {
2018-11-22 18:55:57 +00:00
$this -> drv -> exec ( $this -> create );
$this -> assertException ( " typeViolation " , " Db " , " ExceptionInput " );
$this -> drv -> query ( " INSERT INTO arsse_test(id) values('ook') " );
}
2020-01-20 18:52:48 +00:00
public function testPrepareAValidQuery () : void {
2018-11-22 18:55:57 +00:00
$s = $this -> drv -> prepare ( " SELECT ?, ? " , " int " , " int " );
$this -> assertInstanceOf ( Statement :: class , $s );
}
2020-01-20 18:52:48 +00:00
public function testPrepareAnInvalidQuery () : void {
2018-11-22 18:55:57 +00:00
$this -> assertException ( " engineErrorGeneral " , " Db " );
$s = $this -> drv -> prepare ( " This is an invalid query " , " int " , " int " ) -> run ();
}
2020-01-20 18:52:48 +00:00
public function testCreateASavepoint () : void {
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 2 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 3 , $this -> drv -> savepointCreate ());
}
2020-01-20 18:52:48 +00:00
public function testReleaseASavepoint () : void {
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( true , $this -> drv -> savepointRelease ());
$this -> assertException ( " savepointInvalid " , " Db " );
$this -> drv -> savepointRelease ();
}
2020-01-20 18:52:48 +00:00
public function testUndoASavepoint () : void {
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( true , $this -> drv -> savepointUndo ());
$this -> assertException ( " savepointInvalid " , " Db " );
$this -> drv -> savepointUndo ();
}
2020-01-20 18:52:48 +00:00
public function testManipulateSavepoints () : void {
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 2 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 3 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 4 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 5 , $this -> drv -> savepointCreate ());
$this -> assertTrue ( $this -> drv -> savepointUndo ( 3 ));
$this -> assertFalse ( $this -> drv -> savepointRelease ( 4 ));
$this -> assertEquals ( 6 , $this -> drv -> savepointCreate ());
$this -> assertFalse ( $this -> drv -> savepointRelease ( 5 ));
$this -> assertTrue ( $this -> drv -> savepointRelease ( 6 ));
$this -> assertEquals ( 3 , $this -> drv -> savepointCreate ());
$this -> assertTrue ( $this -> drv -> savepointRelease ( 2 ));
$this -> assertException ( " savepointStale " , " Db " );
$this -> drv -> savepointRelease ( 2 );
}
2020-01-20 18:52:48 +00:00
public function testManipulateSavepointsSomeMore () : void {
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 2 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 3 , $this -> drv -> savepointCreate ());
$this -> assertEquals ( 4 , $this -> drv -> savepointCreate ());
$this -> assertTrue ( $this -> drv -> savepointRelease ( 2 ));
$this -> assertFalse ( $this -> drv -> savepointUndo ( 3 ));
$this -> assertException ( " savepointStale " , " Db " );
$this -> drv -> savepointUndo ( 2 );
}
2020-01-20 18:52:48 +00:00
public function testBeginATransaction () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testCommitATransaction () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr -> commit ();
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 1 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testRollbackATransaction () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr -> rollback ();
$this -> assertEquals ( 0 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testBeginChainedTransactions () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testCommitChainedTransactions () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 -> commit ();
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr1 -> commit ();
$this -> assertEquals ( 2 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testCommitChainedTransactionsOutOfOrder () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr1 -> commit ();
$this -> assertEquals ( 2 , $this -> query ( $select ));
$tr2 -> commit ();
}
2020-01-20 18:52:48 +00:00
public function testRollbackChainedTransactions () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 -> rollback ();
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr1 -> rollback ();
$this -> assertEquals ( 0 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testRollbackChainedTransactionsOutOfOrder () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr1 -> rollback ();
$this -> assertEquals ( 0 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 -> rollback ();
$this -> assertEquals ( 0 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testPartiallyRollbackChainedTransactions () : void {
2018-11-22 18:55:57 +00:00
$select = " SELECT count(*) FROM arsse_test " ;
$this -> drv -> exec ( $this -> create );
$tr1 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 = $this -> drv -> begin ();
2018-12-20 23:06:28 +00:00
$this -> drv -> query ( static :: $insertDefaultValues );
2018-11-22 18:55:57 +00:00
$this -> assertEquals ( 2 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr2 -> rollback ();
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 0 , $this -> query ( $select ));
$tr1 -> commit ();
$this -> assertEquals ( 1 , $this -> drv -> query ( $select ) -> getValue ());
$this -> assertEquals ( 1 , $this -> query ( $select ));
}
2020-01-20 18:52:48 +00:00
public function testFetchSchemaVersion () : void {
2018-11-22 18:55:57 +00:00
$this -> assertSame ( 0 , $this -> drv -> schemaVersion ());
$this -> drv -> exec ( str_replace ( " # " , " 1 " , $this -> setVersion ));
$this -> assertSame ( 1 , $this -> drv -> schemaVersion ());
$this -> drv -> exec ( str_replace ( " # " , " 2 " , $this -> setVersion ));
$this -> assertSame ( 2 , $this -> drv -> schemaVersion ());
2018-11-27 19:26:33 +00:00
// SQLite is unaffected by the removal of the metadata table; other backends are
// in neither case should a query for the schema version produce an error, however
$this -> exec ( " DROP TABLE IF EXISTS arsse_meta " );
2019-01-12 17:43:06 +00:00
$exp = ( static :: $backend === " SQLite 3 " ) ? 2 : 0 ;
2018-11-27 19:26:33 +00:00
$this -> assertSame ( $exp , $this -> drv -> schemaVersion ());
2018-11-22 18:55:57 +00:00
}
2020-01-20 18:52:48 +00:00
public function testLockTheDatabase () : void {
2018-11-27 19:26:33 +00:00
// PostgreSQL doesn't actually lock the whole database, only the metadata table
// normally the application will first query this table to ensure the schema version is correct,
// so the effect is usually the same
2018-11-22 18:55:57 +00:00
$this -> drv -> savepointCreate ( true );
$this -> assertException ();
2018-11-27 22:16:00 +00:00
$this -> exec ( $this -> lock );
2018-11-22 18:55:57 +00:00
}
2020-01-20 18:52:48 +00:00
public function testUnlockTheDatabase () : void {
2018-11-22 18:55:57 +00:00
$this -> drv -> savepointCreate ( true );
$this -> drv -> savepointRelease ();
$this -> drv -> savepointCreate ( true );
$this -> drv -> savepointUndo ();
2018-11-27 19:26:33 +00:00
$this -> assertTrue ( $this -> exec ( str_replace ( " # " , " 3 " , $this -> setVersion )));
2018-11-22 18:55:57 +00:00
}
2019-03-02 03:36:25 +00:00
2020-01-20 18:52:48 +00:00
public function testProduceAStringLiteral () : void {
2019-03-02 03:36:25 +00:00
$this -> assertSame ( " 'It''s a string!' " , $this -> drv -> literalString ( " It's a string! " ));
}
2019-07-26 13:37:51 +00:00
2020-01-20 18:52:48 +00:00
public function testPerformMaintenance () : void {
2019-07-26 13:37:51 +00:00
// this performs maintenance in the absence of tables; see BaseUpdate.php for another test with tables
$this -> assertTrue ( $this -> drv -> maintenance ());
}
2021-01-07 15:12:38 +00:00
public function testTranslateTokens () : void {
$greatest = $this -> drv -> sqlToken ( " GrEatESt " );
$nocase = $this -> drv -> sqlToken ( " noCASE " );
$like = $this -> drv -> sqlToken ( " liKe " );
2021-02-02 15:00:08 +00:00
$asc = $this -> drv -> sqlToken ( " asc " );
$desc = $this -> drv -> sqlToken ( " desc " );
2022-04-24 16:25:37 +00:00
$least = $this -> drv -> sqlToken ( " leASt " );
2021-01-07 15:12:38 +00:00
$this -> assertSame ( " NOT_A_TOKEN " , $this -> drv -> sqlToken ( " NOT_A_TOKEN " ));
2022-04-24 16:25:37 +00:00
$this -> assertSame ( " A " , $this -> drv -> query ( " SELECT $least ('Z', 'A') " ) -> getValue ());
2021-01-07 15:12:38 +00:00
$this -> assertSame ( " Z " , $this -> drv -> query ( " SELECT $greatest ('Z', 'A') " ) -> getValue ());
$this -> assertSame ( " Z " , $this -> drv -> query ( " SELECT 'Z' collate $nocase " ) -> getValue ());
$this -> assertSame ( " Z " , $this -> drv -> query ( " SELECT 'Z' where 'Z' $like 'z' " ) -> getValue ());
2021-02-03 19:20:34 +00:00
$this -> assertEquals ([ null , 1 , 2 ], array_column ( $this -> drv -> query ( " SELECT 1 as t union select null as t union select 2 as t order by t $asc " ) -> getAll (), " t " ));
$this -> assertEquals ([ 2 , 1 , null ], array_column ( $this -> drv -> query ( " SELECT 1 as t union select null as t union select 2 as t order by t $desc " ) -> getAll (), " t " ));
2021-01-07 15:12:38 +00:00
}
2018-11-22 18:55:57 +00:00
}