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_retrial = false;
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()) {
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;
self::$db = $db;
}
/**
@ -148,29 +74,15 @@ class DBA
*/
public static function disconnect()
{
if (is_null(self::$connection)) {
return;
}
switch (self::$driver) {
case 'pdo':
self::$connection = null;
break;
case 'mysqli':
self::$connection->close();
self::$connection = null;
break;
}
self::$db->disconnect();
}
/**
* Perform a reconnect of an existing database connection
*/
public static function reconnect() {
self::disconnect();
$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;
public static function reconnect()
{
self::$db->reconnect();
}
/**
@ -179,7 +91,7 @@ class DBA
*/
public static function getConnection()
{
return self::$connection;
return self::$db->getConnection();
}
/**
@ -190,18 +102,9 @@ class DBA
*
* @return string
*/
public static function serverInfo() {
if (self::$server_info == '') {
switch (self::$driver) {
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;
public static function serverInfo()
{
return self::$db->serverInfo();
}
/**

View File

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

View File

@ -4,108 +4,262 @@ namespace Friendica\Database;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Util\Profiler;
use mysqli;
use mysqli_result;
use mysqli_stmt;
use PDO;
use PDOException;
use PDOStatement;
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 $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)
{
$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;
}
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();
$this->connected = DBA::connected();
if (is_null($this->connection)) {
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();
}
function exists($table, array $condition)
public function exists($table, array $condition)
{
return DBA::exists($table, $condition);
}
function count($table, array $condition = [])
public function count($table, array $condition = [])
{
return DBA::count($table, $condition);
}
function fetch($stmt)
public function fetch($stmt)
{
return DBA::fetch($stmt);
}
function transaction()
public function transaction()
{
return DBA::transaction();
}
function commit()
public function commit()
{
return DBA::commit();
}
function rollback()
public function 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);
}
function delete($table, array $conditions, $cascade = true)
public function delete($table, array $conditions, $cascade = true)
{
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);
}
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);
}
function selectFirst($table, array $fields = [], array $condition = [], $params = [])
public function selectFirst($table, array $fields = [], array $condition = [], $params = [])
{
return DBA::selectFirst($table, $fields, $condition, $params);
}
function lock($table)
public function lock($table)
{
return DBA::lock($table);
}
function unlock()
public function unlock()
{
return DBA::unlock();
}