Example #1
0
 /**
  * Add a item to the queue for persitance on flush
  *
  * @param $trancation
  * @param $onFailure
  *
  * @return bool
  */
 public function flush($transaction = null, $onFailure = self::FLUSH_ABORT, $throwExceptions = true)
 {
     if (is_null($transaction)) {
         $transaction = self::TRANSACTIONS_ALL;
     }
     if (is_null($onFailure)) {
         $onFailure = self::FLUSH_ABORT;
     }
     $response = new Response();
     $exceptions = [];
     $haveAnyTransactionsFailed = false;
     // simulate
     $simulate = $this->debug & self::DEBUG_SIMULATE;
     // profiler
     $profiler = new Profiler("Record manager");
     $profiler->log();
     // debugging query show
     $debugQuery = null;
     if ($this->debug & self::DEBUG_SHOW_QUERY) {
         $debugQuery = function ($e, $event, $data) {
             echo $data . "\n";
         };
         $this->db->debug->on(Debug::INFO, $debugQuery);
     }
     // trap all throw exceptions so that we can properly unattach the $db->debug->on( Pg::QueryPassed $listener )
     try {
         // iterate selected transactions
         foreach ($this->getQueue($transaction, true, true) as $transaction => $queue) {
             unset($this->queue[$transaction]);
             $taskResponse = null;
             $hasTransactionFailed = false;
             $beginTransaction = new Query("BEGIN TRANSACTION READ WRITE; /* %transaction:% */");
             $beginTransaction->transaction = $transaction;
             $this->db->query($beginTransaction);
             $this->eventEmitter->emit(EventEmitter::TRANSACTION_START, $this, $transaction, $queue);
             // loop over our tasks
             foreach ($queue as $task) {
                 // are we continuing to process?
                 if ($hasTransactionFailed or $haveAnyTransactionsFailed && $onFailure === self::FLUSH_ABORT) {
                     $taskResponse = Response::ABORTED;
                 } else {
                     try {
                         $taskResponse = $task->execute($this->db, $simulate) ? Response::SUCCESS : Response::FAILED;
                     } catch (\Exception $e) {
                         // It'd be nice if we could just test for Query exceptions here but unfortunately PHPUnit dicks pretty hard with exception types.
                         // @Mr Beale. I realise this violates the "only handle exceptions that you understand" rule but I can't find a way round this. Pete
                         $taskResponse = $e;
                         $exceptions[] = $e;
                     }
                 }
                 // transaction success
                 if ($taskResponse !== Response::SUCCESS) {
                     $hasTransactionFailed = true;
                     $haveAnyTransactionsFailed = true;
                 }
                 $response->add($transaction, $task, $taskResponse);
             }
             // end or rollback transaction
             $endTransaction = new Query("%commitOrRollback:% TRANSACTION; /* %transaction:% */");
             $endTransaction->commitOrRollback = new Raw($hasTransactionFailed ? 'ROLLBACK' : 'COMMIT');
             $endTransaction->transaction = $transaction;
             $this->db->query($endTransaction);
             // response rollback
             if ($hasTransactionFailed) {
                 $response->rollback($transaction);
             }
             $profiler->log($transaction);
         }
         // if we've gathered any exceptions throw them here
         if ($throwExceptions and $exceptions) {
             throw $exceptions[0];
         }
         $response->profilerAssign($profiler);
     } catch (\Exception $e) {
         $this->db->debug->removeListener(Pg::QUERY_PARSED, $debugQuery);
         throw $e;
     }
     return $response;
 }