Commit 98ecf66a authored by Sebastian Kummer's avatar Sebastian Kummer

ZO-28 Implement sync-one deletion of previousily available entry, delete

all invalid items at once in ClearAllNotCurrentChunkType(), separate
getting the hash field and the actual hashing of a GABEntry, GetGAB()
should not terminate if no entry is found.
parent 9b513386
...@@ -61,11 +61,15 @@ abstract class SyncWorker { ...@@ -61,11 +61,15 @@ abstract class SyncWorker {
// build the chunks // build the chunks
$chunks = array(); $chunks = array();
foreach ($gab as $entry) { foreach ($gab as $entry) {
$id = $this->calculateChunkId($entry); $key = $this->getHashFieldValue($entry);
// Ignore entries without the configured hash value. Warning is logged by getHashFieldValue().
if (!$key)
continue;
$id = $this->calculateChunkId($key);
if (!isset($chunks[$id])) { if (!isset($chunks[$id])) {
$chunks[$id] = array(); $chunks[$id] = array();
} }
$key = $entry->{$this->hashFieldId};
$chunks[$id][$key] = $entry; $chunks[$id][$key] = $entry;
} }
...@@ -124,17 +128,43 @@ abstract class SyncWorker { ...@@ -124,17 +128,43 @@ abstract class SyncWorker {
// search for the entry in the GAB // search for the entry in the GAB
$entries = $this->GetGAB($uniqueId); $entries = $this->GetGAB($uniqueId);
// if an entry is found, update the chunk
// if the entry is NOT found, we should remove it from the chunk (entry deleted)
if (isset($entries[0])) {
$entry = $entries[0]; $entry = $entries[0];
$key = $this->getHashFieldValue($entry);
if (!$key) {
$this->Terminate("SyncOne: Unique key can't be found in entry from GAB. Aborting.");
}
}
else {
$entry = false;
$key = $uniqueId;
}
// get the chunkId and the data // get the data for the chunkId
$chunkId = $this->calculateChunkId($entry);
$folderid = $this->getFolderId(); $folderid = $this->getFolderId();
$chunkId = $this->calculateChunkId($key);
$chunkdata = $this->GetChunkData($folderid, $chunkId); $chunkdata = $this->GetChunkData($folderid, $chunkId);
$chunk = json_decode($chunkdata, true); $chunk = json_decode($chunkdata, true);
// update the entry // update or remove the entry
$key = $entry->{$this->hashFieldId}; if ($entry) {
$chunk[$key] = $entry; $chunk[$key] = $entry;
$this->Log("Updating entry.");
}
else {
// if we have the key in the chunk, it existed before and should be deleted
if (isset($chunk[$key])) {
unset($chunk[$key]);
$this->Log("Deleting entry.");
}
// if we get here, the entry was not found in the GAB but also not in the chunk data. Invalid entry, abort!
else {
$this->Terminate(sprintf("No entry for '%s' can be found in GAB or hashed entries. Nothing to do here. Aborting.", $uniqueId));
}
}
// get the hash, sort the chunk and serialize it // get the hash, sort the chunk and serialize it
$amountEntries = count($chunk); $amountEntries = count($chunk);
...@@ -236,23 +266,32 @@ abstract class SyncWorker { ...@@ -236,23 +266,32 @@ abstract class SyncWorker {
} }
/** /**
* Calculates the chunk-id for a GABEntry. * Returns the configured hash field from the GABEntry.
* If it is not available the method returns false.
* *
* @param GABEntry $gabEntry * @param GABEntry $gabEntry
* *
* @access protected * @access protected
* @return boolean|number * @return string|boolean
*/ */
protected function calculateChunkId($gabEntry) { protected function getHashFieldValue($gabEntry) {
$value = false;
if (property_exists($gabEntry, $this->hashFieldId)) { if (property_exists($gabEntry, $this->hashFieldId)) {
$value = $gabEntry->{$this->hashFieldId}; return $gabEntry->{$this->hashFieldId};
} }
if (!$value) { else {
$this->Log("Calculate chunk-id: error, configured UNIQUEID is not set in GAB entry."); $this->Log("getHashFieldValue: error, configured UNIQUEID is not set in GAB entry.");
return false; return false;
} }
}
/**
* Calculated the chunk-id of a value.
*
* @parem string $value
* @access protected
* @return number
*/
protected function calculateChunkId($value) {
$hash = sprintf("%u", crc32($value)); $hash = sprintf("%u", crc32($value));
return fmod($hash, AMOUT_OF_CHUNKS); return fmod($hash, AMOUT_OF_CHUNKS);
} }
......
...@@ -170,19 +170,12 @@ class Zarafa extends SyncWorker { ...@@ -170,19 +170,12 @@ class Zarafa extends SyncWorker {
} }
else { else {
$this->Log(sprintf("Zarafa->ClearAllNotCurrentChunkType: found %d invalid items, deleting", $querycnt)); $this->Log(sprintf("Zarafa->ClearAllNotCurrentChunkType: found %d invalid items, deleting", $querycnt));
$deleted = 0; $entries = mapi_table_queryallrows($table, array(PR_ENTRYID, $this->mapiprops['chunktype']));
while($deleted <= $querycnt) {
$entries = mapi_table_queryrows($table, array(PR_ENTRYID, $this->mapiprops['chunktype']), $deleted, 20);
$entry_ids = array_reduce($entries, function ($result, $item) { $entry_ids = array_reduce($entries, function ($result, $item) {
$result[] = $item[PR_ENTRYID]; $result[] = $item[PR_ENTRYID];
return $result; return $result;
}, array()); }, array());
$toDelete = count($entry_ids);
if ($toDelete > 0) {
mapi_folder_deletemessages($folder, array_values($entry_ids)); mapi_folder_deletemessages($folder, array_values($entry_ids));
}
$deleted += $toDelete;
}
$this->Log("Zarafa->ClearAllNotCurrentChunkType: done"); $this->Log("Zarafa->ClearAllNotCurrentChunkType: done");
} }
$this->Log(""); $this->Log("");
...@@ -192,6 +185,7 @@ class Zarafa extends SyncWorker { ...@@ -192,6 +185,7 @@ class Zarafa extends SyncWorker {
/** /**
* Returns a list with all GAB entries or a single entry specified by $uniqueId. * Returns a list with all GAB entries or a single entry specified by $uniqueId.
* The search for that single entry is done using the configured UNIQUEID parameter. * The search for that single entry is done using the configured UNIQUEID parameter.
* If no entry is found for a $uniqueId an empty array() must be returned.
* *
* @param string $uniqueId A value to be found in the configured UNIQUEID. * @param string $uniqueId A value to be found in the configured UNIQUEID.
* If set, only one item is returned. If false or not set, the entire GAB is returned. * If set, only one item is returned. If false or not set, the entire GAB is returned.
...@@ -223,7 +217,7 @@ class Zarafa extends SyncWorker { ...@@ -223,7 +217,7 @@ class Zarafa extends SyncWorker {
mapi_table_restrict($table, $restriction); mapi_table_restrict($table, $restriction);
$querycnt = mapi_table_getrowcount($table); $querycnt = mapi_table_getrowcount($table);
if ($querycnt == 0) { if ($querycnt == 0) {
$this->Terminate(sprintf("Zarafa->GetGAB(): Single GAB entry '%s' requested but could not be found.", $uniqueId)); $this->Log(sprintf("Zarafa->GetGAB(): Single GAB entry '%s' requested but could not be found.", $uniqueId));
} }
elseif ($querycnt > 1) { elseif ($querycnt > 1) {
$this->Terminate(sprintf("Zarafa->GetGAB(): Single GAB entry '%s' requested but %d entries found. Aborting.", $uniqueId, $querycnt)); $this->Terminate(sprintf("Zarafa->GetGAB(): Single GAB entry '%s' requested but %d entries found. Aborting.", $uniqueId, $querycnt));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment