N°1260 every classes creating a mysqli instance now use a dedicated method in CMDBSource

SVN:trunk[5309]
This commit is contained in:
Pierre Goiffon
2018-02-08 14:21:33 +00:00
parent d2f0deec9c
commit 37232bc222
4 changed files with 116 additions and 78 deletions

View File

@@ -134,8 +134,6 @@ class CMDBSource
*/
public static function Init($sServer, $sUser, $sPwd, $sSource = '', $sSSLKey = NULL, $sSSLCert = NULL, $sSSLCA = NULL, $sSSLCipher = NULL )
{
self::$m_oMysqli = null;
self::$m_sDBHost = $sServer;
self::$m_sDBUser = $sUser;
self::$m_sDBPwd = $sPwd;
@@ -145,31 +143,54 @@ class CMDBSource
self::$m_sDBSSLCA = empty($sSSLCA) ? null : $sSSLCA;
self::$m_sDBSSLCipher = empty($sSSLCipher) ? null : $sSSLCipher;
self::$m_oMysqli = self::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $sSSLKey, $sSSLCert, $sSSLCA,
$sSSLCipher);
}
/**
* @param string $sServer
* @param string $sUser
* @param string $sPwd
* @param string $sSource database to use
* @param string $sSSLKey
* @param string $sSSLCert
* @param string $sSSLCA
* @param string $sSSLCipher
*
* @return \mysqli
* @throws \MySQLException
*/
public static function GetMysqliInstance(
$sServer, $sUser, $sPwd, $sSource = '', $sSSLKey = null, $sSSLCert = null, $sSSLCA = null, $sSSLCipher = null
) {
$oMysqli = null;
$sServer = null;
$iPort = null;
self::InitServerAndPort($sServer, $iPort);
$iFlags = null;
mysqli_report(MYSQLI_REPORT_STRICT); // *some* errors (like connection errors) will throw mysqli_sql_exception instead
// of generating warnings printed to the output but some other errors will still
// cause the query() method to return false !!!
// *some* errors (like connection errors) will throw mysqli_sql_exception instead of generating warnings printed to the output
// but some other errors will still cause the query() method to return false !!!
mysqli_report(MYSQLI_REPORT_STRICT);
try
{
self::$m_oMysqli = new mysqli();
self::$m_oMysqli->init();
$oMysqli = new mysqli();
$oMysqli->init();
if (!empty(self::$m_sDBSSLKey) && !empty(self::$m_sDBSSLCert) && !empty(self::$m_sDBSSLCA))
if (!empty($sSSLKey) && !empty($sSSLCert) && !empty($sSSLCA))
{
$iFlags = MYSQLI_CLIENT_SSL;
self::$m_oMysqli->ssl_set(self::$m_sDBSSLKey, self::$m_sDBSSLCert, self::$m_sDBSSLCA, null,
self::$m_sDBSSLCipher);
$oMysqli->ssl_set($sSSLKey, $sSSLCert, $sSSLCA, null, $sSSLCipher);
}
self::$m_oMysqli->real_connect($sServer, self::$m_sDBUser, self::$m_sDBPwd, '', $iPort,
$oMysqli->real_connect($sServer, $sUser, $sPwd, '', $iPort,
ini_get("mysqli.default_socket"), $iFlags);
}
catch(mysqli_sql_exception $e)
{
throw new MySQLException('Could not connect to the DB server', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser), $e);
throw new MySQLException('Could not connect to the DB server',
array('host' => $sServer, 'user' => $sUser), $e);
}
if (!empty($sSource))
@@ -177,13 +198,16 @@ class CMDBSource
try
{
mysqli_report(MYSQLI_REPORT_STRICT); // Errors, in the next query, will throw mysqli_sql_exception
self::$m_oMysqli->query("USE `$sSource`");
$oMysqli->query("USE `$sSource`");
}
catch(mysqli_sql_exception $e)
{
throw new MySQLException('Could not select DB', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser, 'db_name'=>self::$m_sDBName), $e);
throw new MySQLException('Could not select DB',
array('host' => $sServer, 'user' => $sUser, 'db_name' => $sSource), $e);
}
}
return $oMysqli;
}
/**
@@ -328,6 +352,14 @@ class CMDBSource
return $res;
}
/**
* @return \mysqli
*/
public static function GetMysqli()
{
return self::$m_oMysqli;
}
public static function GetErrNo()
{
if (self::$m_oMysqli->errno != 0)

View File

@@ -30,8 +30,16 @@
class iTopMutex
{
protected $sName;
protected $hDBLink;
/** @var bool */
protected $bLocked; // Whether or not this instance of the Mutex is locked
/** @var \mysqli */
protected $hDBLink;
protected $sDBHost;
protected $sDBUser;
protected $sDBPwd;
protected $sDBName;
protected $sDBSubname;
protected $sDBSSLKey;
protected $sDBSSLCert;
protected $sDBSSLCA;
@@ -47,10 +55,10 @@ class iTopMutex
{
$oConfig = utils::GetConfig(); // Will return an empty config when called during the setup
}
$sDBHost = is_null($sDBHost) ? $oConfig->Get('db_host') : $sDBHost;
$sDBUser = is_null($sDBUser) ? $oConfig->Get('db_user') : $sDBUser;
$sDBPwd = is_null($sDBPwd) ? $oConfig->Get('db_pwd') : $sDBPwd;
$sDBName = $oConfig->Get('db_name');
$this->sDBHost = is_null($sDBHost) ? $oConfig->Get('db_host') : $sDBHost;
$this->sDBUser = is_null($sDBUser) ? $oConfig->Get('db_user') : $sDBUser;
$this->sDBPwd = is_null($sDBPwd) ? $oConfig->Get('db_pwd') : $sDBPwd;
$this->sDBName = $oConfig->Get('db_name');
$sDBSubname = $oConfig->Get('db_subname');
$this->sDBSSLKey = $oConfig->Get('db_ssl.key');
$this->sDBSSLCert = $oConfig->Get('db_ssl.cert');
@@ -58,12 +66,12 @@ class iTopMutex
$this->sDBSSLCipher = $oConfig->Get('db_ssl.cipher');
$this->sName = 'itop.'.$sName;
$this->sName = $sName;
if (substr($sName, -strlen($sDBName.$sDBSubname)) != $sDBName.$sDBSubname)
if (substr($sName, -strlen($this->sDBName.$sDBSubname)) != $this->sDBName.$sDBSubname)
{
// If the name supplied already ends with the expected suffix
// don't add it twice, since the setup may try to detect an already
// running cron job by its mutex, without knowing if the config already exists or not
$this->sName .= $sDBName.$sDBSubname;
$this->sName .= $this->sDBName.$sDBSubname;
}
// Limit the length of the name for MySQL > 5.7.5
@@ -78,7 +86,7 @@ class iTopMutex
// It is a MUST to create a dedicated session each time a lock is required, because
// using GET_LOCK anytime on the same session will RELEASE the current and unique session lock (known issue)
$this->InitMySQLSession($sDBHost, $sDBUser, $sDBPwd);
$this->InitMySQLSession();
}
public function __destruct()
@@ -211,45 +219,29 @@ class iTopMutex
self::$aAcquiredLocks[$this->sName]--;
}
public function InitMySQLSession($sHost, $sUser, $sPwd)
/**
* Initialiaze database connection. Mandatory attributes must be already set !
*
* @throws \Exception
* @throws \MySQLException
*/
public function InitMySQLSession()
{
$aConnectInfo = explode(':', $sHost);
if (count($aConnectInfo) > 1)
{
// Override the default port
$sServer = $aConnectInfo[0];
$iPort = $aConnectInfo[1];
$this->hDBLink = mysqli_init();
if ( empty($this->sDBSSLKey) || empty($this->sDBSSLCert) || empty($this->sDBSSLCA) )
{
$this->hDBLink->real_connect($sServer,$sUser,$sPwd,'',$iPort);
}
else
{
$this->hDBLink->ssl_set($this->sDBSSLKey,$this->sDBSSLCert,$this->sDBSSLCA,NULL,$this->sDBSSLCipher);
$this->hDBLink->real_connect($sServer,$sUser,$sPwd,'',$iPort, ini_get("mysqli.default_socket"),MYSQLI_CLIENT_SSL );
}
}
else
{
$this->hDBLink = new mysqli();
$this->hDBLink->init();
if ( empty($this->sDBSSLKey) || empty($this->sDBSSLCert) || empty($this->sDBSSLCA) )
{
$this->hDBLink->real_connect($sHost,$sUser,$sPwd);
}
else
{
$this->hDBLink->ssl_set($this->sDBSSLKey,$this->sDBSSLCert,$this->sDBSSLCA,NULL,$this->sDBSSLCipher);
$this->hDBLink->real_connect('p:'.$sHost,$sUser,$sPwd,'',NULL, ini_get("mysqli.default_socket"),MYSQLI_CLIENT_SSL );
}
}
$sServer = $this->sDBHost;
$sUser = $this->sDBUser;
$sPwd = $this->sDBPwd;
$sSource = $this->sDBName;
$sSSLKey = $this->sDBSSLKey;
$sSSLCert = $this->sDBSSLCert;
$sSSLCA = $this->sDBSSLCA;
$sSSLCipher = $this->sDBSSLCipher;
$this->hDBLink = CMDBSource::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $sSSLKey, $sSSLCert, $sSSLCA,
$sSSLCipher);
if (!$this->hDBLink)
{
throw new Exception("Could not connect to the DB server (host=$sHost, user=$sUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
throw new Exception("Could not connect to the DB server (host=$sServer, user=$sUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
}
}

View File

@@ -1,6 +1,6 @@
<?php
// Copyright (C) 2017 Combodo SARL
// Copyright (C) 2017-2018 Combodo SARL
//
// This file is part of iTop.
//
@@ -21,7 +21,7 @@
* iTop Hub Launch Page
* Collect the information to be posted to iTopHub
*
* @copyright Copyright (c) 2017 Combodo SARL
* @copyright Copyright (c) 2017-2018 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -127,11 +127,7 @@ function collect_configuration()
);
// Database information
$class = new ReflectionClass('CMDBSource');
$m_oMysqli_property = $class->getProperty('m_oMysqli');
$m_oMysqli_property->setAccessible(true);
$m_oMysqli = $m_oMysqli_property->getValue();
$m_oMysqli = CMDBSource::GetMysqli();
$aConfiguration['database_settings']['server'] = (string) $m_oMysqli->server_version;
$aConfiguration['database_settings']['client'] = (string) $m_oMysqli->client_version;

