diff --git a/lib/Db/PDODriver.php b/lib/Db/PDODriver.php index e418cdc..413a0cc 100644 --- a/lib/Db/PDODriver.php +++ b/lib/Db/PDODriver.php @@ -26,13 +26,7 @@ trait PDODriver { list($excClass, $excMsg, $excData) = $this->exceptionBuild(); throw new $excClass($excMsg, $excData); } - $changes = $r->rowCount(); - try { - $lastId = 0; - $lastId = ($changes) ? $this->db->lastInsertId() : 0; - } catch (\PDOException $e) { // @codeCoverageIgnore - } - return new PDOResult($r, [$changes, $lastId]); + return new PDOResult($this->db, $r); } public function prepareArray(string $query, array $paramTypes): Statement { diff --git a/lib/Db/PDOResult.php b/lib/Db/PDOResult.php index 8889511..d817d01 100644 --- a/lib/Db/PDOResult.php +++ b/lib/Db/PDOResult.php @@ -10,26 +10,28 @@ use JKingWeb\Arsse\Db\Exception; class PDOResult extends AbstractResult { protected $set; + protected $db; protected $cur = null; - protected $rows = 0; - protected $id = 0; // actual public methods public function changes(): int { - return $this->rows; + return $this->set->rowCount(); } public function lastId(): int { - return $this->id; + try { + return (int) $this->db->lastInsertId(); + } catch (\PDOException $e) { + return 0; + } } // constructor/destructor - public function __construct(\PDOStatement $result, array $changes = [0,0]) { + public function __construct(\PDO $db, \PDOStatement $result) { $this->set = $result; - $this->rows = (int) $changes[0]; - $this->id = (int) $changes[1]; + $this->db = $db; } public function __destruct() { @@ -38,6 +40,7 @@ class PDOResult extends AbstractResult { } catch (\PDOException $e) { // @codeCoverageIgnore } unset($this->set); + unset($this->db); } // PHP iterator methods diff --git a/lib/Db/PDOStatement.php b/lib/Db/PDOStatement.php index 26a5045..3a09015 100644 --- a/lib/Db/PDOStatement.php +++ b/lib/Db/PDOStatement.php @@ -40,13 +40,7 @@ class PDOStatement extends AbstractStatement { list($excClass, $excMsg, $excData) = $this->exceptionBuild(); throw new $excClass($excMsg, $excData); } - $changes = $this->st->rowCount(); - try { - $lastId = 0; - $lastId = ($changes) ? $this->db->lastInsertId() : 0; - } catch (\PDOException $e) { // @codeCoverageIgnore - } - return new PDOResult($this->st, [$changes, $lastId]); + return new PDOResult($this->db, $this->st); } protected function bindValue($value, string $type, int $position): bool { diff --git a/lib/Db/PostgreSQL/PDODriver.php b/lib/Db/PostgreSQL/PDODriver.php index d9716da..37763dd 100644 --- a/lib/Db/PostgreSQL/PDODriver.php +++ b/lib/Db/PostgreSQL/PDODriver.php @@ -22,7 +22,10 @@ class PDODriver extends Driver { protected function makeConnection(string $user, string $pass, string $db, string $host, int $port, string $service) { $dsn = $this->makeconnectionString(true, $user, $pass, $db, $host, $port, $service); - $this->db = new \PDO("pgsql:$dsn", $user, $pass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]); + $this->db = new \PDO("pgsql:$dsn", $user, $pass, [ + \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, + //\PDO::ATTR_PERSISTENT => true, + ]); } public function __destruct() { diff --git a/lib/Db/SQLite3/PDODriver.php b/lib/Db/SQLite3/PDODriver.php index 42e1cf8..cbad93c 100644 --- a/lib/Db/SQLite3/PDODriver.php +++ b/lib/Db/SQLite3/PDODriver.php @@ -21,7 +21,9 @@ class PDODriver extends Driver { } protected function makeConnection(string $file, string $key) { - $this->db = new \PDO("sqlite:".$file, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]); + $this->db = new \PDO("sqlite:".$file, "", "", [ + \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, + ]); } public function __destruct() { diff --git a/tests/cases/Db/BaseDriver.php b/tests/cases/Db/BaseDriver.php index f51a121..fd8cb5a 100644 --- a/tests/cases/Db/BaseDriver.php +++ b/tests/cases/Db/BaseDriver.php @@ -57,7 +57,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest { } public static function tearDownAfterClass() { - static::$implementation = null; + static::$interface = null; static::$dbInfo = null; self::clearData(); } diff --git a/tests/cases/Db/BaseResult.php b/tests/cases/Db/BaseResult.php index de1ddf2..a2159e4 100644 --- a/tests/cases/Db/BaseResult.php +++ b/tests/cases/Db/BaseResult.php @@ -56,13 +56,20 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest { } 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()); + $this->makeResult(static::$createMeta); + $r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_meta(key,value) values('test', 1)")); + $this->assertSame(1, $r->changes()); + $this->assertSame(0, $r->lastId()); + } + + public function testGetChangeCountAndLastInsertIdBis() { + $this->makeResult(static::$createTest); + $r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_test default values")); + $this->assertSame(1, $r->changes()); + $this->assertSame(1, $r->lastId()); + $r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_test default values")); + $this->assertSame(1, $r->changes()); + $this->assertSame(2, $r->lastId()); } public function testIterateOverResults() { @@ -91,7 +98,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest { 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")); + $test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union all select 1970 as year union all select 2112 as year")); $this->assertSame($exp[0], $test->getValue()); $this->assertSame($exp[1], $test->getValue()); $this->assertSame($exp[2], $test->getValue()); @@ -101,7 +108,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest { 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")); + $test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union all select 1970 as year, 20 as century union all 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()); diff --git a/tests/cases/Db/PostgreSQL/TestResult.php b/tests/cases/Db/PostgreSQL/TestResult.php new file mode 100644 index 0000000..06c1001 --- /dev/null +++ b/tests/cases/Db/PostgreSQL/TestResult.php @@ -0,0 +1,23 @@ + + */ +class TestResult extends \JKingWeb\Arsse\TestCase\Db\BaseResult { + protected static $implementation = "PDO PostgreSQL"; + protected static $createMeta = "CREATE TABLE arsse_meta(key text primary key not null, value text)"; + protected static $createTest = "CREATE TABLE arsse_test(id bigserial primary key)"; + + protected function makeResult(string $q): array { + $set = static::$interface->query($q); + return [static::$interface, $set]; + } +} diff --git a/tests/cases/Db/SQLite3/TestResult.php b/tests/cases/Db/SQLite3/TestResult.php index b05287e..1b34a1d 100644 --- a/tests/cases/Db/SQLite3/TestResult.php +++ b/tests/cases/Db/SQLite3/TestResult.php @@ -13,6 +13,8 @@ use JKingWeb\Arsse\Test\DatabaseInformation; */ class TestResult extends \JKingWeb\Arsse\TestCase\Db\BaseResult { protected static $implementation = "SQLite 3"; + protected static $createMeta = "CREATE TABLE arsse_meta(key text primary key not null, value text) without rowid"; + protected static $createTest = "CREATE TABLE arsse_test(id integer primary key)"; public static function tearDownAfterClass() { if (static::$interface) { diff --git a/tests/cases/Db/SQLite3PDO/TestResult.php b/tests/cases/Db/SQLite3PDO/TestResult.php new file mode 100644 index 0000000..12b082e --- /dev/null +++ b/tests/cases/Db/SQLite3PDO/TestResult.php @@ -0,0 +1,23 @@ + + */ +class TestResult extends \JKingWeb\Arsse\TestCase\Db\BaseResult { + protected static $implementation = "PDO SQLite 3"; + protected static $createMeta = "CREATE TABLE arsse_meta(key text primary key not null, value text) without rowid"; + protected static $createTest = "CREATE TABLE arsse_test(id integer primary key)"; + + protected function makeResult(string $q): array { + $set = static::$interface->query($q); + return [static::$interface, $set]; + } +} diff --git a/tests/cases/Db/TestResultPDO.php b/tests/cases/Db/TestResultPDO.php deleted file mode 100644 index 7ad1edd..0000000 --- a/tests/cases/Db/TestResultPDO.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ -class TestResultPDO extends \JKingWeb\Arsse\TestCase\Db\BaseResult { - protected static $implementation; - - 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::$implementation = $drivers[0]; - foreach ($drivers as $driver) { - $info = new DatabaseInformation($driver); - $interface = ($info->interfaceConstructor)(); - if ($interface) { - self::$implementation = $driver; - break; - } - } - unset($interface); - unset($info); - parent::setUpBeforeClass(); - } - - protected function makeResult(string $q): array { - $set = static::$interface->query($q); - $rows = $set->rowCount(); - $id = static::$interface->lastInsertID(); - return [$set, [$rows, $id]]; - } -} diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 29fe5e4..da4be23 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -45,7 +45,6 @@ cases/Db/TestTransaction.php cases/Db/TestResultAggregate.php cases/Db/TestResultEmpty.php - cases/Db/TestResultPDO.php cases/Db/SQLite3/TestResult.php cases/Db/SQLite3/TestStatement.php @@ -53,11 +52,13 @@ cases/Db/SQLite3/TestDriver.php cases/Db/SQLite3/TestUpdate.php + cases/Db/SQLite3PDO/TestResult.php cases/Db/SQLite3PDO/TestStatement.php cases/Db/SQLite3PDO/TestCreation.php cases/Db/SQLite3PDO/TestDriver.php cases/Db/SQLite3PDO/TestUpdate.php + cases/Db/PostgreSQL/TestResult.php cases/Db/PostgreSQL/TestStatement.php cases/Db/PostgreSQL/TestCreation.php cases/Db/PostgreSQL/TestDriver.php