WIP DBA refactoring

This commit is contained in:
Philipp Holzer 2019-03-01 09:08:42 +01:00
parent 7af787728f
commit 0b6d3c71f9
No known key found for this signature in database
GPG Key ID: 517BE60E2CE5C8A5
3 changed files with 201 additions and 142 deletions

View File

@ -53,94 +53,20 @@ class DBA
private static $in_transaction = false; private static $in_transaction = false;
private static $in_retrial = false; private static $in_retrial = false;
private static $relation = []; private static $relation = [];
private static $db_serveraddr = '';
private static $db_user = '';
private static $db_pass = '';
private static $db_name = '';
private static $db_charset = '';
public static function connect($basePath, IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null) /**
* @var IDatabase
*/
private static $db;
/**
* Initialize the DBA with a given database
*
* @param IDatabase $db
*/
public function init(IDatabase $db)
{ {
if (!is_null(self::$connection) && self::connected()) { self::$db = $db;
return true;
}
// We are storing these values for being able to perform a reconnect
self::$basePath = $basePath;
self::$configCache = $configCache;
self::$profiler = $profiler;
self::$db_serveraddr = $serveraddr;
self::$db_user = $user;
self::$db_pass = $pass;
self::$db_name = $db;
self::$db_charset = $charset;
$port = 0;
$serveraddr = trim($serveraddr);
$serverdata = explode(':', $serveraddr);
$server = $serverdata[0];
if (count($serverdata) > 1) {
$port = trim($serverdata[1]);
}
$server = trim($server);
$user = trim($user);
$pass = trim($pass);
$db = trim($db);
$charset = trim($charset);
if (!(strlen($server) && strlen($user))) {
return false;
}
if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
self::$driver = 'pdo';
$connect = "mysql:host=".$server.";dbname=".$db;
if ($port > 0) {
$connect .= ";port=".$port;
}
if ($charset) {
$connect .= ";charset=".$charset;
}
try {
self::$connection = @new PDO($connect, $user, $pass);
self::$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
self::$connected = true;
} catch (PDOException $e) {
/// @TODO At least log exception, don't ignore it!
}
}
if (!self::$connected && class_exists('\mysqli')) {
self::$driver = 'mysqli';
if ($port > 0) {
self::$connection = @new mysqli($server, $user, $pass, $db, $port);
} else {
self::$connection = @new mysqli($server, $user, $pass, $db);
}
if (!mysqli_connect_errno()) {
self::$connected = true;
if ($charset) {
self::$connection->set_charset($charset);
}
}
}
// No suitable SQL driver was found.
if (!self::$connected) {
self::$driver = null;
self::$connection = null;
}
return self::$connected;
} }
/** /**
@ -148,29 +74,15 @@ class DBA
*/ */
public static function disconnect() public static function disconnect()
{ {
if (is_null(self::$connection)) { self::$db->disconnect();
return;
}
switch (self::$driver) {
case 'pdo':
self::$connection = null;
break;
case 'mysqli':
self::$connection->close();
self::$connection = null;
break;
}
} }
/** /**
* Perform a reconnect of an existing database connection * Perform a reconnect of an existing database connection
*/ */
public static function reconnect() { public static function reconnect()
self::disconnect(); {
self::$db->reconnect();
$ret = self::connect(self::$basePath, self::$configCache, self::$profiler, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
return $ret;
} }
/** /**
@ -179,7 +91,7 @@ class DBA
*/ */
public static function getConnection() public static function getConnection()
{ {
return self::$connection; return self::$db->getConnection();
} }
/** /**
@ -190,18 +102,9 @@ class DBA
* *
* @return string * @return string
*/ */
public static function serverInfo() { public static function serverInfo()
if (self::$server_info == '') { {
switch (self::$driver) { return self::$db->serverInfo();
case 'pdo':
self::$server_info = self::$connection->getAttribute(PDO::ATTR_SERVER_VERSION);
break;
case 'mysqli':
self::$server_info = self::$connection->server_info;
break;
}
}
return self::$server_info;
} }
/** /**

View File

@ -17,6 +17,8 @@ interface IDatabase
/** /**
* Perform a reconnect of an existing database connection * Perform a reconnect of an existing database connection
*
* @return bool Wsa the reconnect successful?
*/ */
function reconnect(); function reconnect();

View File

@ -4,108 +4,262 @@ namespace Friendica\Database;
use Friendica\Core\Config\Cache\IConfigCache; use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use mysqli;
use mysqli_result;
use mysqli_stmt;
use PDO;
use PDOException;
use PDOStatement;
class MysqlDatabase implements IDatabase, IDatabaseLock class MysqlDatabase implements IDatabase, IDatabaseLock
{ {
const DRIVER_PDO = 'pdo';
const DRIVER_MYSQLI = 'mysqli';
const DRIVER_INVALID = null;
/**
* The connection state of the database
* @var bool
*/
private $connected; private $connected;
private $dbUser;
private $dbPass;
private $dbName;
private $dbHost;
private $dbCharset;
private $serverInfo;
private $profiler;
private $configCache;
/**
* The connection to the database
* @var PDO|mysqli
*/
private $connection;
private $driver;
public function __construct(IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null) public function __construct(IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null)
{ {
$this->connected = DBA::connect($configCache, $profiler, $serveraddr, $user, $pass, $db, $charset); $this->configCache = $configCache;
$this->profiler = $profiler;
$this->dbHost = $serveraddr;
$this->dbUser = $user;
$this->dbPass = $pass;
$this->dbName = $db;
$this->dbCharset = $charset;
$this->serverInfo = '';
$this->connect();
} }
function isConnected() public function isConnected()
{ {
return $this->connected; return $this->connected;
} }
function disconnect() private function connect()
{ {
DBA::disconnect(); if (!is_null($this->connection) && $this->isConnected()) {
return;
}
$port = 0;
$serveraddr = trim($this->dbHost);
$serverdata = explode(':', $serveraddr);
$server = $serverdata[0];
if (count($serverdata) > 1) {
$port = trim($serverdata[1]);
}
$server = trim($server);
$user = trim($this->dbUser);
$pass = trim($this->dbPass);
$db = trim($this->dbName);
$charset = trim($this->dbCharset);
if (!(strlen($server) && strlen($user))) {
$this->connected = false;
return;
}
if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
$this->driver = self::DRIVER_PDO;
$connect = "mysql:host=".$server.";dbname=".$db;
if ($port > 0) {
$connect .= ";port=".$port;
}
if ($charset) {
$connect .= ";charset=".$charset;
}
try {
$this->connection = @new PDO($connect, $user, $pass);
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$this->connected = true;
} catch (PDOException $e) {
/// @TODO At least log exception, don't ignore it!
}
}
if (!$this->connected && class_exists('\mysqli')) {
$this->driver = self::DRIVER_MYSQLI;
if ($port > 0) {
$this->connection = @new mysqli($server, $user, $pass, $db, $port);
} else {
$this->connection = @new mysqli($server, $user, $pass, $db);
}
if (!mysqli_connect_errno()) {
$this->connected = true;
if ($charset) {
$this->connection->set_charset($charset);
}
}
}
// No suitable SQL driver was found.
if (!$this->connected) {
$this->driver = self::DRIVER_INVALID;
$this->connection = null;
}
} }
function reconnect() /**
* {@inheritdoc}
*/
public function disconnect()
{ {
DBA::reconnect(); if (is_null($this->connection)) {
$this->connected = DBA::connected(); return;
}
switch ($this->driver) {
case self::DRIVER_PDO:
$this->connection = null;
break;
case self::DRIVER_MYSQLI:
$this->connection->close();
$this->connection = null;
break;
}
} }
function getConnection() /**
* {@inheritdoc}
*/
public function reconnect()
{ {
return DBA::getConnection(); $this->disconnect();
$this->connect();
return $this->connected;
} }
function serverInfo() /**
* {@inheritdoc}
* @return mixed|mysqli|PDO
*/
public function getConnection()
{ {
return DBA::serverInfo(); return $this->connection;
} }
function databaseName() /**
* {@inheritdoc}
*/
public function serverInfo()
{
if (empty($this->serverInfo)) {
switch ($this->driver) {
case self::DRIVER_PDO:
$this->serverInfo = $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
break;
case self::DRIVER_MYSQLI:
$this->serverInfo = $this->connection->server_info;
break;
}
}
return $this->serverInfo;
}
public function databaseName()
{ {
return DBA::databaseName(); return DBA::databaseName();
} }
function exists($table, array $condition) public function exists($table, array $condition)
{ {
return DBA::exists($table, $condition); return DBA::exists($table, $condition);
} }
function count($table, array $condition = []) public function count($table, array $condition = [])
{ {
return DBA::count($table, $condition); return DBA::count($table, $condition);
} }
function fetch($stmt) public function fetch($stmt)
{ {
return DBA::fetch($stmt); return DBA::fetch($stmt);
} }
function transaction() public function transaction()
{ {
return DBA::transaction(); return DBA::transaction();
} }
function commit() public function commit()
{ {
return DBA::commit(); return DBA::commit();
} }
function rollback() public function rollback()
{ {
return DBA::rollback(); return DBA::rollback();
} }
function insert($table, array $param, $on_duplicate_update = false) public function insert($table, array $param, $on_duplicate_update = false)
{ {
return DBA::insert($table, $param, $on_duplicate_update); return DBA::insert($table, $param, $on_duplicate_update);
} }
function delete($table, array $conditions, $cascade = true) public function delete($table, array $conditions, $cascade = true)
{ {
return DBA::delete($table, $conditions, [$cascade]); return DBA::delete($table, $conditions, [$cascade]);
} }
function update($table, array $fields, array $condition, array $old_fields = []) public function update($table, array $fields, array $condition, array $old_fields = [])
{ {
return DBA::delete($table, $fields, $condition, $old_fields); return DBA::delete($table, $fields, $condition, $old_fields);
} }
function select($table, array $fields = [], array $condition = [], array $params = []) public function select($table, array $fields = [], array $condition = [], array $params = [])
{ {
return DBA::select($table, $fields, $condition, $params); return DBA::select($table, $fields, $condition, $params);
} }
function selectFirst($table, array $fields = [], array $condition = [], $params = []) public function selectFirst($table, array $fields = [], array $condition = [], $params = [])
{ {
return DBA::selectFirst($table, $fields, $condition, $params); return DBA::selectFirst($table, $fields, $condition, $params);
} }
function lock($table) public function lock($table)
{ {
return DBA::lock($table); return DBA::lock($table);
} }
function unlock() public function unlock()
{ {
return DBA::unlock(); return DBA::unlock();
} }