From ab02df94d45feeb622572c1b98cfcd9aba9c6a28 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 9 Jun 2016 20:40:31 +0200 Subject: [PATCH] extract PDO code from Sqlfs streamwrapper into class Api\Db\Pdo, to be able to use it for z-push SqlStateMaschine --- api/src/Db/Pdo.php | 159 ++++++++++++++++++++++++++++ api/src/Vfs/Sqlfs/StreamWrapper.php | 118 +-------------------- 2 files changed, 160 insertions(+), 117 deletions(-) create mode 100644 api/src/Db/Pdo.php diff --git a/api/src/Db/Pdo.php b/api/src/Db/Pdo.php new file mode 100644 index 0000000000..6c3f40776c --- /dev/null +++ b/api/src/Db/Pdo.php @@ -0,0 +1,159 @@ + + * @copyright (c) 2008-16 by Ralf Becker + * @version $Id$ + */ + +namespace EGroupware\Api\Db; + +/** + * PDO database connection + */ +class Pdo +{ + /** + * Reference to the PDO object we use + * + * @var \PDO + */ + static protected $pdo; + + /** + * PDO database type: mysql, pgsl + * + * @var string + */ + public static $pdo_type; + + /** + * Case sensitive comparison operator, for mysql we use ' COLLATE utf8_bin =' + * + * @var string + */ + public static $case_sensitive_equal = '='; + + /** + * Get active PDO connection + * + * @return \PDO + * @throws \PDOException when opening PDO connection fails + * @throws Exception when opening regular db-connection fails + */ + static public function connection() + { + if (!isset(self::$pdo)) + { + self::reconnect(); + } + return self::$pdo; + } + + /** + * Reconnect to database + */ + static public function reconnect() + { + self::$pdo = self::_pdo(); + } + + /** + * Create pdo object / connection, as long as pdo is not generally used in eGW + * + * @return \PDO + */ + static protected function _pdo() + { + $egw_db = isset($GLOBALS['egw_setup']) ? $GLOBALS['egw_setup']->db : $GLOBALS['egw']->db; + + switch($egw_db->Type) + { + case 'mysqli': + case 'mysqlt': + case 'mysql': + self::$case_sensitive_equal = '= BINARY '; + self::$pdo_type = 'mysql'; + break; + default: + self::$pdo_type = $egw_db->Type; + break; + } + // get host used be egw_db + $egw_db->connect(); + $host = $egw_db->get_host(); + + $dsn = self::$pdo_type.':dbname='.$egw_db->Database.($host ? ';host='.$host.($egw_db->Port ? ';port='.$egw_db->Port : '') : ''); + // check once if pdo extension and DB specific driver is loaded or can be loaded + static $pdo_available=null; + if (is_null($pdo_available)) + { + foreach(array('pdo','pdo_'.self::$pdo_type) as $ext) + { + check_load_extension($ext,true); // true = throw Exception + } + $pdo_available = true; + } + // set client charset of the connection + switch(self::$pdo_type) + { + case 'mysql': + $dsn .= ';charset=utf8'; + break; + case 'pgsql': + $query = "SET NAMES 'utf-8'"; + break; + } + try { + self::$pdo = new \PDO($dsn,$egw_db->User,$egw_db->Password,array( + \PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION, + )); + } + catch(\PDOException $e) + { + unset($e); + // Exception reveals password, so we ignore the exception and connect again without pw, to get the right exception without pw + self::$pdo = new \PDO($dsn,$egw_db->User,'$egw_db->Password'); + } + if ($query) + { + self::$pdo->exec($query); + } + return self::$pdo; + } + + /** + * Just a little abstration 'til I know how to organise stuff like that with PDO + * + * @param mixed $time + * @return string Y-m-d H:i:s + */ + static public function _pdo_timestamp($time) + { + if (is_numeric($time)) + { + $time = date('Y-m-d H:i:s',$time); + } + return $time; + } + + /** + * Just a little abstration 'til I know how to organise stuff like that with PDO + * + * @param boolean $val + * @return string '1' or '0' for mysql, 'true' or 'false' for everyone else + */ + static public function _pdo_boolean($val) + { + if (self::$pdo_type == 'mysql') + { + return $val ? '1' : '0'; + } + return $val ? 'true' : 'false'; + } +} diff --git a/api/src/Vfs/Sqlfs/StreamWrapper.php b/api/src/Vfs/Sqlfs/StreamWrapper.php index afafdf95d5..eddd233c84 100644 --- a/api/src/Vfs/Sqlfs/StreamWrapper.php +++ b/api/src/Vfs/Sqlfs/StreamWrapper.php @@ -34,7 +34,7 @@ use EGroupware\Api; * * @link http://www.php.net/manual/en/function.stream-wrapper-register.php */ -class StreamWrapper implements Vfs\StreamWrapperIface +class StreamWrapper extends Api\Db\Pdo implements Vfs\StreamWrapperIface { /** * Mime type of directories, the old vfs uses 'Directory', while eg. WebDAV uses 'httpd/unix-directory' @@ -141,12 +141,6 @@ class StreamWrapper implements Vfs\StreamWrapperIface * @var array $path => info-array pairs */ static protected $stat_cache = array(); - /** - * Reference to the PDO object we use - * - * @var \PDO - */ - static protected $pdo; /** * Array with filenames of dir opened with dir_opendir * @@ -1624,116 +1618,6 @@ class StreamWrapper implements Vfs\StreamWrapperIface return $stat; } - public static $pdo_type; - /** - * Case sensitive comparison operator, for mysql we use ' COLLATE utf8_bin =' - * - * @var string - */ - public static $case_sensitive_equal = '='; - - /** - * Reconnect to database - */ - static public function reconnect() - { - self::$pdo = self::_pdo(); - } - - /** - * Create pdo object / connection, as long as pdo is not generally used in eGW - * - * @return \PDO - */ - static protected function _pdo() - { - $egw_db = isset($GLOBALS['egw_setup']) ? $GLOBALS['egw_setup']->db : $GLOBALS['egw']->db; - - switch($egw_db->Type) - { - case 'mysqli': - case 'mysqlt': - case 'mysql': - self::$case_sensitive_equal = '= BINARY '; - self::$pdo_type = 'mysql'; - break; - default: - self::$pdo_type = $egw_db->Type; - break; - } - // get host used be egw_db - $egw_db->connect(); - $host = $egw_db->get_host(); - - $dsn = self::$pdo_type.':dbname='.$egw_db->Database.($host ? ';host='.$host.($egw_db->Port ? ';port='.$egw_db->Port : '') : ''); - // check once if pdo extension and DB specific driver is loaded or can be loaded - static $pdo_available=null; - if (is_null($pdo_available)) - { - foreach(array('pdo','pdo_'.self::$pdo_type) as $ext) - { - check_load_extension($ext,true); // true = throw Exception - } - $pdo_available = true; - } - // set client charset of the connection - switch(self::$pdo_type) - { - case 'mysql': - $dsn .= ';charset=utf8'; - break; - case 'pgsql': - $query = "SET NAMES 'utf-8'"; - break; - } - try { - self::$pdo = new \PDO($dsn,$egw_db->User,$egw_db->Password,array( - \PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION, - )); - } - catch(\PDOException $e) - { - unset($e); - // Exception reveals password, so we ignore the exception and connect again without pw, to get the right exception without pw - self::$pdo = new \PDO($dsn,$egw_db->User,'$egw_db->Password'); - } - if ($query) - { - self::$pdo->exec($query); - } - return self::$pdo; - } - - /** - * Just a little abstration 'til I know how to organise stuff like that with PDO - * - * @param mixed $time - * @return string Y-m-d H:i:s - */ - static protected function _pdo_timestamp($time) - { - if (is_numeric($time)) - { - $time = date('Y-m-d H:i:s',$time); - } - return $time; - } - - /** - * Just a little abstration 'til I know how to organise stuff like that with PDO - * - * @param boolean $val - * @return string '1' or '0' for mysql, 'true' or 'false' for everyone else - */ - static protected function _pdo_boolean($val) - { - if (self::$pdo_type == 'mysql') - { - return $val ? '1' : '0'; - } - return $val ? 'true' : 'false'; - } - /** * Maximum value for a single hash element (should be 10^N): 10, 100 (default), 1000, ... *