J. King
5 years ago
38 changed files with 452 additions and 398 deletions
@ -0,0 +1,68 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait MySQL { |
||||
|
protected static $implementation = "MySQL"; |
||||
|
protected static $backend = "MySQL"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\MySQL\Result::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\MySQL\Statement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\MySQL\Driver::class; |
||||
|
protected static $stringOutput = false; |
||||
|
|
||||
|
public static function dbInterface() { |
||||
|
} |
||||
|
|
||||
|
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 = []) { |
||||
|
// rollback any pending transaction |
||||
|
try { |
||||
|
$db->query("UNLOCK TABLES; ROLLBACK"); |
||||
|
} catch (\Throwable $e) { |
||||
|
} |
||||
|
foreach (self::dbTableList($db) as $table) { |
||||
|
if ($table === "arsse_meta") { |
||||
|
$db->query("DELETE FROM $table where `key` <> 'schema_version'"); |
||||
|
} else { |
||||
|
$db->query("DELETE FROM $table"); |
||||
|
} |
||||
|
$db->query("ALTER TABLE $table auto_increment = 1"); |
||||
|
} |
||||
|
foreach ($afterStatements as $st) { |
||||
|
$db->query($st); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static function dbRaze($db, array $afterStatements = []) { |
||||
|
// rollback any pending transaction |
||||
|
try { |
||||
|
$db->query("UNLOCK TABLES; ROLLBACK"); |
||||
|
} catch (\Throwable $e) { |
||||
|
} |
||||
|
foreach (self::dbTableList($db) as $table) { |
||||
|
$db->query("DROP TABLE IF EXISTS $table"); |
||||
|
} |
||||
|
foreach ($afterStatements as $st) { |
||||
|
$db->query($st); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait MySQLPDO { |
||||
|
protected static $implementation = "PDO MySQL"; |
||||
|
protected static $backend = "MySQL"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\MySQL\PDOStatement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\MySQL\PDODriver::class; |
||||
|
protected static $stringOutput = true; |
||||
|
|
||||
|
public static function dbInterface() { |
||||
|
try { |
||||
|
$dsn = []; |
||||
|
$params = [ |
||||
|
'charset' => "utf8mb4", |
||||
|
'host' => Arsse::$conf->dbMySQLHost, |
||||
|
'port' => Arsse::$conf->dbMySQLPort, |
||||
|
'dbname' => Arsse::$conf->dbMySQLDb, |
||||
|
]; |
||||
|
foreach ($params as $k => $v) { |
||||
|
$dsn[] = "$k=$v"; |
||||
|
} |
||||
|
$dsn = "mysql:".implode(";", $dsn); |
||||
|
return new \PDO($dsn, Arsse::$conf->dbMySQLUser, Arsse::$conf->dbMySQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::MYSQL_ATTR_MULTI_STATEMENTS => false, \PDO::MYSQL_ATTR_INIT_COMMAND => "SET sql_mode = '".\JKingWeb\Arsse\Db\MySQL\PDODriver::SQL_MODE."'",]); |
||||
|
} catch (\Throwable $e) { |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static function dbTableList($db): array { |
||||
|
return MySQL::dbTableList($db); |
||||
|
} |
||||
|
|
||||
|
public static function dbTruncate($db, array $afterStatements = []) { |
||||
|
MySQL::dbTruncate($db, $afterStatements); |
||||
|
} |
||||
|
|
||||
|
public static function dbRaze($db, array $afterStatements = []) { |
||||
|
MySQL::dbRaze($db, $afterStatements); |
||||
|
} |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait PostgreSQL { |
||||
|
protected static $implementation = "PostgreSQL"; |
||||
|
protected static $backend = "PostgreSQL"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\PostgreSQL\Result::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\PostgreSQL\Statement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\PostgreSQL\Driver::class; |
||||
|
protected static $stringOutput = true; |
||||
|
|
||||
|
public static function dbInterface() { |
||||
|
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(false, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, ""); |
||||
|
if ($d = @pg_connect($connString, \PGSQL_CONNECT_FORCE_NEW)) { |
||||
|
foreach (\JKingWeb\Arsse\Db\PostgreSQL\Driver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) { |
||||
|
pg_query($d, $q); |
||||
|
} |
||||
|
return $d; |
||||
|
} else { |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static function dbExec($db, $q) { |
||||
|
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 = []) { |
||||
|
// 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 = []) { |
||||
|
// 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); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait PostgreSQLPDO { |
||||
|
protected static $implementation = "PDO PostgreSQL"; |
||||
|
protected static $backend = "PostgreSQL"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\PostgreSQL\PDOStatement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\PostgreSQL\PDODriver::class; |
||||
|
protected static $stringOutput = false; |
||||
|
|
||||
|
public static function dbInterface() { |
||||
|
$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; |
||||
|
} |
||||
|
|
||||
|
public static function dbTableList($db): array { |
||||
|
return PostgreSQL::dbTableList($db); |
||||
|
} |
||||
|
|
||||
|
public static function dbTruncate($db, array $afterStatements = []) { |
||||
|
PostgreSQL::dbTruncate($db, $afterStatements); |
||||
|
} |
||||
|
|
||||
|
public static function dbRaze($db, array $afterStatements = []) { |
||||
|
PostgreSQL::dbRaze($db, $afterStatements); |
||||
|
} |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait SQLite3 { |
||||
|
protected static $implementation = "SQLite 3"; |
||||
|
protected static $backend = "SQLite 3"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\SQLite3\Result::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\SQLite3\Statement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\SQLite3\Driver::class; |
||||
|
protected static $stringOutput = false; |
||||
|
|
||||
|
protected static function dbInterface() { |
||||
|
try { |
||||
|
$d = new \SQLite3(Arsse::$conf->dbSQLite3File); |
||||
|
} catch (\Throwable $e) { |
||||
|
return; |
||||
|
} |
||||
|
$d->enableExceptions(true); |
||||
|
return $d; |
||||
|
} |
||||
|
|
||||
|
public static function dbTableList($db): array { |
||||
|
$listTables = "SELECT name from sqlite_master where type = 'table' and name like 'arsse_%'"; |
||||
|
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 = []) { |
||||
|
// 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 = []) { |
||||
|
// 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); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,41 @@ |
|||||
|
<?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\DatabaseDrivers; |
||||
|
|
||||
|
use JKingWeb\Arsse\Arsse; |
||||
|
use JKingWeb\Arsse\Db\Driver; |
||||
|
|
||||
|
trait SQLite3PDO { |
||||
|
protected static $implementation = "PDO SQLite 3"; |
||||
|
protected static $backend = "SQLite 3"; |
||||
|
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class; |
||||
|
protected static $dbStatementClass = \JKingWeb\Arsse\Db\SQLite3\PDOStatement::class; |
||||
|
protected static $dbDriverClass = \JKingWeb\Arsse\Db\SQLite3\PDODriver::class; |
||||
|
protected static $stringOutput = true; |
||||
|
|
||||
|
public static function dbInterface() { |
||||
|
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; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static function dbTableList($db): array { |
||||
|
return SQLite3::dbTableList($db); |
||||
|
} |
||||
|
|
||||
|
public static function dbTruncate($db, array $afterStatements = []) { |
||||
|
SQLite3::dbTruncate($db, $afterStatements); |
||||
|
} |
||||
|
|
||||
|
public static function dbRaze($db, array $afterStatements = []) { |
||||
|
SQLite3::dbRaze($db, $afterStatements); |
||||
|
} |
||||
|
} |
@ -1,320 +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\Test; |
|
||||
|
|
||||
use JKingWeb\Arsse\Arsse; |
|
||||
use JKingWeb\Arsse\Db\Driver; |
|
||||
|
|
||||
class DatabaseInformation { |
|
||||
public $name; |
|
||||
public $backend; |
|
||||
public $pdo; |
|
||||
public $resultClass; |
|
||||
public $statementClass; |
|
||||
public $driverClass; |
|
||||
public $stringOutput; |
|
||||
public $interfaceConstructor; |
|
||||
public $truncateFunction; |
|
||||
public $razeFunction; |
|
||||
|
|
||||
protected static $data; |
|
||||
|
|
||||
public function __construct(string $name) { |
|
||||
if (!isset(self::$data)) { |
|
||||
self::$data = self::getData(); |
|
||||
} |
|
||||
if (!array_key_exists($name, self::$data)) { |
|
||||
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() { |
|
||||
$sqlite3TableList = function($db): array { |
|
||||
$listTables = "SELECT name from sqlite_master where type = 'table' and name like 'arsse_%'"; |
|
||||
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; |
|
||||
}; |
|
||||
$sqlite3TruncateFunction = function($db, array $afterStatements = []) use ($sqlite3TableList) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
$db->exec("ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
foreach ($sqlite3TableList($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); |
|
||||
} |
|
||||
}; |
|
||||
$sqlite3RazeFunction = function($db, array $afterStatements = []) use ($sqlite3TableList) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
$db->exec("ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
$db->exec("PRAGMA foreign_keys=0"); |
|
||||
foreach ($sqlite3TableList($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); |
|
||||
} |
|
||||
}; |
|
||||
$pgObjectList = function($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 : []; |
|
||||
} |
|
||||
}; |
|
||||
$pgExecFunction = function($db, $q) { |
|
||||
if ($db instanceof Driver) { |
|
||||
$db->exec($q); |
|
||||
} elseif ($db instanceof \PDO) { |
|
||||
$db->exec($q); |
|
||||
} else { |
|
||||
pg_query($db, $q); |
|
||||
} |
|
||||
}; |
|
||||
$pgTruncateFunction = function($db, array $afterStatements = []) use ($pgObjectList, $pgExecFunction) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
@$pgExecFunction($db, "ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
foreach ($pgObjectList($db) as $obj) { |
|
||||
if ($obj['type'] !== "TABLE") { |
|
||||
continue; |
|
||||
} elseif ($obj['name'] === "arsse_meta") { |
|
||||
$pgExecFunction($db, "DELETE FROM {$obj['name']} where key <> 'schema_version'"); |
|
||||
} else { |
|
||||
$pgExecFunction($db, "TRUNCATE TABLE {$obj['name']} restart identity cascade"); |
|
||||
} |
|
||||
} |
|
||||
foreach ($afterStatements as $st) { |
|
||||
$pgExecFunction($db, $st); |
|
||||
} |
|
||||
}; |
|
||||
$pgRazeFunction = function($db, array $afterStatements = []) use ($pgObjectList, $pgExecFunction) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
$pgExecFunction($db, "ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
foreach ($pgObjectList($db) as $obj) { |
|
||||
$pgExecFunction($db, "DROP {$obj['type']} IF EXISTS {$obj['name']} cascade"); |
|
||||
} |
|
||||
foreach ($afterStatements as $st) { |
|
||||
$pgExecFunction($db, $st); |
|
||||
} |
|
||||
}; |
|
||||
$mysqlTableList = function($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; |
|
||||
}; |
|
||||
$mysqlTruncateFunction = function($db, array $afterStatements = []) use ($mysqlTableList) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
$db->query("UNLOCK TABLES; ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
foreach ($mysqlTableList($db) as $table) { |
|
||||
if ($table === "arsse_meta") { |
|
||||
$db->query("DELETE FROM $table where `key` <> 'schema_version'"); |
|
||||
} else { |
|
||||
$db->query("DELETE FROM $table"); |
|
||||
} |
|
||||
$db->query("ALTER TABLE $table auto_increment = 1"); |
|
||||
} |
|
||||
foreach ($afterStatements as $st) { |
|
||||
$db->query($st); |
|
||||
} |
|
||||
}; |
|
||||
$mysqlRazeFunction = function($db, array $afterStatements = []) use ($mysqlTableList) { |
|
||||
// rollback any pending transaction |
|
||||
try { |
|
||||
$db->query("UNLOCK TABLES; ROLLBACK"); |
|
||||
} catch (\Throwable $e) { |
|
||||
} |
|
||||
foreach ($mysqlTableList($db) as $table) { |
|
||||
$db->query("DROP TABLE IF EXISTS $table"); |
|
||||
} |
|
||||
foreach ($afterStatements as $st) { |
|
||||
$db->query($st); |
|
||||
} |
|
||||
}; |
|
||||
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; |
|
||||
}, |
|
||||
'truncateFunction' => $sqlite3TruncateFunction, |
|
||||
'razeFunction' => $sqlite3RazeFunction, |
|
||||
], |
|
||||
'PDO SQLite 3' => [ |
|
||||
'pdo' => true, |
|
||||
'backend' => "SQLite 3", |
|
||||
'statementClass' => \JKingWeb\Arsse\Db\SQLite3\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; |
|
||||
} |
|
||||
}, |
|
||||
'truncateFunction' => $sqlite3TruncateFunction, |
|
||||
'razeFunction' => $sqlite3RazeFunction, |
|
||||
], |
|
||||
'PostgreSQL' => [ |
|
||||
'pdo' => false, |
|
||||
'backend' => "PostgreSQL", |
|
||||
'statementClass' => \JKingWeb\Arsse\Db\PostgreSQL\Statement::class, |
|
||||
'resultClass' => \JKingWeb\Arsse\Db\PostgreSQL\Result::class, |
|
||||
'driverClass' => \JKingWeb\Arsse\Db\PostgreSQL\Driver::class, |
|
||||
'stringOutput' => true, |
|
||||
'interfaceConstructor' => function() { |
|
||||
$connString = \JKingWeb\Arsse\Db\PostgreSQL\Driver::makeConnectionString(false, Arsse::$conf->dbPostgreSQLUser, Arsse::$conf->dbPostgreSQLPass, Arsse::$conf->dbPostgreSQLDb, Arsse::$conf->dbPostgreSQLHost, Arsse::$conf->dbPostgreSQLPort, ""); |
|
||||
if ($d = @pg_connect($connString, \PGSQL_CONNECT_FORCE_NEW)) { |
|
||||
foreach (\JKingWeb\Arsse\Db\PostgreSQL\Driver::makeSetupQueries(Arsse::$conf->dbPostgreSQLSchema) as $q) { |
|
||||
pg_query($d, $q); |
|
||||
} |
|
||||
return $d; |
|
||||
} else { |
|
||||
return; |
|
||||
} |
|
||||
}, |
|
||||
'truncateFunction' => $pgTruncateFunction, |
|
||||
'razeFunction' => $pgRazeFunction, |
|
||||
], |
|
||||
'PDO PostgreSQL' => [ |
|
||||
'pdo' => true, |
|
||||
'backend' => "PostgreSQL", |
|
||||
'statementClass' => \JKingWeb\Arsse\Db\PostgreSQL\PDOStatement::class, |
|
||||
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class, |
|
||||
'driverClass' => \JKingWeb\Arsse\Db\PostgreSQL\PDODriver::class, |
|
||||
'stringOutput' => false, |
|
||||
'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; |
|
||||
}, |
|
||||
'truncateFunction' => $pgTruncateFunction, |
|
||||
'razeFunction' => $pgRazeFunction, |
|
||||
], |
|
||||
'PDO MySQL' => [ |
|
||||
'pdo' => true, |
|
||||
'backend' => "MySQL", |
|
||||
'statementClass' => \JKingWeb\Arsse\Db\MySQL\PDOStatement::class, |
|
||||
'resultClass' => \JKingWeb\Arsse\Db\PDOResult::class, |
|
||||
'driverClass' => \JKingWeb\Arsse\Db\MySQL\PDODriver::class, |
|
||||
'stringOutput' => true, |
|
||||
'interfaceConstructor' => function() { |
|
||||
try { |
|
||||
$dsn = []; |
|
||||
$params = [ |
|
||||
'charset' => "utf8mb4", |
|
||||
'host' => Arsse::$conf->dbMySQLHost, |
|
||||
'port' => Arsse::$conf->dbMySQLPort, |
|
||||
'dbname' => Arsse::$conf->dbMySQLDb, |
|
||||
]; |
|
||||
foreach ($params as $k => $v) { |
|
||||
$dsn[] = "$k=$v"; |
|
||||
} |
|
||||
$dsn = "mysql:".implode(";", $dsn); |
|
||||
return new \PDO($dsn, Arsse::$conf->dbMySQLUser, Arsse::$conf->dbMySQLPass, [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::MYSQL_ATTR_MULTI_STATEMENTS => false, \PDO::MYSQL_ATTR_INIT_COMMAND => "SET sql_mode = '".\JKingWeb\Arsse\Db\MySQL\PDODriver::SQL_MODE."'",]); |
|
||||
} catch (\Throwable $e) { |
|
||||
return; |
|
||||
} |
|
||||
}, |
|
||||
'truncateFunction' => $mysqlTruncateFunction, |
|
||||
'razeFunction' => $mysqlRazeFunction, |
|
||||
], |
|
||||
]; |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue