diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php
index b9453ebf8..183ab29e7 100644
--- a/application/cmdbabstract.class.inc.php
+++ b/application/cmdbabstract.class.inc.php
@@ -438,7 +438,6 @@ abstract class cmdbAbstractObject extends CMDBObject
$aAttribs[$sAttCode] = array('label' => MetaModel::GetLabel($sClassName, $sAttCode), 'description' => MetaModel::GetDescription($sClassName, $sAttCode));
}
$aValues = array();
- $oSet->Seek(0);
$bDisplayLimit = isset($aExtraParams['display_limit']) ? $aExtraParams['display_limit'] : true;
$iMaxObjects = -1;
if ($bDisplayLimit)
@@ -446,8 +445,10 @@ abstract class cmdbAbstractObject extends CMDBObject
if ($oSet->Count() > utils::GetConfig()->GetMaxDisplayLimit())
{
$iMaxObjects = utils::GetConfig()->GetMinDisplayLimit();
+ $oSet->SetLimit($iMaxObjects);
}
}
+ $oSet->Seek(0);
while (($oObj = $oSet->Fetch()) && ($iMaxObjects != 0))
{
$aRow = array();
diff --git a/core/config.class.inc.php b/core/config.class.inc.php
index 09597a4dc..46733fcd2 100644
--- a/core/config.class.inc.php
+++ b/core/config.class.inc.php
@@ -42,6 +42,10 @@ define ('DEFAULT_LOG_ISSUE', true);
define ('DEFAULT_LOG_WEB_SERVICE', true);
define ('DEFAULT_LOG_KPI_DURATION', false);
define ('DEFAULT_LOG_KPI_MEMORY', false);
+define ('DEFAULT_DEBUG_QUERIES', false);
+
+define ('DEFAULT_QUERY_CACHE_ENABLED', true);
+
define ('DEFAULT_MIN_DISPLAY_LIMIT', 10);
define ('DEFAULT_MAX_DISPLAY_LIMIT', 15);
@@ -88,6 +92,8 @@ class Config
protected $m_bLogWebService;
protected $m_bLogKpiDuration; // private setting
protected $m_bLogKpiMemory; // private setting
+ protected $m_bDebugQueries; // private setting
+ protected $m_bQueryCacheEnabled; // private setting
/**
* @var integer Number of elements to be displayed when there are more than m_iMaxDisplayLimit elements
@@ -300,6 +306,9 @@ class Config
$this->m_bLogWebService = isset($MySettings['log_web_service']) ? (bool) trim($MySettings['log_web_service']) : DEFAULT_LOG_WEB_SERVICE;
$this->m_bLogKPIDuration = isset($MySettings['log_kpi_duration']) ? (bool) trim($MySettings['log_kpi_duration']) : DEFAULT_LOG_KPI_DURATION;
$this->m_bLogKPIMemory = isset($MySettings['log_kpi_memory']) ? (bool) trim($MySettings['log_kpi_memory']) : DEFAULT_LOG_KPI_MEMORY;
+ $this->m_bDebugQueries = isset($MySettings['debug_queries']) ? (bool) trim($MySettings['debug_queries']) : DEFAULT_DEBUG_QUERIES;
+ $this->m_bQueryCacheEnabled = isset($MySettings['query_cache_enabled']) ? (bool) trim($MySettings['query_cache_enabled']) : DEFAULT_QUERY_CACHE_ENABLED;
+
$this->m_iMinDisplayLimit = isset($MySettings['min_display_limit']) ? trim($MySettings['min_display_limit']) : DEFAULT_MIN_DISPLAY_LIMIT;
$this->m_iMaxDisplayLimit = isset($MySettings['max_display_limit']) ? trim($MySettings['max_display_limit']) : DEFAULT_MAX_DISPLAY_LIMIT;
$this->m_iStandardReloadInterval = isset($MySettings['standard_reload_interval']) ? trim($MySettings['standard_reload_interval']) : DEFAULT_STANDARD_RELOAD_INTERVAL;
@@ -451,6 +460,16 @@ class Config
return $this->m_bLogKPIMemory;
}
+ public function GetDebugQueries()
+ {
+ return $this->m_bDebugQueries;
+ }
+
+ public function GetQueryCacheEnabled()
+ {
+ return $this->m_bQueryCacheEnabled;
+ }
+
public function GetMinDisplayLimit()
{
return $this->m_iMinDisplayLimit;
diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php
index 077cc4be3..979826c5b 100644
--- a/core/dbobjectset.class.php
+++ b/core/dbobjectset.class.php
@@ -38,11 +38,13 @@ class DBObjectSet
private $m_aId2Row;
private $m_iCurrRow;
- public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array())
+ public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array(), $iLimitCount = 0, $iLimitStart = 0)
{
$this->m_oFilter = $oFilter;
$this->m_aOrderBy = $aOrderBy;
$this->m_aArgs = $aArgs;
+ $this->m_iLimitCount = $iLimitCount;
+ $this->m_iLimitStart = $iLimitStart;
$this->m_bLoaded = false;
$this->m_aData = array(); // array of (row => array of (classalias) => object)
@@ -194,11 +196,33 @@ class DBObjectSet
return MetaModel::GetRootClass($this->GetClass());
}
+ public function SetLimit($iLimitCount, $iLimitStart = 0)
+ {
+ $this->m_iLimitCount = $iLimitCount;
+ $this->m_iLimitStart = $iLimitStart;
+ }
+
+ public function GetLimitCount()
+ {
+ return $this->m_iLimitCount;
+ }
+
+ public function GetLimitStart()
+ {
+ return $this->m_iLimitStart;
+ }
+
public function Load()
{
if ($this->m_bLoaded) return;
-
- $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs);
+ if ($this->m_iLimitCount > 0)
+ {
+ $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs, $this->m_iLimitCount, $this->m_iLimitStart);
+ }
+ else
+ {
+ $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs);
+ }
$resQuery = CMDBSource::Query($sSQL);
if (!$resQuery) return;
@@ -220,8 +244,13 @@ class DBObjectSet
public function Count()
{
- if (!$this->m_bLoaded) $this->Load();
- return count($this->m_aData);
+ $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs, 0, 0, true);
+ $resQuery = CMDBSource::Query($sSQL);
+ if (!$resQuery) return 0;
+
+ $aRow = CMDBSource::FetchArray($resQuery);
+ CMDBSource::FreeResult($resQuery);
+ return $aRow['COUNT'];
}
public function Fetch($sClassAlias = '')
diff --git a/core/kpi.class.inc.php b/core/kpi.class.inc.php
index ade2c6464..6822c94e9 100644
--- a/core/kpi.class.inc.php
+++ b/core/kpi.class.inc.php
@@ -47,34 +47,50 @@ class ExecutionKPI
{
foreach (self::$m_aStats as $sOperation => $aOpStats)
{
- echo "====================
\n";
- echo "KPIs for $sOperation
\n";
- echo "====================
\n";
+ echo "
'.$aQueryData['count'].'
'; - echo 'Example: '.$aQueryData['sql'][0].'
'; + echo "Trace activated, but no query found
\n"; + return; + } + + $iSqlCount = 0; + foreach (self::$m_aQueriesLog as $aOqlData) + { + $iSqlCount += $aOqlData['hits']; + } + echo "$sHits hits for OQL query: $sOql
\n"; + echo "Count of executed queries: $iTotal
"; - echo "Count of built queries: ".count(self::$m_aQueriesLog)."
"; } public static function MakeDeleteQuery(DBObjectSearch $oFilter, $aArgs = array()) @@ -3211,6 +3248,9 @@ abstract class MetaModel ExecutionKPI::EnableMemory(); } + self::$m_bTraceQueries = self::$m_oConfig->GetDebugQueries(); + self::$m_bQueryCacheEnabled = self::$m_oConfig->GetQueryCacheEnabled(); + // Note: load the dictionary as soon as possible, because it might be // needed when some error occur foreach (self::$m_oConfig->GetDictionaries() as $sModule => $sToInclude) diff --git a/core/sqlquery.class.inc.php b/core/sqlquery.class.inc.php index 36daf2c50..e7b9ae5a9 100644 --- a/core/sqlquery.class.inc.php +++ b/core/sqlquery.class.inc.php @@ -238,7 +238,7 @@ class SQLQuery } // Interface, build the SQL query - public function RenderSelect($aOrderBy = array(), $aArgs = array()) + public function RenderSelect($aOrderBy = array(), $aArgs = array(), $iLimitCount = 0, $iLimitStart = 0, $bGetCount = false) { // The goal will be to complete the lists as we build the Joins $aFrom = array(); @@ -248,15 +248,31 @@ class SQLQuery $aSetValues = array(); $this->privRender($aFrom, $aFields, $oCondition, $aDelTables, $aSetValues); - $sSelect = self::ClauseSelect($aFields); $sFrom = self::ClauseFrom($aFrom); $sWhere = self::ClauseWhere($oCondition, $aArgs); - $sOrderBy = self::ClauseOrderBy($aOrderBy); - if (!empty($sOrderBy)) + if ($bGetCount) { - $sOrderBy = "ORDER BY $sOrderBy"; + $sSQL = "SELECT COUNT(*) AS COUNT FROM $sFrom WHERE $sWhere"; } - return "SELECT DISTINCT $sSelect FROM $sFrom WHERE $sWhere $sOrderBy"; + else + { + $sSelect = self::ClauseSelect($aFields); + $sOrderBy = self::ClauseOrderBy($aOrderBy); + if (!empty($sOrderBy)) + { + $sOrderBy = "ORDER BY $sOrderBy"; + } + if ($iLimitCount > 0) + { + $sLimit = 'LIMIT '.$iLimitStart.', '.$iLimitCount; + } + else + { + $sLimit = ''; + } + $sSQL = "SELECT DISTINCT $sSelect FROM $sFrom WHERE $sWhere $sOrderBy $sLimit"; + } + return $sSQL; } private static function ClauseSelect($aFields)