Пример #1
0
 /**
  * DB connection for meta data.
  * 
  * @param ConnectionInterface $conn
  */
 public function __construct(ConnectionInterface $conn)
 {
     parent::__construct();
     $this->conn = $conn;
     if (mt_rand(0, 100) > 95) {
         $stmt = $conn->prepare("DELETE FROM `#__webdav_lock` WHERE `expires_at` < :time");
         $stmt->bindValue('time', time());
         $stmt->execute();
     }
 }
Пример #2
0
 /**
  * {@inheritdoc}
  */
 public function findExecution(UUID $id)
 {
     static $injectVars = NULL;
     if ($injectVars === NULL) {
         $injectVars = new \ReflectionMethod(VirtualExecution::class, 'injectVariablesLocal');
         $injectVars->setAccessible(true);
     }
     $ref = (string) $id;
     if (isset($this->executions[$ref])) {
         return $this->executions[$ref];
     }
     // Need to select multiple rows as one process instance may span over different process definitions (using CallActivity)
     $sql = "\tSELECT DISTINCT e.`process_id`, d.`id` as definition_id, d.`definition`\r\n\t\t\t\t\tFROM `#__bpmn_execution` AS e\r\n\t\t\t\t\tINNER JOIN `#__bpmn_process_definition` AS d ON (d.`id` = e.`definition_id`)\r\n\t\t\t\t\tWHERE e.`process_id` = (\r\n\t\t\t\t\t\tSELECT `process_id` FROM `#__bpmn_execution` WHERE `id` = :eid\r\n\t\t\t\t\t)\r\n\t\t";
     $stmt = $this->conn->prepare($sql);
     $stmt->bindValue('eid', $id);
     $stmt->transform('process_id', new UUIDTransformer());
     $stmt->transform('definition_id', new UUIDTransformer());
     $stmt->execute();
     $rows = $stmt->fetchRows();
     if (empty($rows)) {
         throw new \OutOfBoundsException(sprintf('Execution not found: "%s"', $ref));
     }
     $processId = $rows[0]['process_id'];
     $definitions = [];
     foreach ($rows as $row) {
         $definitions[(string) $row['definition_id']] = unserialize(BinaryData::decode($row['definition']));
     }
     // Select (and lock) all execution rows of the process instance using a pessimistic lock.
     $sql = "\tSELECT e.*\r\n\t\t\t\t\tFROM `#__bpmn_execution` AS e\r\n\t\t\t\t\tWHERE e.`process_id` = :pid\r\n\t\t";
     switch ($this->conn->getDriverName()) {
         case DB::DRIVER_MYSQL:
         case DB::DRIVER_POSTGRESQL:
             $sql .= " FOR UPDATE";
     }
     $stmt = $this->conn->prepare($sql);
     $stmt->bindAll(['pid' => $processId]);
     $stmt->transform('id', new UUIDTransformer());
     $stmt->transform('pid', new UUIDTransformer());
     $stmt->transform('process_id', new UUIDTransformer());
     $stmt->transform('definition_id', new UUIDTransformer());
     $stmt->execute();
     $variables = [];
     $executions = [];
     $parents = [];
     while ($row = $stmt->fetchNextRow()) {
         $id = $row['id'];
         $pid = $row['pid'];
         $defId = (string) $row['definition_id'];
         if (empty($definitions[$defId])) {
             throw new \OutOfBoundsException(sprintf('Missing process definition "%s" referenced from execution "%s"', $defId, $id));
         }
         $definition = $definitions[$defId];
         if ($pid !== NULL) {
             $parents[(string) $id] = (string) $pid;
         }
         $state = (int) $row['state'];
         $active = (double) $row['active'];
         $node = $row['node'] === NULL ? NULL : $definition->findNode($row['node']);
         $transition = $row['transition'] === NULL ? NULL : $definition->findTransition($row['transition']);
         $businessKey = $row['business_key'];
         $variables[(string) $id] = [];
         $exec = $executions[(string) $id] = new VirtualExecution($id, $this, $definition);
         $exec->setBusinessKey($businessKey);
         $exec->setExecutionState($state);
         $exec->setNode($node);
         $exec->setTransition($transition);
         $exec->setTimestamp($active);
     }
     foreach ($parents as $id => $pid) {
         $executions[$id]->setParentExecution($executions[$pid]);
     }
     if (!empty($variables)) {
         $params = [];
         foreach (array_keys($variables) as $i => $k) {
             $params['p' . $i] = new UUID($k);
         }
         $placeholders = implode(', ', array_map(function ($p) {
             return ':' . $p;
         }, array_keys($params)));
         $sql = "\tSELECT `execution_id`, `name`, `value_blob`\r\n\t\t\t\t\t\tFROM `#__bpmn_execution_variables`\r\n\t\t\t\t\t\tWHERE `execution_id` IN ({$placeholders})\r\n\t\t\t";
         $stmt = $this->conn->prepare($sql);
         $stmt->bindAll($params);
         $stmt->transform('execution_id', new UUIDTransformer());
         $stmt->execute();
         while (false !== ($row = $stmt->fetchNextRow())) {
             $variables[(string) $row['execution_id']][$row['name']] = unserialize(BinaryData::decode($row['value_blob']));
         }
     }
     foreach ($variables as $id => $vars) {
         $injectVars->invoke($executions[$id], $vars);
     }
     foreach ($executions as $execution) {
         $execution->setSyncState(Execution::SYNC_STATE_NO_CHANGE);
         $this->executions[(string) $execution->getId()] = $execution;
     }
     if (empty($this->executions[$ref])) {
         throw new \OutOfBoundsException(sprintf('Execution not found: "%s"', $ref));
     }
     return $this->executions[$ref];
 }