31 private static $isInfoEnabled =
false;
32 private static $isDebugEnabled =
false;
33 private static $logger =
null;
35 private $persistenceFacade =
null;
36 private $eventManager =
null;
39 private $isActive =
false;
40 private $isInCommit =
false;
41 private $observedObjects = [];
60 if (self::$logger ==
null) {
63 $this->persistenceFacade = $persistenceFacade;
64 $this->eventManager = $eventManager;
68 self::$isInfoEnabled = self::$logger->isInfoEnabled();
69 self::$isDebugEnabled = self::$logger->isDebugEnabled();
83 if (self::$isInfoEnabled) {
84 self::$logger->info(
"Starting transaction");
107 if (self::$isInfoEnabled) {
108 self::$logger->info(
"Rollback transaction");
113 $this->isInCommit =
false;
122 return $this->isActive;
129 unset($this->detachedObjects[$object->
getOID()->__toString()]);
157 if (isset($this->newObjects[$key])) {
158 $object = $this->newObjects[$key];
159 unset($this->newObjects[$key]);
161 if (isset($this->dirtyObjects[$key])) {
162 $object = $this->dirtyObjects[$key];
163 unset($this->dirtyObjects[$key]);
165 if (isset($this->deletedObjects[$key])) {
166 $object = $this->deletedObjects[$key];
167 unset($this->deletedObjects[$key]);
169 if (isset($this->loadedObjects[$key])) {
170 $object = $this->loadedObjects[$key];
171 unset($this->loadedObjects[$key]);
173 unset($this->observedObjects[$key]);
174 $this->detachedObjects[$key] = $object;
181 $registeredObject =
null;
183 if (isset($this->loadedObjects[$key])) {
184 $registeredObject = $this->loadedObjects[$key];
186 if (isset($this->newObjects[$key])) {
187 $registeredObject = $this->newObjects[$key];
189 return $registeredObject;
196 return $this->observedObjects;
206 $key = $oid->__toString();
207 if (self::$isDebugEnabled) {
208 self::$logger->debug(
"New Data:\n".$object->
dump());
209 self::$logger->debug(
"Registry before:\n".$this->
dump());
213 $registeredObject =
null;
214 if (isset($this->loadedObjects[$key])) {
215 $registeredObject = $this->loadedObjects[$key];
217 if (self::$isDebugEnabled) {
218 self::$logger->debug(
"Merging data of ".$key);
220 $registeredObject->mergeValues($object);
223 if (self::$isDebugEnabled) {
224 self::$logger->debug(
"Register loaded object: ".$key);
226 $this->loadedObjects[$key] = $object;
229 if (self::$isDebugEnabled) {
230 self::$logger->debug(
"Start listening to: ".$key);
232 $this->observedObjects[$key] = $object;
234 $registeredObject = $object;
236 if (self::$isDebugEnabled) {
237 self::$logger->debug(
"Registry after:\n".$this->
dump());
239 return $registeredObject;
247 $key = $object->
getOID()->__toString();
248 if (self::$isDebugEnabled) {
249 self::$logger->debug(
"Register new object: ".$key);
251 $this->newObjects[$key] = $object;
252 $this->observedObjects[$key] = $object;
261 $key = $object->
getOID()->__toString();
263 if (isset($this->newObjects[$key]) || isset($this->deletedObjects[$key])) {
266 if (self::$isDebugEnabled) {
267 self::$logger->debug(
"Register dirty object: ".$key);
269 $this->dirtyObjects[$key] = $object;
278 $key = $object->
getOID()->__toString();
281 if (isset($this->newObjects[$key])) {
282 unset($this->newObjects[$key]);
286 if (isset($this->dirtyObjects[$key])) {
287 unset($this->dirtyObjects[$key]);
289 if (self::$isDebugEnabled) {
290 self::$logger->debug(
"Register deleted object: ".$key);
292 $this->deletedObjects[$key] = $object;
302 if ($this->isInCommit) {
305 if (self::$isInfoEnabled) {
306 self::$logger->info(
"Commit transaction [collect=".($collect ?
"true" :
"false").
"]");
308 $this->isInCommit =
true;
316 $knowTypes = $this->persistenceFacade->getKnownTypes();
319 foreach ($knowTypes as $type) {
320 $mapper = $this->persistenceFacade->getMapper($type);
321 $mapper->beginTransaction();
327 $emptyState =
'0:0:0';
328 while (!$commitDone) {
331 sizeof($this->dirtyObjects).
':'.
333 $insertedOids = array_merge($insertedOids, $this->
processInserts());
334 $updatedOids = array_merge($updatedOids, $this->
processUpdates());
335 $deletedOids = array_merge($deletedOids, $this->
processDeletes());
338 sizeof($this->dirtyObjects).
':'.
341 if ($oldState != $emptyState && $oldState == $newState) {
345 $commitDone = $newState == $emptyState;
348 if (self::$isInfoEnabled) {
349 self::$logger->info(
"Committing transaction");
351 foreach ($knowTypes as $type) {
352 $mapper = $this->persistenceFacade->getMapper($type);
353 $statements = array_merge($statements, $mapper->getStatements());
355 $mapper->rollbackTransaction();
358 $mapper->commitTransaction();
362 catch (Exception $ex) {
364 self::$logger->error(
"Rolling back transaction. Exception: ".$ex->__toString());
365 foreach ($knowTypes as $type) {
366 $mapper = $this->persistenceFacade->getMapper($type);
367 $mapper->rollbackTransaction();
376 $this->isInCommit =
false;
386 foreach ($this->newObjects as $object) {
387 unset($this->observedObjects[$object->getOID()->__toString()]);
389 $this->newObjects = [];
391 foreach ($this->dirtyObjects as $object) {
392 unset($this->observedObjects[$object->getOID()->__toString()]);
394 $this->dirtyObjects = [];
396 foreach ($this->deletedObjects as $object) {
397 unset($this->observedObjects[$object->getOID()->__toString()]);
399 $this->deletedObjects = [];
401 foreach ($this->loadedObjects as $object) {
402 unset($this->observedObjects[$object->getOID()->__toString()]);
404 $this->loadedObjects = [];
406 $this->detachedObjects = [];
415 $pendingInserts = [];
416 $insertOids = array_keys($this->newObjects);
417 while (
sizeof($insertOids) > 0) {
418 $key = array_shift($insertOids);
419 if (self::$isDebugEnabled) {
420 self::$logger->debug(
"Process insert on object: ".$key);
422 $object = $this->newObjects[$key];
426 $requiredObjects = $object->getIndispensableObjects();
427 foreach ($requiredObjects as $requiredObject) {
429 if (self::$isDebugEnabled) {
430 self::$logger->debug(
"Postpone insert of object: ".$key.
". Required objects are not saved yet.");
432 $pendingInserts[] = $object;
438 $oldOid = $object->getOID();
439 $object->getMapper()->save($object);
440 $insertedOids[$oldOid->__toString()] = $object->getOID()->__toString();
442 unset($this->newObjects[$key]);
443 $insertOids = array_keys($this->newObjects);
444 unset($this->observedObjects[$key]);
445 $this->observedObjects[$object->getOID()->__toString()] = $object;
448 foreach ($pendingInserts as $object) {
449 $key = $object->getOID()->__toString();
450 $this->newObjects[$key] = $object;
452 return $insertedOids;
461 $updateOids = array_keys($this->dirtyObjects);
462 while (
sizeof($updateOids) > 0) {
463 $key = array_shift($updateOids);
464 if (self::$isDebugEnabled) {
465 self::$logger->debug(
"Process update on object: ".$key);
467 $object = $this->dirtyObjects[$key];
468 $object->getMapper()->save($object);
469 unset($this->dirtyObjects[$key]);
470 $updatedOids[] = $key;
471 $updateOids = array_keys($this->dirtyObjects);
482 $deleteOids = array_keys($this->deletedObjects);
483 while (
sizeof($deleteOids) > 0) {
484 $key = array_shift($deleteOids);
485 if (self::$isDebugEnabled) {
486 self::$logger->debug(
"Process delete on object: ".$key);
488 $object = $this->deletedObjects[$key];
489 $object->getMapper()->delete($object);
490 unset($this->deletedObjects[$key]);
491 $deletedOids[] = $key;
492 $deleteOids = array_keys($this->deletedObjects);
505 if (!$object || in_array($object->getOID()->__toString(), array_map(
function($obj) {
506 return $obj ? $obj->getOID()->__toString() :
null;
513 if (self::$isDebugEnabled) {
514 self::$logger->debug(
"State changed: ".$object->getOID().
" old:".$oldState.
" new:".$newState);
537 foreach (array_values($this->loadedObjects) as $curObject) {
538 $str .= $curObject->dump();