From 0b6d3c71f94dc820081b3afc94b581a690c6da27 Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Fri, 1 Mar 2019 09:08:42 +0100 Subject: [PATCH] WIP DBA refactoring --- src/Database/DBA.php | 137 ++++------------------ src/Database/IDatabase.php | 2 + src/Database/MysqlDatabase.php | 204 +++++++++++++++++++++++++++++---- 3 files changed, 201 insertions(+), 142 deletions(-) diff --git a/src/Database/DBA.php b/src/Database/DBA.php index 5211c09106..e275ba6671 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -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(); } /** diff --git a/src/Database/IDatabase.php b/src/Database/IDatabase.php index 59ff9ffe41..fd0722cf14 100644 --- a/src/Database/IDatabase.php +++ b/src/Database/IDatabase.php @@ -17,6 +17,8 @@ interface IDatabase /** * Perform a reconnect of an existing database connection + * + * @return bool Wsa the reconnect successful? */ function reconnect(); diff --git a/src/Database/MysqlDatabase.php b/src/Database/MysqlDatabase.php index d566f56268..609d88cac8 100644 --- a/src/Database/MysqlDatabase.php +++ b/src/Database/MysqlDatabase.php @@ -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(); }