From b423e98295827c4cae8da9a47e912e199c9a6623 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 30 Mar 2011 08:30:42 +0000 Subject: [PATCH] Optimizations: - Setup: grouped CREATE TABLE / ALTER TABLE statements in one single CREATE table - Every page: cache the prepared queries and data model into APC Cleanup: removed unused verb RegisterPlugin Fix: GetObject could fail (could not find the reference from within the forum) SVN:trunk[1154] --- .../userrightsprofile.class.inc.php | 1 - .../userrightsprojection.class.inc.php | 3 +- core/dict.class.inc.php | 21 +- core/metamodel.class.php | 328 +++++++++++++----- core/sqlquery.class.inc.php | 11 + 5 files changed, 260 insertions(+), 104 deletions(-) diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php index c6c2091bb..03d391170 100644 --- a/addons/userrights/userrightsprofile.class.inc.php +++ b/addons/userrights/userrightsprofile.class.inc.php @@ -509,7 +509,6 @@ class UserRightsProfile extends UserRightsAddOnAPI public function Init() { - MetaModel::RegisterPlugin('userrights', 'ACbyProfile'); } diff --git a/addons/userrights/userrightsprojection.class.inc.php b/addons/userrights/userrightsprojection.class.inc.php index eef9e297c..408bf478d 100644 --- a/addons/userrights/userrightsprojection.class.inc.php +++ b/addons/userrights/userrightsprojection.class.inc.php @@ -660,7 +660,8 @@ class UserRightsProjection extends UserRightsAddOnAPI public function Init() { - MetaModel::RegisterPlugin('userrights', 'ACbyProfile', array($this, 'CacheData')); + // CacheData to be invoked in a module extension + //MetaModel::RegisterPlugin('userrights', 'ACbyProfile', array($this, 'CacheData')); } protected $m_aDimensions = array(); // id -> object diff --git a/core/dict.class.inc.php b/core/dict.class.inc.php index 0b8c87fb6..02c43a4c3 100644 --- a/core/dict.class.inc.php +++ b/core/dict.class.inc.php @@ -232,21 +232,21 @@ class Dict MyHelpers::var_dump_html(self::$m_aData); } - public static function InCache() + public static function InCache($sApplicationPrefix) { if (function_exists('apc_fetch')) { $bResult = false; // Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter // - self::$m_aData = apc_fetch('dict'); + self::$m_aData = apc_fetch($sApplicationPrefix.'-dict'); if (is_bool(self::$m_aData) && (self::$m_aData === false)) { self::$m_aData = array(); } else { - self::$m_aLanguages = apc_fetch('languages'); + self::$m_aLanguages = apc_fetch($sApplicationPrefix.'-languages'); if (is_bool(self::$m_aLanguages) && (self::$m_aLanguages === false)) { self::$m_aLanguages = array(); @@ -261,12 +261,21 @@ class Dict return false; } - public static function InitCache() + public static function InitCache($sApplicationPrefix) { if (function_exists('apc_store')) { - apc_store('languages', self::$m_aLanguages); - apc_store('dict', self::$m_aData); + apc_store($sApplicationPrefix.'-languages', self::$m_aLanguages); + apc_store($sApplicationPrefix.'-dict', self::$m_aData); + } + } + + public static function ResetCache($sApplicationPrefix) + { + if (function_exists('apc_delete')) + { + apc_delete($sApplicationPrefix.'-languages'); + apc_delete($sApplicationPrefix.'-dict'); } } } diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 8e2cb95be..a450d976c 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -538,7 +538,7 @@ abstract class MetaModel final static protected function DBEnumTables() { - // This API do not rely on our capability to query the DB and retrieve + // This API does not rely on our capability to query the DB and retrieve // the list of existing tables // Rather, it uses the list of expected tables, corresponding to the data model $aTables = array(); @@ -1277,6 +1277,31 @@ abstract class MetaModel // } //} } + + // Build the list of available extensions + // + $aInterfaces = array('iApplicationUIExtension', 'iApplicationObjectExtension'); + foreach($aInterfaces as $sInterface) + { + self::$m_aExtensionClasses[$sInterface] = array(); + } + + foreach(get_declared_classes() as $sPHPClass) + { + $oRefClass = new ReflectionClass($sPHPClass); + $oExtensionInstance = null; + foreach($aInterfaces as $sInterface) + { + if ($oRefClass->implementsInterface($sInterface)) + { + if (is_null($oExtensionInstance)) + { + $oExtensionInstance = new $sPHPClass; + } + self::$m_aExtensionClasses[$sInterface][] = $oExtensionInstance; + } + } + } } // To be overriden, must be called for any object class (optimization) @@ -1782,6 +1807,22 @@ abstract class MetaModel // hit! $oSelect = clone self::$m_aQueryStructCache[$sOqlId]; } + elseif (function_exists('apc_fetch')) + { + // Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter + // + $sAppIdentity = self::GetConfig()->Get('session_name'); + $sOqlAPCCacheId = $sAppIdentity.'-query-cache-'.$sOqlId; + $oKPI = new ExecutionKPI(); + $result = apc_fetch($sOqlAPCCacheId); + $oKPI->ComputeStats('Query APC (fetch)', $sOqlQuery); + + if (is_object($result)) + { + $oSelect = $result; + self::$m_aQueryStructCache[$sOqlId] = $oSelect; + } + } } if (!isset($oSelect)) @@ -1792,9 +1833,20 @@ abstract class MetaModel $oKPI = new ExecutionKPI(); $oSelect = self::MakeQuery($oFilter->GetSelectedClasses(), $oQBExpr, $aClassAliases, $aTableAliases, $oFilter, array(), true /* main query */); + $oSelect->SetSourceOQL($sOqlQuery); $oKPI->ComputeStats('MakeQuery (select)', $sOqlQuery); - self::$m_aQueryStructCache[$sOqlId] = clone $oSelect; + if (self::$m_bQueryCacheEnabled) + { + if (function_exists('apc_store')) + { + $oKPI = new ExecutionKPI(); + apc_store($sOqlAPCCacheId, $oSelect); + $oKPI->ComputeStats('Query APC (store)', $sOqlQuery); + } + + self::$m_aQueryStructCache[$sOqlId] = clone $oSelect; + } } // Check the order by specification, and prefix with the class alias @@ -2697,26 +2749,13 @@ abstract class MetaModel protected static function DBCreateTables() { - list($aErrors, $aSugFix) = self::DBCheckFormat(); + list($aErrors, $aSugFix, $aCondensedQueries) = self::DBCheckFormat(); - $aSQL = array(); - foreach ($aSugFix as $sClass => $aTarget) + //$sSQL = implode('; ', $aCondensedQueries); Does not work - multiple queries not allowed + foreach($aCondensedQueries as $sQuery) { - foreach ($aTarget as $aQueries) - { - foreach ($aQueries as $sQuery) - { - if (!empty($sQuery)) - { - //$aSQL[] = $sQuery; - // forces a refresh of cached information - CMDBSource::CreateTable($sQuery); - } - } - } + CMDBSource::CreateTable($sQuery); } - // does not work -how to have multiple statements in a single query? - // $sDoCreateAll = implode(" ; ", $aSQL); } protected static function DBCreateViews() @@ -2906,6 +2945,12 @@ abstract class MetaModel { $aErrors = array(); $aSugFix = array(); + + // A new way of representing things to be done - quicker to execute ! + $aCreateTable = array(); // array of =>
+ $aCreateTableItems = array(); // array of
=> array of + $aAlterTableItems = array(); // array of
=> + foreach (self::GetClasses() as $sClass) { if (!self::HasTable($sClass)) continue; @@ -2915,17 +2960,24 @@ abstract class MetaModel $sTable = self::DBGetTable($sClass); $sKeyField = self::DBGetKey($sClass); $sAutoIncrement = (self::IsAutoIncrementKey($sClass) ? "AUTO_INCREMENT" : ""); + $sKeyFieldDefinition = "`$sKeyField` INT(11) NOT NULL $sAutoIncrement PRIMARY KEY"; if (!CMDBSource::IsTable($sTable)) { $aErrors[$sClass]['*'][] = "table '$sTable' could not be found into the DB"; - $aSugFix[$sClass]['*'][] = "CREATE TABLE `$sTable` (`$sKeyField` INT(11) NOT NULL $sAutoIncrement PRIMARY KEY) ENGINE = ".MYSQL_ENGINE." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $aSugFix[$sClass]['*'][] = "CREATE TABLE `$sTable` ($sKeyFieldDefinition) ENGINE = ".MYSQL_ENGINE." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $aCreateTable[$sTable] = "ENGINE = ".MYSQL_ENGINE." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $aCreateTableItems[$sTable][$sKeyField] = $sKeyFieldDefinition; } // Check that the key field exists // elseif (!CMDBSource::IsField($sTable, $sKeyField)) { $aErrors[$sClass]['id'][] = "key '$sKeyField' (table $sTable) could not be found"; - $aSugFix[$sClass]['id'][] = "ALTER TABLE `$sTable` ADD `$sKeyField` INT(11) NOT NULL $sAutoIncrement PRIMARY KEY"; + $aSugFix[$sClass]['id'][] = "ALTER TABLE `$sTable` ADD $sKeyFieldDefinition"; + if (!array_key_exists($sTable, $aCreateTable)) + { + $aAlterTableItems[$sTable][$sKeyField] = "ADD $sKeyFieldDefinition"; + } } else { @@ -2935,11 +2987,19 @@ abstract class MetaModel { $aErrors[$sClass]['id'][] = "key '$sKeyField' is not a key for table '$sTable'"; $aSugFix[$sClass]['id'][] = "ALTER TABLE `$sTable`, DROP PRIMARY KEY, ADD PRIMARY key(`$sKeyField`)"; + if (!array_key_exists($sTable, $aCreateTable)) + { + $aAlterTableItems[$sTable][$sKeyField] = "CHANGE `$sKeyField` $sKeyFieldDefinition"; + } } if (self::IsAutoIncrementKey($sClass) && !CMDBSource::IsAutoIncrement($sTable, $sKeyField)) { $aErrors[$sClass]['id'][] = "key '$sKeyField' (table $sTable) is not automatically incremented"; - $aSugFix[$sClass]['id'][] = "ALTER TABLE `$sTable` CHANGE `$sKeyField` `$sKeyField` INT(11) NOT NULL AUTO_INCREMENT"; + $aSugFix[$sClass]['id'][] = "ALTER TABLE `$sTable` CHANGE `$sKeyField` $sKeyFieldDefinition"; + if (!array_key_exists($sTable, $aCreateTable)) + { + $aAlterTableItems[$sTable][$sKeyField] = "CHANGE `$sKeyField` $sKeyFieldDefinition"; + } } } @@ -2955,15 +3015,31 @@ abstract class MetaModel foreach($oAttDef->GetSQLColumns() as $sField => $sDBFieldType) { $bIndexNeeded = $oAttDef->RequiresIndex(); - $sFieldSpecs = $oAttDef->IsNullAllowed() ? "$sDBFieldType NULL" : "$sDBFieldType NOT NULL"; + $sFieldDefinition = "`$sField` ".($oAttDef->IsNullAllowed() ? "$sDBFieldType NULL" : "$sDBFieldType NOT NULL"); if (!CMDBSource::IsField($sTable, $sField)) { $aErrors[$sClass][$sAttCode][] = "field '$sField' could not be found in table '$sTable'"; - $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` ADD `$sField` $sFieldSpecs"; + $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` ADD $sFieldDefinition"; if ($bIndexNeeded) { $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` ADD INDEX (`$sField`)"; } + if (array_key_exists($sTable, $aCreateTable)) + { + $aCreateTableItems[$sTable][$sField] = $sFieldDefinition; + if ($bIndexNeeded) + { + $aCreateTableItems[$sTable][$sField.'_ix'] = "INDEX (`$sField`)"; + } + } + else + { + $aAlterTableItems[$sTable][$sField] = "ADD $sFieldDefinition"; + if ($bIndexNeeded) + { + $aAlterTableItems[$sTable][$sField.'_ix'] = "ADD INDEX (`$sField`)"; + } + } } else { @@ -2990,7 +3066,8 @@ abstract class MetaModel } if ($bToBeChanged) { - $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` CHANGE `$sField` `$sField` $sFieldSpecs"; + $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` CHANGE `$sField` $sFieldDefinition"; + $aAlterTableItems[$sTable][$sField] = "CHANGE `$sField` $sFieldDefinition"; } // Create indexes (external keys only... so far) @@ -2999,12 +3076,26 @@ abstract class MetaModel { $aErrors[$sClass][$sAttCode][] = "Foreign key '$sField' in table '$sTable' should have an index"; $aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` ADD INDEX (`$sField`)"; + $aAlterTableItems[$sTable][$sField.'_ix'] = "ADD INDEX (`$sField`)"; } } } } } - return array($aErrors, $aSugFix); + + $aCondensedQueries = array(); + foreach($aCreateTable as $sTable => $sTableOptions) + { + $sTableItems = implode(', ', $aCreateTableItems[$sTable]); + $aCondensedQueries[] = "CREATE TABLE `$sTable` ($sTableItems) $sTableOptions"; + } + foreach($aAlterTableItems as $sTable => $aChangeList) + { + $sChangeList = implode(', ', $aChangeList); + $aCondensedQueries[] = "ALTER TABLE `$sTable` $sChangeList"; + } + + return array($aErrors, $aSugFix, $aCondensedQueries); } public static function DBCheckViews() @@ -3462,37 +3553,10 @@ abstract class MetaModel { self::LoadConfig($sConfigFile); - $aInterfaces = array('iApplicationUIExtension', 'iApplicationObjectExtension'); - foreach($aInterfaces as $sInterface) - { - self::$m_aExtensionClasses[$sInterface] = array(); - } - - foreach(get_declared_classes() as $sPHPClass) - { - $oRefClass = new ReflectionClass($sPHPClass); - $oExtensionInstance = null; - foreach($aInterfaces as $sInterface) - { - if ($oRefClass->implementsInterface($sInterface)) - { - if (is_null($oExtensionInstance)) - { - $oExtensionInstance = new $sPHPClass; - } - self::$m_aExtensionClasses[$sInterface][] = $oExtensionInstance; - } - } - } - if ($bModelOnly) return; CMDBSource::SelectDB(self::$m_sDBName); - // Some of the init could not be done earlier (requiring classes to be declared and DB to be accessible) - // To be deprecated - self::InitPlugins(); - foreach(get_declared_classes() as $sPHPClass) { if (is_subclass_of($sPHPClass, 'ModuleHandlerAPI')) @@ -3550,13 +3614,14 @@ abstract class MetaModel // Note: load the dictionary as soon as possible, because it might be // needed when some error occur - if (!Dict::InCache()) + $sAppIdentity = self::GetConfig()->Get('session_name'); + if (!Dict::InCache($sAppIdentity)) { foreach (self::$m_oConfig->GetDictionaries() as $sModule => $sToInclude) { - self::Plugin($sConfigFile, 'dictionaries', $sToInclude); + self::IncludeModule($sConfigFile, 'dictionaries', $sToInclude); } - Dict::InitCache(); + Dict::InitCache($sAppIdentity); } // Set the language... after the dictionaries have been loaded! Dict::SetDefaultLanguage(self::$m_oConfig->GetDefaultLanguage()); @@ -3567,19 +3632,19 @@ abstract class MetaModel foreach (self::$m_oConfig->GetAppModules() as $sModule => $sToInclude) { - self::Plugin($sConfigFile, 'application', $sToInclude); + self::IncludeModule($sConfigFile, 'application', $sToInclude); } foreach (self::$m_oConfig->GetDataModels() as $sModule => $sToInclude) { - self::Plugin($sConfigFile, 'business', $sToInclude); + self::IncludeModule($sConfigFile, 'business', $sToInclude); } foreach (self::$m_oConfig->GetWebServiceCategories() as $sModule => $sToInclude) { - self::Plugin($sConfigFile, 'webservice', $sToInclude); + self::IncludeModule($sConfigFile, 'webservice', $sToInclude); } foreach (self::$m_oConfig->GetAddons() as $sModule => $sToInclude) { - self::Plugin($sConfigFile, 'addons', $sToInclude); + self::IncludeModule($sConfigFile, 'addons', $sToInclude); } $sServer = self::$m_oConfig->GetDBHost(); @@ -3590,13 +3655,76 @@ abstract class MetaModel $sCharacterSet = self::$m_oConfig->GetDBCharacterSet(); $sCollation = self::$m_oConfig->GetDBCollation(); - $oKPI = new ExecutionKPI(); + if (function_exists('apc_fetch')) + { + $oKPI = new ExecutionKPI(); + // Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter + // + $sAppIdentity = self::GetConfig()->Get('session_name'); + $sOqlAPCCacheId = $sAppIdentity.'-metamodel'; + $result = apc_fetch($sOqlAPCCacheId); - // The include have been included, let's browse the existing classes and - // develop some data based on the proposed model - self::InitClasses($sTablePrefix); + if (is_array($result)) + { + // todo - verifier que toutes les classes mentionnees ici sont chargees dans InitClasses() + self::$m_aExtensionClasses = $result['m_aExtensionClasses']; + self::$m_Category2Class = $result['m_Category2Class']; + self::$m_aRootClasses = $result['m_aRootClasses']; + self::$m_aParentClasses = $result['m_aParentClasses']; + self::$m_aChildClasses = $result['m_aChildClasses']; + self::$m_aClassParams = $result['m_aClassParams']; + self::$m_aAttribDefs = $result['m_aAttribDefs']; + self::$m_aAttribOrigins = $result['m_aAttribOrigins']; + self::$m_aExtKeyFriends = $result['m_aExtKeyFriends']; + self::$m_aIgnoredAttributes = $result['m_aIgnoredAttributes']; + self::$m_aFilterDefs = $result['m_aFilterDefs']; + self::$m_aFilterOrigins = $result['m_aFilterOrigins']; + self::$m_aListInfos = $result['m_aListInfos']; + self::$m_aListData = $result['m_aListData']; + self::$m_aRelationInfos = $result['m_aRelationInfos']; + self::$m_aStates = $result['m_aStates']; + self::$m_aStimuli = $result['m_aStimuli']; + self::$m_aTransitions = $result['m_aTransitions']; + } + $oKPI->ComputeAndReport('Metamodel APC (fetch + read)'); + } - $oKPI->ComputeAndReport('Initialization of Data model structures'); + if (count(self::$m_aAttribDefs) == 0) + { + // The includes have been included, let's browse the existing classes and + // develop some data based on the proposed model + $oKPI = new ExecutionKPI(); + + self::InitClasses($sTablePrefix); + + $oKPI->ComputeAndReport('Initialization of Data model structures'); + if (function_exists('apc_store')) + { + $oKPI = new ExecutionKPI(); + + $aCache = array(); + $aCache['m_aExtensionClasses'] = self::$m_aExtensionClasses; + $aCache['m_Category2Class'] = self::$m_Category2Class; + $aCache['m_aRootClasses'] = self::$m_aRootClasses; // array of "classname" => "rootclass" + $aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass") + $aCache['m_aChildClasses'] = self::$m_aChildClasses; // array of ("classname" => array of "childclass") + $aCache['m_aClassParams'] = self::$m_aClassParams; // array of ("classname" => array of class information) + $aCache['m_aAttribDefs'] = self::$m_aAttribDefs; // array of ("classname" => array of attributes) + $aCache['m_aAttribOrigins'] = self::$m_aAttribOrigins; // array of ("classname" => array of ("attcode"=>"sourceclass")) + $aCache['m_aExtKeyFriends'] = self::$m_aExtKeyFriends; // array of ("classname" => array of ("indirect ext key attcode"=> array of ("relative ext field"))) + $aCache['m_aIgnoredAttributes'] = self::$m_aIgnoredAttributes; //array of ("classname" => array of ("attcode") + $aCache['m_aFilterDefs'] = self::$m_aFilterDefs; // array of ("classname" => array filterdef) + $aCache['m_aFilterOrigins'] = self::$m_aFilterOrigins; // array of ("classname" => array of ("attcode"=>"sourceclass")) + $aCache['m_aListInfos'] = self::$m_aListInfos; // array of ("listcode" => various info on the list, common to every classes) + $aCache['m_aListData'] = self::$m_aListData; // array of ("classname" => array of "listcode" => list) + $aCache['m_aRelationInfos'] = self::$m_aRelationInfos; // array of ("relcode" => various info on the list, common to every classes) + $aCache['m_aStates'] = self::$m_aStates; // array of ("classname" => array of "statecode"=>array('label'=>..., attribute_inherit=> attribute_list=>...)) + $aCache['m_aStimuli'] = self::$m_aStimuli; // array of ("classname" => array of ("stimuluscode"=>array('label'=>...))) + $aCache['m_aTransitions'] = self::$m_aTransitions; // array of ("classname" => array of ("statcode_from"=>array of ("stimuluscode" => array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD))) + apc_store($sOqlAPCCacheId, $aCache); + $oKPI->ComputeAndReport('Metamodel APC (store)'); + } + } self::$m_sDBName = $sSource; self::$m_sTablePrefix = $sTablePrefix; @@ -3617,16 +3745,7 @@ abstract class MetaModel protected static $m_aExtensionClasses = array(); - protected static $m_aPlugins = array(); - public static function RegisterPlugin($sType, $sName, $aInitCallSpec = array()) - { - self::$m_aPlugins[$sName] = array( - 'type' => $sType, - 'init' => $aInitCallSpec, - ); - } - - protected static function Plugin($sConfigFile, $sModuleType, $sToInclude) + protected static function IncludeModule($sConfigFile, $sModuleType, $sToInclude) { $sFirstChar = substr($sToInclude, 0, 1); $sSecondChar = substr($sToInclude, 1, 1); @@ -3656,24 +3775,6 @@ abstract class MetaModel require_once($sFile); } - // #@# to be deprecated! - // - protected static function InitPlugins() - { - foreach(self::$m_aPlugins as $sName => $aData) - { - $aCallSpec = @$aData['init']; - if (count($aCallSpec) == 2) - { - if (!is_callable($aCallSpec)) - { - throw new CoreException('Wrong declaration in plugin', array('plugin' => $aData['name'], 'type' => $aData['type'], 'class' => $aData['class'], 'init' => $aData['init'])); - } - call_user_func($aCallSpec); - } - } - } - // Building an object // // @@ -3698,8 +3799,8 @@ abstract class MetaModel // NOTE: Quick and VERY dirty caching mechanism which relies on // the fact that the string '987654321' will never appear in the // standard query - // This will be replaced for sure with a prepared statement - // or a view... next optimization to come! + // This could be simplified a little, relying solely on the query cache, + // but this would slow down -by how much time?- the application $oFilter = new DBObjectSearch($sClass); $oFilter->AddCondition('id', 987654321, '='); if ($bAllowAllData) @@ -3717,7 +3818,7 @@ abstract class MetaModel self::$aQueryCacheGetObjectHits[$sClass] += 1; // echo " -load $sClass/$iKey- ".self::$aQueryCacheGetObjectHits[$sClass]."
\n"; } - $sSQL = str_replace('987654321', CMDBSource::Quote($iKey), $sSQL); + $sSQL = str_replace(CMDBSource::Quote(987654321), CMDBSource::Quote($iKey), $sSQL); $res = CMDBSource::Query($sSQL); $aRow = CMDBSource::FetchArray($res); @@ -4021,6 +4122,41 @@ abstract class MetaModel return array(); } } + + public static function GetCacheEntries() + { + if (!function_exists('apc_cache_info')) return array(); + + $aCacheUserData = apc_cache_info('user'); + $sAppIdentity = MetaModel::GetConfig()->Get('session_name'); + $sPrefix = $sAppIdentity.'-'; + + $aEntries = array(); + foreach($aCacheUserData['cache_list'] as $i => $aEntry) + { + $sEntryKey = $aEntry['info']; + if (strpos($sEntryKey, $sPrefix) === 0) + { + $sCleanKey = substr($sEntryKey, strlen($sPrefix)); + $aEntries[$sCleanKey] = $aEntry; + } + } + return $aEntries; + } + + public static function ResetCache() + { + if (!function_exists('apc_delete')) return; + + $sAppIdentity = MetaModel::GetConfig()->Get('session_name'); + Dict::ResetCache($sAppIdentity); + + foreach(self::GetCacheEntries() as $sKey => $aAPCInfo) + { + $sAPCKey = $aAPCInfo['info']; + apc_delete($sAPCKey); + } + } } // class MetaModel diff --git a/core/sqlquery.class.inc.php b/core/sqlquery.class.inc.php index 22605d711..8a2b26051 100644 --- a/core/sqlquery.class.inc.php +++ b/core/sqlquery.class.inc.php @@ -37,6 +37,7 @@ require_once('cmdbsource.class.inc.php'); class SQLQuery { + private $m_SourceOQL = ''; private $m_sTable = ''; private $m_sTableAlias = ''; private $m_aFields = array(); @@ -69,6 +70,16 @@ class SQLQuery $this->m_oSelectedIdField = $oSelectedIdField; } + public function SetSourceOQL($sOQL) + { + $this->m_SourceOQL = $sOQL; + } + + public function GetSourceOQL() + { + return $this->m_SourceOQL; + } + public function DisplayHtml() { if (count($this->m_aFields) == 0) $sFields = "";