View File

@@ -513,27 +513,45 @@ if (class_exists('ZipArchive')) // The setup must be able to start even if the "
/**
* Helper to open a Database connection
*
* @return \mysqli
* @throws \BackupException
* @uses CMDBSource
*/
protected function DBConnect()
{
if (is_null($this->iDBPort))
$oConfig = MetaModel::GetConfig();
$sServer = $oConfig->Get('db_host');
$sUser = $oConfig->Get('db_user');
$sPwd = $oConfig->Get('db_pwd');
$sSource = $oConfig->Get('db_name');
$sSSLKey = $oConfig->Get('db_ssl.key');
$sSSLCert = $oConfig->Get('db_ssl.cert');
$sSSLCA = $oConfig->Get('db_ssl.ca');
$sSSLCipher = $oConfig->Get('db_ssl.cipher');
try
{
$oMysqli = new mysqli($this->sDBHost, $this->sDBUser, $this->sDBPwd);
$oMysqli = CMDBSource::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $sSSLKey, $sSSLCert,
$sSSLCA,
$sSSLCipher);
if ($oMysqli->connect_errno)
{
$sHost = is_null($this->iDBPort) ? $this->sDBHost : $this->sDBHost.' on port '.$this->iDBPort;
throw new BackupException("Cannot connect to the MySQL server '$sHost' (".$oMysqli->connect_errno.") ".$oMysqli->connect_error);
}
if (!$oMysqli->select_db($this->sDBName))
{
throw new BackupException("The database '$this->sDBName' does not seem to exist");
}
return $oMysqli;
}
else
catch (MySQLException $e)
{
$oMysqli = new mysqli($this->sDBHost, $this->sDBUser, $this->sDBPwd, '', $this->iDBPort);
throw new BackupException($e->getMessage());
}
if ($oMysqli->connect_errno)
{
$sHost = is_null($this->iDBPort) ? $this->sDBHost : $this->sDBHost.' on port '.$this->iDBPort;
throw new BackupException("Cannot connect to the MySQL server '$sHost' (".$oMysqli->connect_errno.") ".$oMysqli->connect_error);
}
if (!$oMysqli->select_db($this->sDBName))
{
throw new BackupException("The database '$this->sDBName' does not seem to exist");
}
return $oMysqli;
}
/**