mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Align result tests with driver tests
This commit is contained in:
parent
aa1b65b5d4
commit
f22e53fdc9
25 changed files with 358 additions and 379 deletions
|
@ -8,7 +8,7 @@ namespace JKingWeb\Arsse\TestCase\Db;
|
||||||
|
|
||||||
use JKingWeb\Arsse\Db\Statement;
|
use JKingWeb\Arsse\Db\Statement;
|
||||||
use JKingWeb\Arsse\Db\Result;
|
use JKingWeb\Arsse\Db\Result;
|
||||||
|
use JKingWeb\Arsse\Test\DatabaseInformation;
|
||||||
|
|
||||||
abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
protected $drv;
|
protected $drv;
|
||||||
|
@ -22,12 +22,13 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
];
|
];
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->setConf($this->conf);
|
self::setConf($this->conf);
|
||||||
$this->interface = $this->getDbInterface($this->implementation);
|
$info = new DatabaseInformation($this->implementation);
|
||||||
|
$this->interface = ($info->interfaceConstructor)();
|
||||||
if (!$this->interface) {
|
if (!$this->interface) {
|
||||||
$this->markTestSkipped("$this->implementation database driver not available");
|
$this->markTestSkipped("$this->implementation database driver not available");
|
||||||
}
|
}
|
||||||
$this->drv = $this->getDbDriver($this->implementation);
|
$this->drv = new $info->driverClass;
|
||||||
$this->exec("DROP TABLE IF EXISTS arsse_test");
|
$this->exec("DROP TABLE IF EXISTS arsse_test");
|
||||||
$this->exec("DROP TABLE IF EXISTS arsse_meta");
|
$this->exec("DROP TABLE IF EXISTS arsse_meta");
|
||||||
$this->exec("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");
|
$this->exec("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");
|
||||||
|
|
112
tests/cases/Db/BaseResult.php
Normal file
112
tests/cases/Db/BaseResult.php
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
/** @license MIT
|
||||||
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
||||||
|
* See LICENSE and AUTHORS files for details */
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\Arsse\TestCase\Db;
|
||||||
|
|
||||||
|
use JKingWeb\Arsse\Db\Result;
|
||||||
|
use JKingWeb\Arsse\Test\DatabaseInformation;
|
||||||
|
|
||||||
|
abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
protected $resultClass;
|
||||||
|
protected $stringOutput;
|
||||||
|
protected $interface;
|
||||||
|
|
||||||
|
abstract protected function exec(string $q);
|
||||||
|
abstract protected function makeResult(string $q): array;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
self::setConf();
|
||||||
|
$info = new DatabaseInformation($this->implementation);
|
||||||
|
$this->interface = ($info->interfaceConstructor)();
|
||||||
|
if (!$this->interface) {
|
||||||
|
$this->markTestSkipped("$this->implementation database driver not available");
|
||||||
|
}
|
||||||
|
$this->resultClass = $info->resultClass;
|
||||||
|
$this->stringOutput = $info->stringOutput;
|
||||||
|
$this->exec("DROP TABLE IF EXISTS arsse_meta");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown() {
|
||||||
|
$this->exec("DROP TABLE IF EXISTS arsse_meta");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConstructResult() {
|
||||||
|
$this->assertInstanceOf(Result::class, new $this->resultClass(...$this->makeResult("SELECT 1")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetChangeCountAndLastInsertId() {
|
||||||
|
$this->makeResult("CREATE TABLE arsse_meta(key varchar(255) primary key not null, value text)");
|
||||||
|
$out = $this->makeResult("INSERT INTO arsse_meta(key,value) values('test', 1)");
|
||||||
|
$rows = $out[1][0];
|
||||||
|
$id = $out[1][1];
|
||||||
|
$r = new $this->resultClass(...$out);
|
||||||
|
$this->assertSame((int) $rows, $r->changes());
|
||||||
|
$this->assertSame((int) $id, $r->lastId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIterateOverResults() {
|
||||||
|
$exp = [0 => 1, 1 => 2, 2 => 3];
|
||||||
|
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
|
||||||
|
foreach (new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
|
||||||
|
$rows[$index] = $row['col'];
|
||||||
|
}
|
||||||
|
$this->assertSame($exp, $rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIterateOverResultsTwice() {
|
||||||
|
$exp = [0 => 1, 1 => 2, 2 => 3];
|
||||||
|
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
|
||||||
|
$result = new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col"));
|
||||||
|
foreach ($result as $index => $row) {
|
||||||
|
$rows[$index] = $row['col'];
|
||||||
|
}
|
||||||
|
$this->assertSame($exp, $rows);
|
||||||
|
$this->assertException("resultReused", "Db");
|
||||||
|
foreach ($result as $row) {
|
||||||
|
$rows[] = $row['col'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSingleValues() {
|
||||||
|
$exp = [1867, 1970, 2112];
|
||||||
|
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
|
||||||
|
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union select 1970 as year union select 2112 as year"));
|
||||||
|
$this->assertSame($exp[0], $test->getValue());
|
||||||
|
$this->assertSame($exp[1], $test->getValue());
|
||||||
|
$this->assertSame($exp[2], $test->getValue());
|
||||||
|
$this->assertSame(null, $test->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetFirstValuesOnly() {
|
||||||
|
$exp = [1867, 1970, 2112];
|
||||||
|
$exp = $this->stringOutput ? $this->stringify($exp) : $exp;
|
||||||
|
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century"));
|
||||||
|
$this->assertSame($exp[0], $test->getValue());
|
||||||
|
$this->assertSame($exp[1], $test->getValue());
|
||||||
|
$this->assertSame($exp[2], $test->getValue());
|
||||||
|
$this->assertSame(null, $test->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRows() {
|
||||||
|
$exp = [
|
||||||
|
['album' => '2112', 'track' => '2112'],
|
||||||
|
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
||||||
|
];
|
||||||
|
$test = new $this->resultClass(...$this->makeResult("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
|
||||||
|
$this->assertSame($exp[0], $test->getRow());
|
||||||
|
$this->assertSame($exp[1], $test->getRow());
|
||||||
|
$this->assertSame(null, $test->getRow());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAllRows() {
|
||||||
|
$exp = [
|
||||||
|
['album' => '2112', 'track' => '2112'],
|
||||||
|
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
||||||
|
];
|
||||||
|
$test = new $this->resultClass(...$this->makeResult("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
|
||||||
|
$this->assertEquals($exp, $test->getAll());
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ use JKingWeb\Arsse\Db\PostgreSQL\Driver;
|
||||||
class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
/** @dataProvider provideConnectionStrings */
|
/** @dataProvider provideConnectionStrings */
|
||||||
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp) {
|
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp) {
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
|
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
|
||||||
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
|
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
|
||||||
$act = Driver::makeConnectionString($pdo, $user, $pass, $db, $host, $port, $service);
|
$act = Driver::makeConnectionString($pdo, $user, $pass, $db, $host, $port, $service);
|
||||||
|
|
|
@ -107,7 +107,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
chmod($path."Awal/arsse.db-wal", 0111);
|
chmod($path."Awal/arsse.db-wal", 0111);
|
||||||
chmod($path."Ashm/arsse.db-shm", 0111);
|
chmod($path."Ashm/arsse.db-shm", 0111);
|
||||||
// set up configuration
|
// set up configuration
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown() {
|
||||||
|
|
|
@ -49,7 +49,7 @@ class TestDriver extends \JKingWeb\Arsse\TestCase\Db\BaseDriver {
|
||||||
|
|
||||||
public function provideDrivers() {
|
public function provideDrivers() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf([
|
self::setConf([
|
||||||
'dbTimeoutExec' => 0.5,
|
'dbTimeoutExec' => 0.5,
|
||||||
'dbSQLite3Timeout' => 0,
|
'dbSQLite3Timeout' => 0,
|
||||||
'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),
|
'dbSQLite3File' => tempnam(sys_get_temp_dir(), 'ook'),
|
||||||
|
|
33
tests/cases/Db/SQLite3/TestResult.php
Normal file
33
tests/cases/Db/SQLite3/TestResult.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
/** @license MIT
|
||||||
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
||||||
|
* See LICENSE and AUTHORS files for details */
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\Arsse\TestCase\Db\SQLite3;
|
||||||
|
|
||||||
|
use JKingWeb\Arsse\Test\DatabaseInformation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
|
||||||
|
*/
|
||||||
|
class TestResult extends \JKingWeb\Arsse\TestCase\Db\BaseResult {
|
||||||
|
protected $implementation = "SQLite 3";
|
||||||
|
|
||||||
|
public function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
$this->interface->close();
|
||||||
|
unset($this->interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function exec(string $q) {
|
||||||
|
$this->interface->exec($q);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function makeResult(string $q): array {
|
||||||
|
$set = $this->interface->query($q);
|
||||||
|
$rows = $this->interface->changes();
|
||||||
|
$id = $this->interface->lastInsertRowID();
|
||||||
|
return [$set, [$rows, $id]];
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,7 @@ class TestUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
|
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
|
||||||
$this->setConf($conf);
|
self::setConf($conf);
|
||||||
$this->base = $this->vfs->url();
|
$this->base = $this->vfs->url();
|
||||||
$this->path = $this->base."/SQLite3/";
|
$this->path = $this->base."/SQLite3/";
|
||||||
$this->drv = new Driver();
|
$this->drv = new Driver();
|
||||||
|
|
|
@ -108,7 +108,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
chmod($path."Awal/arsse.db-wal", 0111);
|
chmod($path."Awal/arsse.db-wal", 0111);
|
||||||
chmod($path."Ashm/arsse.db-shm", 0111);
|
chmod($path."Ashm/arsse.db-shm", 0111);
|
||||||
// set up configuration
|
// set up configuration
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown() {
|
public function tearDown() {
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TestUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
|
$this->vfs = vfsStream::setup("schemata", null, ['SQLite3' => []]);
|
||||||
$conf['dbDriver'] = PDODriver::class;
|
$conf['dbDriver'] = PDODriver::class;
|
||||||
$this->setConf($conf);
|
self::setConf($conf);
|
||||||
$this->base = $this->vfs->url();
|
$this->base = $this->vfs->url();
|
||||||
$this->path = $this->base."/SQLite3/";
|
$this->path = $this->base."/SQLite3/";
|
||||||
$this->drv = new PDODriver();
|
$this->drv = new PDODriver();
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
<?php
|
|
||||||
/** @license MIT
|
|
||||||
* Copyright 2017 J. King, Dustin Wilson et al.
|
|
||||||
* See LICENSE and AUTHORS files for details */
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
namespace JKingWeb\Arsse\TestCase\Db;
|
|
||||||
|
|
||||||
use JKingWeb\Arsse\Arsse;
|
|
||||||
use JKingWeb\Arsse\Db\Result;
|
|
||||||
use JKingWeb\Arsse\Db\PDOResult;
|
|
||||||
use JKingWeb\Arsse\Db\SQLite3\PDODriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @covers \JKingWeb\Arsse\Db\PDOResult<extended>
|
|
||||||
* @covers \JKingWeb\Arsse\Db\SQLite3\Result<extended>
|
|
||||||
*/
|
|
||||||
class TestResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|
||||||
public function provideResults() {
|
|
||||||
$this->setConf();
|
|
||||||
$interfaces = $this->provideDbInterfaces();
|
|
||||||
$constructors = [
|
|
||||||
'SQLite 3' => function(string $query) use($interfaces) {
|
|
||||||
$drv = $interfaces['SQLite 3']['interface'];
|
|
||||||
$set = $drv->query($query);
|
|
||||||
$rows = $drv->changes();
|
|
||||||
$id = $drv->lastInsertRowID();
|
|
||||||
return [$set, [$rows, $id]];
|
|
||||||
},
|
|
||||||
];
|
|
||||||
foreach ($constructors as $drv => $func) {
|
|
||||||
yield $drv => [isset($interfaces[$drv]['interface']), $interfaces[$drv]['stringOutput'], $interfaces[$drv]['result'], $func];
|
|
||||||
}
|
|
||||||
// there is only one PDO result implementation, so we test the first implementation we find
|
|
||||||
$pdo = array_reduce($interfaces, function ($carry, $item) {
|
|
||||||
return $carry ?? ($item['interface'] instanceof \PDO ? $item : null);
|
|
||||||
}) ?? $interfaces['PDO SQLite 3'];
|
|
||||||
yield "PDO" => [isset($pdo['interface']), $pdo['stringOutput'], $pdo['result'], function(string $query) use($pdo) {
|
|
||||||
$drv = $pdo['interface'];
|
|
||||||
$set = $drv->query($query);
|
|
||||||
$rows = $set->rowCount();
|
|
||||||
$id = $drv->lastInsertID();
|
|
||||||
return [$set, [$rows, $id]];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testConstructResult(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$this->assertInstanceOf(Result::class, new $class(...$func("SELECT 1")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testGetChangeCountAndLastInsertId(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$func("CREATE TABLE if not exists arsse_meta(key varchar(255) primary key not null, value text)");
|
|
||||||
$out = $func("INSERT INTO arsse_meta(key,value) values('test', 1)");
|
|
||||||
$rows = $out[1][0];
|
|
||||||
$id = $out[1][1];
|
|
||||||
$r = new $class(...$out);
|
|
||||||
$this->assertSame((int) $rows, $r->changes());
|
|
||||||
$this->assertSame((int) $id, $r->lastId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testIterateOverResults(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [0 => 1, 1 => 2, 2 => 3];
|
|
||||||
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
|
|
||||||
foreach (new $class(...$func("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
|
|
||||||
$rows[$index] = $row['col'];
|
|
||||||
}
|
|
||||||
$this->assertSame($exp, $rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testIterateOverResultsTwice(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [0 => 1, 1 => 2, 2 => 3];
|
|
||||||
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
|
|
||||||
$result = new $class(...$func("SELECT 1 as col union select 2 as col union select 3 as col"));
|
|
||||||
foreach ($result as $index => $row) {
|
|
||||||
$rows[$index] = $row['col'];
|
|
||||||
}
|
|
||||||
$this->assertSame($exp, $rows);
|
|
||||||
$this->assertException("resultReused", "Db");
|
|
||||||
foreach ($result as $row) {
|
|
||||||
$rows[] = $row['col'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testGetSingleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [1867, 1970, 2112];
|
|
||||||
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
|
|
||||||
$test = new $class(...$func("SELECT 1867 as year union select 1970 as year union select 2112 as year"));
|
|
||||||
$this->assertSame($exp[0], $test->getValue());
|
|
||||||
$this->assertSame($exp[1], $test->getValue());
|
|
||||||
$this->assertSame($exp[2], $test->getValue());
|
|
||||||
$this->assertSame(null, $test->getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testGetFirstValuesOnly(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [1867, 1970, 2112];
|
|
||||||
$exp = $stringCoersion ? $this->stringify($exp) : $exp;
|
|
||||||
$test = new $class(...$func("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century"));
|
|
||||||
$this->assertSame($exp[0], $test->getValue());
|
|
||||||
$this->assertSame($exp[1], $test->getValue());
|
|
||||||
$this->assertSame($exp[2], $test->getValue());
|
|
||||||
$this->assertSame(null, $test->getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testGetRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [
|
|
||||||
['album' => '2112', 'track' => '2112'],
|
|
||||||
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
|
||||||
];
|
|
||||||
$test = new $class(...$func("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
|
|
||||||
$this->assertSame($exp[0], $test->getRow());
|
|
||||||
$this->assertSame($exp[1], $test->getRow());
|
|
||||||
$this->assertSame(null, $test->getRow());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @dataProvider provideResults */
|
|
||||||
public function testGetAllRows(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
|
||||||
if (!$driverTestable) {
|
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [
|
|
||||||
['album' => '2112', 'track' => '2112'],
|
|
||||||
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
|
||||||
];
|
|
||||||
$test = new $class(...$func("SELECT '2112' as album, '2112' as track union select 'Clockwork Angels' as album, 'The Wreckers' as track"));
|
|
||||||
$this->assertEquals($exp, $test->getAll());
|
|
||||||
}
|
|
||||||
}
|
|
52
tests/cases/Db/TestResultPDO.php
Normal file
52
tests/cases/Db/TestResultPDO.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
/** @license MIT
|
||||||
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
||||||
|
* See LICENSE and AUTHORS files for details */
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\Arsse\TestCase\Db;
|
||||||
|
|
||||||
|
use JKingWeb\Arsse\Test\DatabaseInformation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \JKingWeb\Arsse\Db\PDOResult<extended>
|
||||||
|
*/
|
||||||
|
class TestResultPDO extends \JKingWeb\Arsse\TestCase\Db\BaseResult {
|
||||||
|
protected static $firstAvailableDriver;
|
||||||
|
|
||||||
|
public static function setUpBeforeClass() {
|
||||||
|
self::setConf();
|
||||||
|
// we only need to test one PDO implementation (they all use the same result class), so we find the first usable one
|
||||||
|
$drivers = DatabaseInformation::listPDO();
|
||||||
|
self::$firstAvailableDriver = $drivers[0];
|
||||||
|
foreach ($drivers as $driver) {
|
||||||
|
$info = new DatabaseInformation($driver);
|
||||||
|
$interface = ($info->interfaceConstructor)();
|
||||||
|
if ($interface) {
|
||||||
|
self::$firstAvailableDriver = $driver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
$this->implementation = self::$firstAvailableDriver;
|
||||||
|
parent::setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
unset($this->interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function exec(string $q) {
|
||||||
|
$this->interface->exec($q);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function makeResult(string $q): array {
|
||||||
|
$set = $this->interface->query($q);
|
||||||
|
$rows = $set->rowCount();
|
||||||
|
$id = $this->interface->lastInsertID();
|
||||||
|
return [$set, [$rows, $id]];
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,18 +38,14 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testConstructStatement(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testConstructStatement() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$this->assertInstanceOf(Statement::class, new $class(...$func("SELECT ? as value")));
|
$this->assertInstanceOf(Statement::class, new $class(...$func("SELECT ? as value")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideBindings */
|
/** @dataProvider provideBindings */
|
||||||
public function testBindATypedValue(bool $driverTestable, string $class, \Closure $func, $value, string $type, string $exp) {
|
public function testBindATypedValue(bool $driverTestable, string $class, \Closure $func, $value, string $type, string $exp) {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
if ($exp=="null") {
|
if ($exp=="null") {
|
||||||
$query = "SELECT (cast(? as text) is null) as pass";
|
$query = "SELECT (cast(? as text) is null) as pass";
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,10 +59,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideBinaryBindings */
|
/** @dataProvider provideBinaryBindings */
|
||||||
public function testHandleBinaryData(bool $driverTestable, string $class, \Closure $func, $value, string $type, string $exp) {
|
public function testHandleBinaryData($value, string $type, string $exp) {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
if ($exp=="null") {
|
if ($exp=="null") {
|
||||||
$query = "SELECT (cast(? as text) is null) as pass";
|
$query = "SELECT (cast(? as text) is null) as pass";
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,20 +74,16 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testBindMissingValue(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testBindMissingValue() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$s = new $class(...$func("SELECT ? as value", ["int"]));
|
$s = new $class(...$func("SELECT ? as value", ["int"]));
|
||||||
$val = $s->runArray()->getRow()['value'];
|
$val = $s->runArray()->getRow()['value'];
|
||||||
$this->assertSame(null, $val);
|
$this->assertSame(null, $val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testBindMultipleValues(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testBindMultipleValues() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [
|
$exp = [
|
||||||
'one' => 1,
|
'one' => 1,
|
||||||
'two' => 2,
|
'two' => 2,
|
||||||
|
@ -105,10 +95,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testBindRecursively(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testBindRecursively() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$exp = [
|
$exp = [
|
||||||
'one' => 1,
|
'one' => 1,
|
||||||
'two' => 2,
|
'two' => 2,
|
||||||
|
@ -122,20 +110,16 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testBindWithoutType(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testBindWithoutType() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
$this->assertException("paramTypeMissing", "Db");
|
$this->assertException("paramTypeMissing", "Db");
|
||||||
$s = new $class(...$func("SELECT ? as value", []));
|
$s = new $class(...$func("SELECT ? as value", []));
|
||||||
$s->runArray([1]);
|
$s->runArray([1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testViolateConstraint(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testViolateConstraint() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
(new $class(...$func("CREATE TABLE if not exists arsse_meta(key varchar(255) primary key not null, value text)")))->run();
|
(new $class(...$func("CREATE TABLE if not exists arsse_meta(key varchar(255) primary key not null, value text)")))->run();
|
||||||
$s = new $class(...$func("INSERT INTO arsse_meta(key) values(?)", ["str"]));
|
$s = new $class(...$func("INSERT INTO arsse_meta(key) values(?)", ["str"]));
|
||||||
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
$this->assertException("constraintViolation", "Db", "ExceptionInput");
|
||||||
|
@ -143,10 +127,8 @@ class TestStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @dataProvider provideStatements */
|
/** @dataProvider provideStatements */
|
||||||
public function testMismatchTypes(bool $driverTestable, bool $stringCoersion, string $class, \Closure $func) {
|
public function testMismatchTypes() {
|
||||||
if (!$driverTestable) {
|
$class = $this->statementClass;
|
||||||
$this->markTestSkipped();
|
|
||||||
}
|
|
||||||
(new $class(...$func("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run();
|
(new $class(...$func("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run();
|
||||||
$s = new $class(...$func("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"]));
|
$s = new $class(...$func("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"]));
|
||||||
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
$this->assertException("typeViolation", "Db", "ExceptionInput");
|
||||||
|
|
|
@ -96,7 +96,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
$this->base = self::$host."Feed/";
|
$this->base = self::$host."Feed/";
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
Arsse::$db = Phake::mock(Database::class);
|
Arsse::$db = Phake::mock(Database::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class TestFetching extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
$this->base = self::$host."Feed/";
|
$this->base = self::$host."Feed/";
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandle400() {
|
public function testHandle400() {
|
||||||
|
|
|
@ -340,7 +340,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// create a mock user manager
|
// create a mock user manager
|
||||||
Arsse::$user = Phake::mock(User::class);
|
Arsse::$user = Phake::mock(User::class);
|
||||||
Phake::when(Arsse::$user)->auth->thenReturn(true);
|
Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||||
|
|
|
@ -95,7 +95,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSendAuthenticationChallenges() {
|
public function testSendAuthenticationChallenges() {
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
$r = new REST();
|
$r = new REST();
|
||||||
$in = new EmptyResponse(401);
|
$in = new EmptyResponse(401);
|
||||||
$exp = $in->withHeader("WWW-Authenticate", 'Basic realm="OOK"');
|
$exp = $in->withHeader("WWW-Authenticate", 'Basic realm="OOK"');
|
||||||
|
@ -151,7 +151,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
/** @dataProvider provideCorsNegotiations */
|
/** @dataProvider provideCorsNegotiations */
|
||||||
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null) {
|
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null) {
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
$r = Phake::partialMock(REST::class);
|
$r = Phake::partialMock(REST::class);
|
||||||
Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function ($origin) {
|
Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function ($origin) {
|
||||||
return $origin;
|
return $origin;
|
||||||
|
|
|
@ -177,7 +177,7 @@ LONG_STRING;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// create a mock user manager
|
// create a mock user manager
|
||||||
Arsse::$user = Phake::mock(User::class);
|
Arsse::$user = Phake::mock(User::class);
|
||||||
Phake::when(Arsse::$user)->auth->thenReturn(true);
|
Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||||
|
@ -225,7 +225,7 @@ LONG_STRING;
|
||||||
/** @dataProvider provideLoginRequests */
|
/** @dataProvider provideLoginRequests */
|
||||||
public function testLogIn(array $conf, $httpUser, array $data, $sessions) {
|
public function testLogIn(array $conf, $httpUser, array $data, $sessions) {
|
||||||
Arsse::$user->id = null;
|
Arsse::$user->id = null;
|
||||||
$this->setConf($conf);
|
self::setConf($conf);
|
||||||
Phake::when(Arsse::$user)->auth->thenReturn(false);
|
Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||||
Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||||
Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
|
Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
|
||||||
|
@ -259,7 +259,7 @@ LONG_STRING;
|
||||||
/** @dataProvider provideResumeRequests */
|
/** @dataProvider provideResumeRequests */
|
||||||
public function testValidateASession(array $conf, $httpUser, string $data, $result) {
|
public function testValidateASession(array $conf, $httpUser, string $data, $result) {
|
||||||
Arsse::$user->id = null;
|
Arsse::$user->id = null;
|
||||||
$this->setConf($conf);
|
self::setConf($conf);
|
||||||
Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
|
Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
|
||||||
'id' => "PriestsOfSyrinx",
|
'id' => "PriestsOfSyrinx",
|
||||||
'created' => "2000-01-01 00:00:00",
|
'created' => "2000-01-01 00:00:00",
|
||||||
|
|
|
@ -24,7 +24,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// create a mock user manager
|
// create a mock user manager
|
||||||
Arsse::$user = Phake::mock(User::class);
|
Arsse::$user = Phake::mock(User::class);
|
||||||
// create a mock database interface
|
// create a mock database interface
|
||||||
|
@ -108,7 +108,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
$this->assertMessage($exp, $this->reqAuthFailed("42.ico"));
|
$this->assertMessage($exp, $this->reqAuthFailed("42.ico"));
|
||||||
$this->assertMessage($exp, $this->reqAuthFailed("1337.ico"));
|
$this->assertMessage($exp, $this->reqAuthFailed("1337.ico"));
|
||||||
// with HTTP auth required, only authenticated requests should succeed
|
// with HTTP auth required, only authenticated requests should succeed
|
||||||
$this->setConf(['userHTTPAuthRequired' => true]);
|
self::setConf(['userHTTPAuthRequired' => true]);
|
||||||
$exp = new Response(301, ['Location' => "http://example.org/icon.gif"]);
|
$exp = new Response(301, ['Location' => "http://example.org/icon.gif"]);
|
||||||
$this->assertMessage($exp, $this->reqAuth("42.ico"));
|
$this->assertMessage($exp, $this->reqAuth("42.ico"));
|
||||||
$this->assertMessage($exp, $this->reqAuth("1337.ico"));
|
$this->assertMessage($exp, $this->reqAuth("1337.ico"));
|
||||||
|
|
|
@ -19,7 +19,7 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
Arsse::$db = Phake::mock(Database::class);
|
Arsse::$db = Phake::mock(Database::class);
|
||||||
$this->srv = new Service();
|
$this->srv = new Service();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// create a mock database interface
|
// create a mock database interface
|
||||||
Arsse::$db = Phake::mock(Database::class);
|
Arsse::$db = Phake::mock(Database::class);
|
||||||
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
||||||
|
|
|
@ -20,7 +20,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// create a mock database interface
|
// create a mock database interface
|
||||||
Arsse::$db = Phake::mock(Database::class);
|
Arsse::$db = Phake::mock(Database::class);
|
||||||
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
Phake::when(Arsse::$db)->begin->thenReturn(Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
||||||
|
|
|
@ -40,7 +40,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setConf(array $conf = []) {
|
public static function setConf(array $conf = []) {
|
||||||
$defaults = [
|
$defaults = [
|
||||||
'dbSQLite3File' => ":memory:",
|
'dbSQLite3File' => ":memory:",
|
||||||
'dbSQLite3Timeout' => 0,
|
'dbSQLite3Timeout' => 0,
|
||||||
|
@ -126,165 +126,4 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDbDrivers(array $conf = []): array {
|
|
||||||
$this->setConf($conf);
|
|
||||||
return [
|
|
||||||
'SQLite 3' => (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\SQLite3\Driver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
'PDO SQLite 3' => (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
'PDO PostgreSQL' => (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function provideDbInterfaces(array $conf = []): array {
|
|
||||||
$this->setConf($conf);
|
|
||||||
return [
|
|
||||||
'SQLite 3' => [
|
|
||||||
'interface' => (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
|
|
||||||
try {
|
|
||||||
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$d->enableExceptions(true);
|
|
||||||
return $d;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
'statement' => \JKingWeb\Arsse\Db\SQLite3\Statement::class,
|
|
||||||
'result' => \JKingWeb\Arsse\Db\SQLite3\Result::class,
|
|
||||||
'stringOutput' => false,
|
|
||||||
],
|
|
||||||
'PDO SQLite 3' => [
|
|
||||||
'interface' => (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
|
|
||||||
try {
|
|
||||||
return new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
'statement' => \JKingWeb\Arsse\Db\PDOStatement::class,
|
|
||||||
'result' => \JKingWeb\Arsse\Db\PDOResult::class,
|
|
||||||
'stringOutput' => true,
|
|
||||||
],
|
|
||||||
'PDO PostgreSQL' => [
|
|
||||||
'interface' => (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) {
|
|
||||||
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
|
|
||||||
try {
|
|
||||||
$c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
|
|
||||||
$c->exec($q);
|
|
||||||
}
|
|
||||||
return $c;
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
'statement' => \JKingWeb\Arsse\Db\PDOStatement::class,
|
|
||||||
'result' => \JKingWeb\Arsse\Db\PDOResult::class,
|
|
||||||
'stringOutput' => true,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDbDriver(string $name, array $conf = []) {
|
|
||||||
$this->setConf($conf);
|
|
||||||
switch ($name) {
|
|
||||||
case 'SQLite 3':
|
|
||||||
return (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\SQLite3\Driver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
case 'PDO SQLite 3':
|
|
||||||
return (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\SQLite3\PDODriver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
case 'PDO PostgreSQL':
|
|
||||||
return (function() {
|
|
||||||
try {
|
|
||||||
return new \JKingWeb\Arsse\Db\PostgreSQL\PDODriver;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
default:
|
|
||||||
throw new \Exception("Invalid database driver name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDbInterface(string $name, array $conf = []) {
|
|
||||||
$this->setConf($conf);
|
|
||||||
switch ($name) {
|
|
||||||
case 'SQLite 3':
|
|
||||||
return (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet()) {
|
|
||||||
try {
|
|
||||||
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$d->enableExceptions(true);
|
|
||||||
return $d;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
case 'PDO SQLite 3':
|
|
||||||
return (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
|
|
||||||
try {
|
|
||||||
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
|
||||||
$d->exec("PRAGMA busy_timeout=0");
|
|
||||||
return $d;
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
case 'PDO PostgreSQL':
|
|
||||||
return (function() {
|
|
||||||
if (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::requirementsMet()) {
|
|
||||||
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
|
|
||||||
try {
|
|
||||||
$c = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
|
|
||||||
$c->exec($q);
|
|
||||||
}
|
|
||||||
return $c;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
default:
|
|
||||||
throw new \Exception("Invalid database driver name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ trait Setup {
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
// establish a clean baseline
|
// establish a clean baseline
|
||||||
$this->clearData();
|
$this->clearData();
|
||||||
$this->setConf();
|
self::setConf();
|
||||||
// configure and create the relevant database driver
|
// configure and create the relevant database driver
|
||||||
$this->setUpDriver();
|
$this->setUpDriver();
|
||||||
// create the database interface with the suitable driver
|
// create the database interface with the suitable driver
|
||||||
|
|
111
tests/lib/DatabaseInformation.php
Normal file
111
tests/lib/DatabaseInformation.php
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<?php
|
||||||
|
/** @license MIT
|
||||||
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
||||||
|
* See LICENSE and AUTHORS files for details */
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\Arsse\Test;
|
||||||
|
|
||||||
|
use JKingWeb\Arsse\Arsse;
|
||||||
|
|
||||||
|
class DatabaseInformation {
|
||||||
|
public $name;
|
||||||
|
public $backend;
|
||||||
|
public $pdo;
|
||||||
|
public $resultClass;
|
||||||
|
public $statementClass;
|
||||||
|
public $driverClass;
|
||||||
|
public $stringOutput;
|
||||||
|
public $interfaceConstructor;
|
||||||
|
|
||||||
|
protected static $data;
|
||||||
|
|
||||||
|
public function __construct(string $name) {
|
||||||
|
if (!isset(self::$data)) {
|
||||||
|
self::$data = self::getData();
|
||||||
|
}
|
||||||
|
if (!isset(self::$data[$name])) {
|
||||||
|
throw new \Exception("Invalid database driver name");
|
||||||
|
}
|
||||||
|
$this->name = $name;
|
||||||
|
foreach (self::$data[$name] as $key => $value) {
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function list(): array {
|
||||||
|
if (!isset(self::$data)) {
|
||||||
|
self::$data = self::getData();
|
||||||
|
}
|
||||||
|
return array_keys(self::$data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function listPDO(): array {
|
||||||
|
if (!isset(self::$data)) {
|
||||||
|
self::$data = self::getData();
|
||||||
|
}
|
||||||
|
return array_values(array_filter(array_keys(self::$data), function($k) {
|
||||||
|
return self::$data[$k]['pdo'];
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function getData() {
|
||||||
|
return [
|
||||||
|
'SQLite 3' => [
|
||||||
|
'pdo' => false,
|
||||||
|
'backend' => "SQLite 3",
|
||||||
|
'statementClass' => \JKingWeb\Arsse\Db\SQLite3\Statement::class,
|
||||||
|
'resultClass' => \JKingWeb\Arsse\Db\SQLite3\Result::class,
|
||||||
|
'driverClass' => \JKingWeb\Arsse\Db\SQLite3\Driver::class,
|
||||||
|
'stringOutput' => false,
|
||||||
|
'interfaceConstructor' => function() {
|
||||||
|
try {
|
||||||
|
$d = new \SQLite3(Arsse::$conf->dbSQLite3File);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$d->enableExceptions(true);
|
||||||
|
return $d;
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
'PDO SQLite 3' => [
|
||||||
|
'pdo' => true,
|
||||||
|
'backend' => "SQLite 3",
|
||||||
|
'statementClass' => \JKingWeb\Arsse\Db\PDOStatement::class,
|
||||||
|
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class,
|
||||||
|
'driverClass' => \JKingWeb\Arsse\Db\SQLite3\PDODriver::class,
|
||||||
|
'stringOutput' => true,
|
||||||
|
'interfaceConstructor' => function() {
|
||||||
|
try {
|
||||||
|
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
||||||
|
$d->exec("PRAGMA busy_timeout=0");
|
||||||
|
return $d;
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'PDO PostgreSQL' => [
|
||||||
|
'pdo' => true,
|
||||||
|
'backend' => "PostgreSQL",
|
||||||
|
'statementClass' => \JKingWeb\Arsse\Db\PDOStatement::class,
|
||||||
|
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class,
|
||||||
|
'driverClass' => \JKingWeb\Arsse\Db\PostgreSQL\PDODriver::class,
|
||||||
|
'stringOutput' => true,
|
||||||
|
'interfaceConstructor' => function() {
|
||||||
|
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(true, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, "");
|
||||||
|
try {
|
||||||
|
$d = new \PDO("pgsql:".$connString, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach (\JKingWeb\Arsse\Db\PostgreSQL\PDODriver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) {
|
||||||
|
$d->exec($q);
|
||||||
|
}
|
||||||
|
return $d;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,19 +45,23 @@
|
||||||
<file>cases/Db/TestTransaction.php</file>
|
<file>cases/Db/TestTransaction.php</file>
|
||||||
<file>cases/Db/TestResultAggregate.php</file>
|
<file>cases/Db/TestResultAggregate.php</file>
|
||||||
<file>cases/Db/TestResultEmpty.php</file>
|
<file>cases/Db/TestResultEmpty.php</file>
|
||||||
<file>cases/Db/TestResult.php</file>
|
<file>cases/Db/TestResultPDO.php</file>
|
||||||
<file>cases/Db/TestStatement.php</file>
|
|
||||||
|
|
||||||
|
<file>cases/Db/SQLite3/TestResult.php</file>
|
||||||
|
<file>cases/Db/SQLite3/TestStatement.php</file>
|
||||||
<file>cases/Db/SQLite3/TestCreation.php</file>
|
<file>cases/Db/SQLite3/TestCreation.php</file>
|
||||||
<file>cases/Db/SQLite3/TestDriver.php</file>
|
<file>cases/Db/SQLite3/TestDriver.php</file>
|
||||||
<file>cases/Db/SQLite3/TestUpdate.php</file>
|
<file>cases/Db/SQLite3/TestUpdate.php</file>
|
||||||
|
|
||||||
|
<file>cases/Db/SQLite3PDO/TestStatement.php</file>
|
||||||
<file>cases/Db/SQLite3PDO/TestCreation.php</file>
|
<file>cases/Db/SQLite3PDO/TestCreation.php</file>
|
||||||
<file>cases/Db/SQLite3PDO/TestDriver.php</file>
|
<file>cases/Db/SQLite3PDO/TestDriver.php</file>
|
||||||
<file>cases/Db/SQLite3PDO/TestUpdate.php</file>
|
<file>cases/Db/SQLite3PDO/TestUpdate.php</file>
|
||||||
|
|
||||||
|
<file>cases/Db/PostgreSQL/TestStatement.php</file>
|
||||||
<file>cases/Db/PostgreSQL/TestCreation.php</file>
|
<file>cases/Db/PostgreSQL/TestCreation.php</file>
|
||||||
<file>cases/Db/PostgreSQL/TestDriver.php</file>
|
<!--<file>cases/Db/PostgreSQL/TestDriver.php</file>-->
|
||||||
|
<!--<file>cases/Db/PostgreSQL/TestUpdate.php</file>-->
|
||||||
</testsuite>
|
</testsuite>
|
||||||
<testsuite name="Database functions">
|
<testsuite name="Database functions">
|
||||||
<file>cases/Db/SQLite3/Database/TestMiscellany.php</file>
|
<file>cases/Db/SQLite3/Database/TestMiscellany.php</file>
|
||||||
|
|
Loading…
Reference in a new issue