mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
#965 Since 2.0.3, for each synchronized object, around 100 queries are performed (2 are required), and this is multiplied be the number of duplicate replicas (then resulting in a significant slowdown).
SVN:trunk[3380]
This commit is contained in:
@@ -125,27 +125,29 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
|
||||
// Master data sources
|
||||
$sSynchroIcon = '';
|
||||
$oReplicaSet = $this->GetMasterReplica();
|
||||
$bSynchronized = false;
|
||||
$oCreatorTask = null;
|
||||
$bCanBeDeletedByTask = false;
|
||||
$bCanBeDeletedByUser = true;
|
||||
$aMasterSources = array();
|
||||
if ($oReplicaSet->Count() > 0)
|
||||
$aSyncData = $this->GetSynchroData();
|
||||
if (count($aSyncData) > 0)
|
||||
{
|
||||
$bSynchronized = true;
|
||||
while($aData = $oReplicaSet->FetchAssoc())
|
||||
foreach ($aSyncData as $iSourceId => $aSourceData)
|
||||
{
|
||||
// Assumption: $aData['datasource'] will not be null because the data source id is always set...
|
||||
$sApplicationURL = $aData['datasource']->GetApplicationUrl($this, $aData['replica']);
|
||||
$sLink = $aData['datasource']->GetName();
|
||||
$oDataSource = $aSourceData['source'];
|
||||
$oReplica = reset($aSourceData['replica']); // Take the first one!
|
||||
|
||||
$sApplicationURL = $oDataSource->GetApplicationUrl($this, $oReplica);
|
||||
$sLink = $oDataSource->GetName();
|
||||
if (!empty($sApplicationURL))
|
||||
{
|
||||
$sLink = "<a href=\"$sApplicationURL\" target=\"_blank\">".$aData['datasource']->GetName()."</a>";
|
||||
$sLink = "<a href=\"$sApplicationURL\" target=\"_blank\">".$oDataSource->GetName()."</a>";
|
||||
}
|
||||
if ($aData['replica']->Get('status_dest_creator') == 1)
|
||||
if ($oReplica->Get('status_dest_creator') == 1)
|
||||
{
|
||||
$oCreatorTask = $aData['datasource'];
|
||||
$oCreatorTask = $oDataSource;
|
||||
$bCreatedByTask = true;
|
||||
}
|
||||
else
|
||||
@@ -154,12 +156,12 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
}
|
||||
if ($bCreatedByTask)
|
||||
{
|
||||
$sDeletePolicy = $aData['datasource']->Get('delete_policy');
|
||||
$sDeletePolicy = $oDataSource->Get('delete_policy');
|
||||
if (($sDeletePolicy == 'delete') || ($sDeletePolicy == 'update_then_delete'))
|
||||
{
|
||||
$bCanBeDeletedByTask = true;
|
||||
}
|
||||
$sUserDeletePolicy = $aData['datasource']->Get('user_delete_policy');
|
||||
$sUserDeletePolicy = $oDataSource->Get('user_delete_policy');
|
||||
if ($sUserDeletePolicy == 'nobody')
|
||||
{
|
||||
$bCanBeDeletedByUser = false;
|
||||
@@ -172,9 +174,9 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
{
|
||||
}
|
||||
}
|
||||
$aMasterSources[$aData['datasource']->GetKey()]['datasource'] = $aData['datasource'];
|
||||
$aMasterSources[$aData['datasource']->GetKey()]['url'] = $sLink;
|
||||
$aMasterSources[$aData['datasource']->GetKey()]['last_synchro'] = $aData['replica']->Get('status_last_seen');
|
||||
$aMasterSources[$iSourceId]['datasource'] = $oDataSource;
|
||||
$aMasterSources[$iSourceId]['url'] = $sLink;
|
||||
$aMasterSources[$iSourceId]['last_synchro'] = $oReplica->Get('status_last_seen');
|
||||
}
|
||||
|
||||
if (is_object($oCreatorTask))
|
||||
@@ -1402,6 +1404,8 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$sHtml .= "<p>\n";
|
||||
$aFilterCriteria = $oSet->GetFilter()->GetCriteria();
|
||||
$aMapCriteria = array();
|
||||
// Todo: Investigate... The search criteria is an expression, i.e. a tree!
|
||||
// I wonder if that code could work... cleanup required/recommended
|
||||
foreach($aFilterCriteria as $aCriteria)
|
||||
{
|
||||
$aMapCriteria[$aCriteria['filtercode']][] = array('value' => $aCriteria['value'], 'opcode' => $aCriteria['opcode']);
|
||||
@@ -1429,6 +1433,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$sFilterValue = $aMapCriteria[$sFilterCode][0]['value'];
|
||||
$sFilterOpCode = $aMapCriteria[$sFilterCode][0]['opcode'];
|
||||
}
|
||||
// Todo: Investigate...
|
||||
if ($sFilterCode != 'company')
|
||||
{
|
||||
$oUnlimitedFilter->AddCondition($sFilterCode, $sFilterValue, $sFilterOpCode);
|
||||
|
||||
@@ -94,7 +94,7 @@ abstract class DBObject implements iDisplay
|
||||
private $m_bFullyLoaded = false; // Compound objects can be partially loaded
|
||||
private $m_aLoadedAtt = array(); // Compound objects can be partially loaded, array of sAttCode
|
||||
protected $m_aModifiedAtt = array(); // list of (potentially) modified sAttCodes
|
||||
protected $m_oMasterReplicaSet = null; // Set of SynchroReplica related to this object
|
||||
protected $m_aSynchroData = null; // Set of Synch data related to this object
|
||||
protected $m_sHighlightCode = null;
|
||||
|
||||
// Use the MetaModel::NewObject to build an object (do we have to force it?)
|
||||
@@ -1178,48 +1178,45 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
if ($this->InSyncScope())
|
||||
{
|
||||
$oReplicaSet = $this->GetMasterReplica();
|
||||
if ($oReplicaSet->Count() > 0)
|
||||
|
||||
foreach ($this->GetSynchroData() as $iSourceId => $aSourceData)
|
||||
{
|
||||
while($aData = $oReplicaSet->FetchAssoc())
|
||||
foreach ($aSourceData['replica'] as $oReplica)
|
||||
{
|
||||
$oDataSource = $aData['datasource'];
|
||||
$oReplica = $aData['replica'];
|
||||
|
||||
$oDeletionPlan->AddToDelete($oReplica, DEL_SILENT);
|
||||
}
|
||||
$oDataSource = $aSourceData['source'];
|
||||
if ($oDataSource->GetKey() == SynchroExecution::GetCurrentTaskId())
|
||||
{
|
||||
// The current task has the right to delete the object
|
||||
continue;
|
||||
}
|
||||
$oReplica = reset($aSourceData['replica']); // Take the first one
|
||||
if ($oReplica->Get('status_dest_creator') != 1)
|
||||
{
|
||||
// The object is not owned by the task
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($oDataSource->GetKey() == SynchroExecution::GetCurrentTaskId())
|
||||
{
|
||||
// The current task has the right to delete the object
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($oReplica->Get('status_dest_creator') != 1)
|
||||
{
|
||||
// The object is not owned by the task
|
||||
continue;
|
||||
}
|
||||
$sLink = $oDataSource->GetName();
|
||||
$sUserDeletePolicy = $oDataSource->Get('user_delete_policy');
|
||||
switch($sUserDeletePolicy)
|
||||
{
|
||||
case 'nobody':
|
||||
$this->m_aDeleteIssues[] = Dict::Format('Core:Synchro:TheObjectCannotBeDeletedByUser_Source', $sLink);
|
||||
break;
|
||||
|
||||
$sLink = $oDataSource->GetName();
|
||||
$sUserDeletePolicy = $oDataSource->Get('user_delete_policy');
|
||||
switch($sUserDeletePolicy)
|
||||
case 'administrators':
|
||||
if (!UserRights::IsAdministrator())
|
||||
{
|
||||
case 'nobody':
|
||||
$this->m_aDeleteIssues[] = Dict::Format('Core:Synchro:TheObjectCannotBeDeletedByUser_Source', $sLink);
|
||||
break;
|
||||
|
||||
case 'administrators':
|
||||
if (!UserRights::IsAdministrator())
|
||||
{
|
||||
$this->m_aDeleteIssues[] = Dict::Format('Core:Synchro:TheObjectCannotBeDeletedByUser_Source', $sLink);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'everybody':
|
||||
default:
|
||||
// Ok
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'everybody':
|
||||
default:
|
||||
// Ok
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2588,45 +2585,77 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
/**
|
||||
* WILL DEPRECATED SOON
|
||||
* Caching relying on an object set is not efficient since 2.0.3
|
||||
* Use GetSynchroData instead
|
||||
*
|
||||
* Get all the synchro replica related to this object
|
||||
* @param none
|
||||
* @return DBObjectSet Set with two columns: R=SynchroReplica S=SynchroDataSource
|
||||
*/
|
||||
public function GetMasterReplica()
|
||||
{
|
||||
if ($this->m_oMasterReplicaSet == null)
|
||||
$sOQL = "SELECT replica,datasource FROM SynchroReplica AS replica JOIN SynchroDataSource AS datasource ON replica.sync_source_id=datasource.id WHERE replica.dest_class = :dest_class AND replica.dest_id = :dest_id";
|
||||
$oReplicaSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array() /* order by*/, array('dest_class' => get_class($this), 'dest_id' => $this->GetKey()));
|
||||
return $oReplicaSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the synchro data related to this object
|
||||
* @param none
|
||||
* @return array of data_source_id => array
|
||||
* 'source' => $oSource,
|
||||
* 'attributes' => array of $oSynchroAttribute
|
||||
* 'replica' => array of $oReplica (though only one should exist, misuse of the data sync can have this consequence)
|
||||
*/
|
||||
public function GetSynchroData()
|
||||
{
|
||||
if ($this->m_aSynchroData == null)
|
||||
{
|
||||
//$aParentClasses = MetaModel::EnumParentClasses(get_class($this), ENUM_PARENT_CLASSES_ALL);
|
||||
//$sClassesList = "'".implode("','", $aParentClasses)."'";
|
||||
$sOQL = "SELECT replica,datasource FROM SynchroReplica AS replica JOIN SynchroDataSource AS datasource ON replica.sync_source_id=datasource.id WHERE replica.dest_class = :dest_class AND replica.dest_id = :dest_id";
|
||||
$oReplicaSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array() /* order by*/, array('dest_class' => get_class($this), 'dest_id' => $this->GetKey()));
|
||||
$this->m_oMasterReplicaSet = $oReplicaSet;
|
||||
$this->m_aSynchroData = array();
|
||||
while($aData = $oReplicaSet->FetchAssoc())
|
||||
{
|
||||
$iSourceId = $aData['datasource']->GetKey();
|
||||
if (!array_key_exists($iSourceId, $this->m_aSynchroData))
|
||||
{
|
||||
$aAttributes = array();
|
||||
$oAttrSet = $aData['datasource']->Get('attribute_list');
|
||||
while($oSyncAttr = $oAttrSet->Fetch())
|
||||
{
|
||||
$aAttributes[$oSyncAttr->Get('attcode')] = $oSyncAttr;
|
||||
}
|
||||
$this->m_aSynchroData[$iSourceId] = array(
|
||||
'source' => $aData['datasource'],
|
||||
'attributes' => $aAttributes,
|
||||
'replica' => array()
|
||||
);
|
||||
}
|
||||
// Assumption: $aData['datasource'] will not be null because the data source id is always set...
|
||||
$this->m_aSynchroData[$iSourceId]['replica'][] = $aData['replica'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_oMasterReplicaSet->Rewind();
|
||||
}
|
||||
return $this->m_oMasterReplicaSet;
|
||||
return $this->m_aSynchroData;
|
||||
}
|
||||
|
||||
public function GetSynchroReplicaFlags($sAttCode, &$aReason)
|
||||
{
|
||||
$iFlags = OPT_ATT_NORMAL;
|
||||
$oSet = $this->GetMasterReplica();
|
||||
while($aData = $oSet->FetchAssoc())
|
||||
foreach ($this->GetSynchroData() as $iSourceId => $aSourceData)
|
||||
{
|
||||
if ($aData['datasource']->GetKey() == SynchroExecution::GetCurrentTaskId())
|
||||
if ($iSourceId == SynchroExecution::GetCurrentTaskId())
|
||||
{
|
||||
// Ignore the current task (check to write => ok)
|
||||
continue;
|
||||
}
|
||||
// Assumption: $aData['datasource'] will not be null because the data source id is always set...
|
||||
$oReplica = $aData['replica'];
|
||||
$oSource = $aData['datasource'];
|
||||
$oAttrSet = $oSource->Get('attribute_list');
|
||||
while($oSyncAttr = $oAttrSet->Fetch())
|
||||
// Assumption: one replica - take the first one!
|
||||
$oReplica = reset($aSourceData['replica']);
|
||||
$oSource = $aSourceData['source'];
|
||||
if (array_key_exists($sAttCode, $aSourceData['attributes']))
|
||||
{
|
||||
if (($oSyncAttr->Get('attcode') == $sAttCode) && ($oSyncAttr->Get('update') == 1) && ($oSyncAttr->Get('update_policy') == 'master_locked'))
|
||||
$oSyncAttr = $aSourceData['attributes'][$sAttCode];
|
||||
if (($oSyncAttr->Get('update') == 1) && ($oSyncAttr->Get('update_policy') == 'master_locked'))
|
||||
{
|
||||
$iFlags |= OPT_ATT_SLAVE;
|
||||
$sUrl = $oSource->GetApplicationUrl($this, $oReplica);
|
||||
|
||||
Reference in New Issue
Block a user