forked from extern/egroupware
extract PDO code from Sqlfs streamwrapper into class Api\Db\Pdo, to be able to use it for z-push SqlStateMaschine
This commit is contained in:
parent
3f9fd761bb
commit
ab02df94d4
159
api/src/Db/Pdo.php
Normal file
159
api/src/Db/Pdo.php
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware API: PDO database connection
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage db
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @copyright (c) 2008-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @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';
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ use EGroupware\Api;
|
|||||||
*
|
*
|
||||||
* @link http://www.php.net/manual/en/function.stream-wrapper-register.php
|
* @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'
|
* 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
|
* @var array $path => info-array pairs
|
||||||
*/
|
*/
|
||||||
static protected $stat_cache = array();
|
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
|
* Array with filenames of dir opened with dir_opendir
|
||||||
*
|
*
|
||||||
@ -1624,116 +1618,6 @@ class StreamWrapper implements Vfs\StreamWrapperIface
|
|||||||
return $stat;
|
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, ...
|
* Maximum value for a single hash element (should be 10^N): 10, 100 (default), 1000, ...
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user