mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Support PHP 8.1
This commit is contained in:
parent
b660508009
commit
b5579d6e43
18 changed files with 236 additions and 211 deletions
|
@ -13,7 +13,7 @@ require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php";
|
|||
ignore_user_abort(true);
|
||||
ini_set("memory_limit", "-1");
|
||||
ini_set("max_execution_time", "0");
|
||||
// FIXME: This is required by a dependency of Picofeed
|
||||
// FIXME: This is required because various dependencies have yet to adjust to PHP 8.1
|
||||
error_reporting(\E_ALL & ~\E_DEPRECATED);
|
||||
|
||||
if (\PHP_SAPI === "cli") {
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
"config": {
|
||||
"platform": {
|
||||
"php": "7.1.33"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"bamarni/composer-bin-plugin": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -163,6 +163,8 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
}
|
||||
|
||||
protected function makeConnection(string $db, string $user, string $password, string $host, int $port, string $socket): void {
|
||||
$drv = new \mysqli_driver;
|
||||
$drv->report_mode = \MYSQLI_REPORT_OFF;
|
||||
$this->db = mysqli_init();
|
||||
$this->db->options(\MYSQLI_SET_CHARSET_NAME, "utf8mb4");
|
||||
$this->db->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, false);
|
||||
|
|
|
@ -28,7 +28,8 @@ class PDODriver extends Driver {
|
|||
]);
|
||||
try {
|
||||
$this->db = new \PDO($dsn, $user, $password, [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
]);
|
||||
} catch (\PDOException $e) {
|
||||
$msg = $e->getMessage();
|
||||
|
|
|
@ -211,7 +211,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
|
||||
public function query(string $query): \JKingWeb\Arsse\Db\Result {
|
||||
$r = $this->dispatchQuery($query);
|
||||
if (is_resource($r)) {
|
||||
if (is_resource($r) || $r instanceof \PgSql\Result) { //class since PHP 8.1
|
||||
return new Result($this->db, $r);
|
||||
} else {
|
||||
[$excClass, $excMsg, $excData] = $r;
|
||||
|
|
|
@ -35,7 +35,7 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
|||
$this->bindValues($values);
|
||||
$r = $this->dispatchQuery($this->qMunged, $this->in);
|
||||
$this->in = [];
|
||||
if (is_resource($r)) {
|
||||
if (is_resource($r) || $r instanceof \PgSql\Result) { //class since PHP 8.1
|
||||
return new Result($this->db, $r);
|
||||
} else {
|
||||
[$excClass, $excMsg, $excData] = $r;
|
||||
|
|
|
@ -7,10 +7,15 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db;
|
||||
|
||||
interface Result extends \Iterator {
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current();
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key();
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next();
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind();
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid();
|
||||
|
||||
public function getRow();
|
||||
|
|
|
@ -18,7 +18,8 @@ class PDODriver extends AbstractPDODriver {
|
|||
|
||||
protected function makeConnection(string $file, string $key): void {
|
||||
$this->db = new \PDO("sqlite:".$file, "", "", [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,7 @@ const DOCROOT = BASE."tests".DIRECTORY_SEPARATOR."docroot".DIRECTORY_SEPARATOR;
|
|||
ini_set("memory_limit", "-1");
|
||||
ini_set("zend.assertions", "1");
|
||||
ini_set("assert.exception", "true");
|
||||
// FIXME: Workaround for a bug in PCRE2 10.37
|
||||
ini_set("pcre.jit", "0");
|
||||
// FIXME: This is required by a dependency of Picofeed
|
||||
// FIXME: This is required because various dependencies have yet to adjust to PHP 8.1
|
||||
error_reporting(\E_ALL & ~\E_DEPRECATED);
|
||||
require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php";
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Test\DatabaseDrivers;
|
||||
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait MySQL {
|
||||
use MySQLCommon;
|
||||
|
||||
protected static $implementation = "MySQL";
|
||||
protected static $backend = "MySQL";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\MySQL\Result::class;
|
||||
|
@ -21,6 +22,8 @@ trait MySQL {
|
|||
if (!class_exists("mysqli")) {
|
||||
return null;
|
||||
}
|
||||
$drv = new \mysqli_driver;
|
||||
$drv->report_mode = \MYSQLI_REPORT_OFF;
|
||||
$d = mysqli_init();
|
||||
$d->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, false);
|
||||
$d->options(\MYSQLI_SET_CHARSET_NAME, "utf8mb4");
|
||||
|
@ -34,53 +37,4 @@ trait MySQL {
|
|||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
$listTables = "SELECT table_name as name from information_schema.tables where table_schema = database() and table_name like 'arsse_%'";
|
||||
if ($db instanceof Driver) {
|
||||
$tables = $db->query($listTables)->getAll();
|
||||
} elseif ($db instanceof \PDO) {
|
||||
$tables = $db->query($listTables)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$tables = $db->query($listTables)->fetch_all(\MYSQLI_ASSOC);
|
||||
}
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
if ($table === "arsse_meta") {
|
||||
$db->query("DELETE FROM $table where `key` <> 'schema_version'");
|
||||
} else {
|
||||
$db->query("TRUNCATE TABLE $table");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->query($st);
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
$db->query("DROP TABLE IF EXISTS $table");
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->query($st);
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
}
|
||||
}
|
||||
|
|
60
tests/lib/DatabaseDrivers/MySQLCommon.php
Normal file
60
tests/lib/DatabaseDrivers/MySQLCommon.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?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\DatabaseDrivers;
|
||||
|
||||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait MySQLCommon {
|
||||
public static function dbTableList($db): array {
|
||||
$listTables = "SELECT table_name as name from information_schema.tables where table_schema = database() and table_name like 'arsse_%'";
|
||||
if ($db instanceof Driver) {
|
||||
$tables = $db->query($listTables)->getAll();
|
||||
} elseif ($db instanceof \PDO) {
|
||||
$tables = $db->query($listTables)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$tables = $db->query($listTables)->fetch_all(\MYSQLI_ASSOC);
|
||||
}
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
if ($table === "arsse_meta") {
|
||||
$db->query("DELETE FROM $table where `key` <> 'schema_version'");
|
||||
} else {
|
||||
$db->query("TRUNCATE TABLE $table");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->query($st);
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->query("UNLOCK TABLES; ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
$db->query("DROP TABLE IF EXISTS $table");
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->query($st);
|
||||
}
|
||||
$db->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ namespace JKingWeb\Arsse\Test\DatabaseDrivers;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait MySQLPDO {
|
||||
use MySQLCommon;
|
||||
|
||||
protected static $implementation = "PDO MySQL";
|
||||
protected static $backend = "MySQL";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class;
|
||||
|
@ -31,6 +33,7 @@ trait MySQLPDO {
|
|||
$dsn = "mysql:".implode(";", $dsn);
|
||||
$d = new \PDO($dsn, Arsse::$conf->dbMySQLUser, Arsse::$conf->dbMySQLPass, [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
\PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
|
||||
]);
|
||||
foreach (\JKingWeb\Arsse\Db\MySQL\PDODriver::makeSetupQueries() as $q) {
|
||||
|
@ -41,16 +44,4 @@ trait MySQLPDO {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
return MySQL::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
MySQL::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
MySQL::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ use JKingWeb\Arsse\Arsse;
|
|||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait PostgreSQL {
|
||||
use PostgreSQLCommon;
|
||||
|
||||
protected static $implementation = "PostgreSQL";
|
||||
protected static $backend = "PostgreSQL";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\PostgreSQL\Result::class;
|
||||
|
@ -28,61 +30,4 @@ trait PostgreSQL {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbExec($db, $q): void {
|
||||
if ($db instanceof Driver) {
|
||||
$db->exec($q);
|
||||
} elseif ($db instanceof \PDO) {
|
||||
$db->exec($q);
|
||||
} else {
|
||||
pg_query($db, $q);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
$listObjects = "SELECT table_name as name, 'TABLE' as type from information_schema.tables where table_schema = current_schema() and table_name like 'arsse_%' union SELECT collation_name as name, 'COLLATION' as type from information_schema.collations where collation_schema = current_schema()";
|
||||
if ($db instanceof Driver) {
|
||||
return $db->query($listObjects)->getAll();
|
||||
} elseif ($db instanceof \PDO) {
|
||||
return $db->query($listObjects)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$r = @pg_query($db, $listObjects);
|
||||
$out = $r ? pg_fetch_all($r) : false;
|
||||
return $out ? $out : [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $obj) {
|
||||
if ($obj['type'] !== "TABLE") {
|
||||
continue;
|
||||
} elseif ($obj['name'] === "arsse_meta") {
|
||||
self::dbExec($db, "DELETE FROM {$obj['name']} where key <> 'schema_version'");
|
||||
} else {
|
||||
self::dbExec($db, "TRUNCATE TABLE {$obj['name']} restart identity cascade");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
self::dbExec($db, $st);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $obj) {
|
||||
self::dbExec($db, "DROP {$obj['type']} IF EXISTS {$obj['name']} cascade");
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
self::dbExec($db, $st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
69
tests/lib/DatabaseDrivers/PostgreSQLCommon.php
Normal file
69
tests/lib/DatabaseDrivers/PostgreSQLCommon.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?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\DatabaseDrivers;
|
||||
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait PostgreSQLCommon {
|
||||
public static function dbExec($db, $q): void {
|
||||
if ($db instanceof Driver) {
|
||||
$db->exec($q);
|
||||
} elseif ($db instanceof \PDO) {
|
||||
$db->exec($q);
|
||||
} else {
|
||||
pg_query($db, $q);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
$listObjects = "SELECT table_name as name, 'TABLE' as type from information_schema.tables where table_schema = current_schema() and table_name like 'arsse_%' union SELECT collation_name as name, 'COLLATION' as type from information_schema.collations where collation_schema = current_schema()";
|
||||
if ($db instanceof Driver) {
|
||||
return $db->query($listObjects)->getAll();
|
||||
} elseif ($db instanceof \PDO) {
|
||||
return $db->query($listObjects)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} else {
|
||||
$r = @pg_query($db, $listObjects);
|
||||
$out = $r ? pg_fetch_all($r) : false;
|
||||
return $out ? $out : [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $obj) {
|
||||
if ($obj['type'] !== "TABLE") {
|
||||
continue;
|
||||
} elseif ($obj['name'] === "arsse_meta") {
|
||||
self::dbExec($db, "DELETE FROM {$obj['name']} where key <> 'schema_version'");
|
||||
} else {
|
||||
self::dbExec($db, "TRUNCATE TABLE {$obj['name']} restart identity cascade");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
self::dbExec($db, $st);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
@self::dbExec($db, "ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $obj) {
|
||||
self::dbExec($db, "DROP {$obj['type']} IF EXISTS {$obj['name']} cascade");
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
self::dbExec($db, $st);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ namespace JKingWeb\Arsse\Test\DatabaseDrivers;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait PostgreSQLPDO {
|
||||
use PostgreSQLCommon;
|
||||
|
||||
protected static $implementation = "PDO PostgreSQL";
|
||||
protected static $backend = "PostgreSQL";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\PostgreSQL\PDOResult::class;
|
||||
|
@ -28,16 +30,4 @@ trait PostgreSQLPDO {
|
|||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
return PostgreSQL::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
PostgreSQL::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
PostgreSQL::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ use JKingWeb\Arsse\Arsse;
|
|||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait SQLite3 {
|
||||
use SQLite3Common;
|
||||
|
||||
protected static $implementation = "SQLite 3";
|
||||
protected static $backend = "SQLite 3";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\SQLite3\Result::class;
|
||||
|
@ -26,63 +28,4 @@ trait SQLite3 {
|
|||
$d->enableExceptions(true);
|
||||
return $d;
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
$listTables = "SELECT name from sqlite_master where type = 'table' and name like 'arsse^_%' escape '^'";
|
||||
if ($db instanceof Driver) {
|
||||
$tables = $db->query($listTables)->getAll();
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
} elseif ($db instanceof \PDO) {
|
||||
retry:
|
||||
try {
|
||||
$tables = $db->query($listTables)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} catch (\PDOException $e) {
|
||||
goto retry;
|
||||
}
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
} else {
|
||||
$tables = [];
|
||||
$result = $db->query($listTables);
|
||||
while ($r = $result->fetchArray(\SQLITE3_ASSOC)) {
|
||||
$tables[] = $r['name'];
|
||||
}
|
||||
$result->finalize();
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
if ($table === "arsse_meta") {
|
||||
$db->exec("DELETE FROM $table where key <> 'schema_version'");
|
||||
} else {
|
||||
$db->exec("DELETE FROM $table");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->exec($st);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->exec("PRAGMA foreign_keys=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
$db->exec("DROP TABLE IF EXISTS $table");
|
||||
}
|
||||
$db->exec("PRAGMA user_version=0");
|
||||
$db->exec("PRAGMA foreign_keys=1");
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->exec($st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
70
tests/lib/DatabaseDrivers/SQLite3Common.php
Normal file
70
tests/lib/DatabaseDrivers/SQLite3Common.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?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\DatabaseDrivers;
|
||||
|
||||
use JKingWeb\Arsse\Db\Driver;
|
||||
|
||||
trait SQLite3Common {
|
||||
public static function dbTableList($db): array {
|
||||
$listTables = "SELECT name from sqlite_master where type = 'table' and name like 'arsse^_%' escape '^'";
|
||||
if ($db instanceof Driver) {
|
||||
$tables = $db->query($listTables)->getAll();
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
} elseif ($db instanceof \PDO) {
|
||||
retry:
|
||||
try {
|
||||
$tables = $db->query($listTables)->fetchAll(\PDO::FETCH_ASSOC);
|
||||
} catch (\PDOException $e) {
|
||||
goto retry;
|
||||
}
|
||||
$tables = sizeof($tables) ? array_column($tables, "name") : [];
|
||||
} else {
|
||||
$tables = [];
|
||||
$result = $db->query($listTables);
|
||||
while ($r = $result->fetchArray(\SQLITE3_ASSOC)) {
|
||||
$tables[] = $r['name'];
|
||||
}
|
||||
$result->finalize();
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
if ($table === "arsse_meta") {
|
||||
$db->exec("DELETE FROM $table where key <> 'schema_version'");
|
||||
} else {
|
||||
$db->exec("DELETE FROM $table");
|
||||
}
|
||||
}
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->exec($st);
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
// rollback any pending transaction
|
||||
try {
|
||||
$db->exec("ROLLBACK");
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
$db->exec("PRAGMA foreign_keys=0");
|
||||
foreach (self::dbTableList($db) as $table) {
|
||||
$db->exec("DROP TABLE IF EXISTS $table");
|
||||
}
|
||||
$db->exec("PRAGMA user_version=0");
|
||||
$db->exec("PRAGMA foreign_keys=1");
|
||||
foreach ($afterStatements as $st) {
|
||||
$db->exec($st);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ namespace JKingWeb\Arsse\Test\DatabaseDrivers;
|
|||
use JKingWeb\Arsse\Arsse;
|
||||
|
||||
trait SQLite3PDO {
|
||||
use SQLite3Common;
|
||||
|
||||
protected static $implementation = "PDO SQLite 3";
|
||||
protected static $backend = "SQLite 3";
|
||||
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class;
|
||||
|
@ -18,23 +20,14 @@ trait SQLite3PDO {
|
|||
|
||||
public static function dbInterface() {
|
||||
try {
|
||||
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
|
||||
$d = new \PDO("sqlite:".Arsse::$conf->dbSQLite3File, "", "", [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
]);
|
||||
$d->exec("PRAGMA busy_timeout=0");
|
||||
return $d;
|
||||
} catch (\Throwable $e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static function dbTableList($db): array {
|
||||
return SQLite3::dbTableList($db);
|
||||
}
|
||||
|
||||
public static function dbTruncate($db, array $afterStatements = []): void {
|
||||
SQLite3::dbTruncate($db, $afterStatements);
|
||||
}
|
||||
|
||||
public static function dbRaze($db, array $afterStatements = []): void {
|
||||
SQLite3::dbRaze($db, $afterStatements);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue