mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 10:38:45 +02:00
♻️ N°4325 refactor CMDBSource mysqli attributes to a separate wrapper class (#237)
In 2.7.5 with N°3513 we added a second mysqli attribute in CMDBSource, so that we can test transactions (see TransactionsTest). But this wasn't documented, and was really causing confusion ! This refactor wraps both attributes in a dedicated object so that the logic is clearer.
This commit is contained in:
@@ -24,13 +24,15 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Core\DbConnectionWrapper;
|
||||
|
||||
require_once('MyHelpers.class.inc.php');
|
||||
require_once(APPROOT.'core/kpi.class.inc.php');
|
||||
|
||||
|
||||
/**
|
||||
* CMDBSource
|
||||
* database access wrapper
|
||||
* database access wrapper
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
@@ -66,11 +68,6 @@ class CMDBSource
|
||||
*/
|
||||
protected static $m_sDBTlsCA;
|
||||
|
||||
/** @var mysqli $m_oMysqli */
|
||||
protected static $m_oMysqli;
|
||||
/** @var mysqli or mock used for test purpose, only used in query() method */
|
||||
protected static $oMySQLiForQuery;
|
||||
|
||||
/**
|
||||
* @var int number of level for nested transactions : 0 if no transaction was ever opened, +1 for each 'START TRANSACTION' sent
|
||||
* @since 2.7.0 N°679
|
||||
@@ -135,8 +132,8 @@ class CMDBSource
|
||||
self::$m_bDBTlsEnabled = empty($bTlsEnabled) ? false : $bTlsEnabled;
|
||||
self::$m_sDBTlsCA = empty($sTlsCA) ? null : $sTlsCA;
|
||||
|
||||
self::$m_oMysqli = self::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $bTlsEnabled, $sTlsCA, true);
|
||||
self::SetMySQLiForQuery(self::$m_oMysqli);
|
||||
$oMysqli = self::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $bTlsEnabled, $sTlsCA, true);
|
||||
DbConnectionWrapper::SetDbConnection($oMysqli);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,7 +342,8 @@ class CMDBSource
|
||||
{
|
||||
// In case we don't have rights to enumerate the databases
|
||||
// Let's try to connect directly
|
||||
return @((bool)self::$m_oMysqli->query("USE `$sSource`"));
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
return @((bool)DbConnectionWrapper::GetDbConnection(true)->query("USE `$sSource`"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -361,7 +359,7 @@ class CMDBSource
|
||||
*/
|
||||
public static function GetServerInfo()
|
||||
{
|
||||
return mysqli_get_server_info ( self::$m_oMysqli );
|
||||
return mysqli_get_server_info(DbConnectionWrapper::GetDbConnection());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,9 +390,9 @@ class CMDBSource
|
||||
*/
|
||||
public static function SelectDB($sSource)
|
||||
{
|
||||
if (!((bool)self::$m_oMysqli->query("USE `$sSource`")))
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('db_name'=>$sSource));
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
if (!((bool)DbConnectionWrapper::GetDbConnection(true)->query("USE `$sSource`"))) {
|
||||
throw new MySQLException('Could not select DB', array('db_name' => $sSource));
|
||||
}
|
||||
self::$m_sDBName = $sSource;
|
||||
}
|
||||
@@ -448,48 +446,24 @@ class CMDBSource
|
||||
*/
|
||||
public static function GetMysqli()
|
||||
{
|
||||
return self::$m_oMysqli;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private static function GetMySQLiForQuery()
|
||||
{
|
||||
return self::$oMySQLiForQuery;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used for test purpose (mysqli mock)
|
||||
* @param $oMySQLi
|
||||
*/
|
||||
private static function SetMySQLiForQuery($oMySQLi)
|
||||
{
|
||||
self::$oMySQLiForQuery = $oMySQLi;
|
||||
return DbConnectionWrapper::GetDbConnection(false);
|
||||
}
|
||||
|
||||
public static function GetErrNo()
|
||||
{
|
||||
if (self::$m_oMysqli->errno != 0)
|
||||
{
|
||||
return self::$m_oMysqli->errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oMysqli->connect_errno;
|
||||
if (DbConnectionWrapper::GetDbConnection()->errno != 0) {
|
||||
return DbConnectionWrapper::GetDbConnection()->errno;
|
||||
} else {
|
||||
return DbConnectionWrapper::GetDbConnection()->connect_errno;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetError()
|
||||
{
|
||||
if (self::$m_oMysqli->error != '')
|
||||
{
|
||||
return self::$m_oMysqli->error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oMysqli->connect_error;
|
||||
if (DbConnectionWrapper::GetDbConnection()->error != '') {
|
||||
return DbConnectionWrapper::GetDbConnection()->error;
|
||||
} else {
|
||||
return DbConnectionWrapper::GetDbConnection()->connect_error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,7 +503,8 @@ class CMDBSource
|
||||
// Quote if not a number or a numeric string
|
||||
if ($bAlways || is_string($value))
|
||||
{
|
||||
$value = $cQuoteStyle . self::$m_oMysqli->real_escape_string($value) . $cQuoteStyle;
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$value = $cQuoteStyle.DbConnectionWrapper::GetDbConnection()->real_escape_string($value).$cQuoteStyle;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
@@ -612,26 +587,25 @@ class CMDBSource
|
||||
$oKPI = new ExecutionKPI();
|
||||
try
|
||||
{
|
||||
$oResult = self::GetMySQLiForQuery()->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch (mysqli_sql_exception $e)
|
||||
{
|
||||
self::LogDeadLock($e);
|
||||
self::LogDeadLock($e, true);
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
if ($oResult === false)
|
||||
{
|
||||
if ($oResult === false) {
|
||||
$aContext = array('query' => $sSql);
|
||||
|
||||
$iMySqlErrorNo = self::$m_oMysqli->errno;
|
||||
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection(true)->errno;
|
||||
$aMySqlHasGoneAwayErrorCodes = MySQLHasGoneAwayException::getErrorCodes();
|
||||
if (in_array($iMySqlErrorNo, $aMySqlHasGoneAwayErrorCodes))
|
||||
{
|
||||
if (in_array($iMySqlErrorNo, $aMySqlHasGoneAwayErrorCodes)) {
|
||||
throw new MySQLHasGoneAwayException(self::GetError(), $aContext);
|
||||
}
|
||||
$e = new MySQLException('Failed to issue SQL query', $aContext);
|
||||
self::LogDeadLock($e);
|
||||
self::LogDeadLock($e, true);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@@ -640,23 +614,24 @@ class CMDBSource
|
||||
|
||||
/**
|
||||
* @param \Exception $e
|
||||
* @param bool $bForQuery to get the proper DB connection
|
||||
*
|
||||
* @since 2.7.1
|
||||
* @since 3.0.0 N°4325 add new optional parameter to use the correct DB connection
|
||||
*/
|
||||
private static function LogDeadLock(Exception $e)
|
||||
private static function LogDeadLock(Exception $e, $bForQuery = false)
|
||||
{
|
||||
// checks MySQL error code
|
||||
$iMySqlErrorNo = self::$m_oMysqli->errno;
|
||||
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK)))
|
||||
{
|
||||
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection($bForQuery)->errno;
|
||||
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get error info
|
||||
$sUser = UserRights::GetUser();
|
||||
$oError = self::$m_oMysqli->query('SHOW ENGINE INNODB STATUS');
|
||||
if ($oError !== false)
|
||||
{
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oError = DbConnectionWrapper::GetDbConnection(true)->query('SHOW ENGINE INNODB STATUS');
|
||||
if ($oError !== false) {
|
||||
$aData = $oError->fetch_all(MYSQLI_ASSOC);
|
||||
$sInnodbStatus = $aData[0];
|
||||
}
|
||||
@@ -829,7 +804,7 @@ class CMDBSource
|
||||
|
||||
public static function GetInsertId()
|
||||
{
|
||||
$iRes = self::$m_oMysqli->insert_id;
|
||||
$iRes = DbConnectionWrapper::GetDbConnection()->insert_id;
|
||||
if (is_null($iRes))
|
||||
{
|
||||
return 0;
|
||||
@@ -871,7 +846,8 @@ class CMDBSource
|
||||
$oKPI = new ExecutionKPI();
|
||||
try
|
||||
{
|
||||
$oResult = self::GetMySQLiForQuery()->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
@@ -912,7 +888,8 @@ class CMDBSource
|
||||
$oKPI = new ExecutionKPI();
|
||||
try
|
||||
{
|
||||
$oResult = self::GetMySQLiForQuery()->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
@@ -962,7 +939,8 @@ class CMDBSource
|
||||
$aData = array();
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
@@ -994,7 +972,8 @@ class CMDBSource
|
||||
{
|
||||
try
|
||||
{
|
||||
$oResult = self::GetMySQLiForQuery()->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
@@ -1019,7 +998,7 @@ class CMDBSource
|
||||
|
||||
public static function AffectedRows()
|
||||
{
|
||||
return self::$m_oMysqli->affected_rows;
|
||||
return DbConnectionWrapper::GetDbConnection()->affected_rows;
|
||||
}
|
||||
|
||||
public static function FetchArray($oResult)
|
||||
@@ -1482,7 +1461,8 @@ class CMDBSource
|
||||
$sSql = "SELECT * FROM `$sTable`";
|
||||
try
|
||||
{
|
||||
$oResult = self::GetMySQLiForQuery()->query($sSql);
|
||||
/** @noinspection NullPointerExceptionInspection this shouldn't be called with un-init DB */
|
||||
$oResult = DbConnectionWrapper::GetDbConnection(true)->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user