/**
  * This is a private method that performs exactly the same operation as Driver::lockSingleDocument, the reason this is duplicated here
  * is so that we can simulate the correct locking of documents as part of mocking a workflow that will lock a document correctly but not another
  * @param $s
  * @param $transaction_id
  * @param $contextAlias
  * @return array
  */
 public function lockSingleDocumentCallback($s, $transaction_id, $contextAlias)
 {
     $lCollection = \Tripod\Mongo\Config::getInstance()->getCollectionForLocks($this->tripod->getStoreName());
     $countEntriesInLocksCollection = $lCollection->count(array('_id' => array(_ID_RESOURCE => $this->labeller->uri_to_alias($s), _ID_CONTEXT => $contextAlias)));
     if ($countEntriesInLocksCollection > 0) {
         //Subject is already locked
         return false;
     } else {
         try {
             //Add a entry to locks collection for this subject, will throws exception if an entry already there
             $result = $lCollection->insertOne(array('_id' => array(_ID_RESOURCE => $this->labeller->uri_to_alias($s), _ID_CONTEXT => $contextAlias), _LOCKED_FOR_TRANS => $transaction_id, _LOCKED_FOR_TRANS_TS => \Tripod\Mongo\DateUtil::getMongoDate()), array("w" => 1));
             if (!$result->isAcknowledged()) {
                 throw new Exception("Failed to lock document with error message- " . $this->getLastDBError());
             }
         } catch (Exception $e) {
             //Subject is already locked or unable to lock
             $this->debugLog(MONGO_LOCK, array('description' => 'Driver::lockSingleDocument - failed with exception', 'transaction_id' => $transaction_id, 'subject' => $s, 'exception-message' => $e->getMessage()));
             return false;
         }
         //Let's get original document for processing.
         $document = $this->getTripodCollection($this->tripod)->findOne(array('_id' => array(_ID_RESOURCE => $this->labeller->uri_to_alias($s), _ID_CONTEXT => $contextAlias)));
         if (empty($document)) {
             //if document is not there, create it
             try {
                 $result = $this->getTripodCollection($this->tripod)->insertOne(array('_id' => array(_ID_RESOURCE => $this->labeller->uri_to_alias($s), _ID_CONTEXT => $contextAlias)), array("w" => 1));
                 if (!$result->isAcknowledged()) {
                     throw new Exception("Failed to create new document with error message- " . $this->getLastDBError());
                 }
                 $document = $this->getTripodCollection($this->tripod)->findOne(array('_id' => array(_ID_RESOURCE => $this->labeller->uri_to_alias($s), _ID_CONTEXT => $contextAlias)));
             } catch (\Exception $e) {
                 $this->errorLog(MONGO_LOCK, array('description' => 'Driver::lockSingleDocument - failed when creating new document', 'transaction_id' => $transaction_id, 'subject' => $s, 'exception-message' => $e->getMessage()));
                 return false;
             }
         }
         return $document;
     }
 }
Exemplo n.º 2
0
 /**
  * Adds an _id object (or array of _id objects) to the target document's impact index
  *
  * @param array $id
  * @param array &$target
  * @throws \InvalidArgumentException
  */
 protected function addIdToImpactIndex(array $id, &$target, $buildImpactIndex = true)
 {
     if ($buildImpactIndex) {
         if (isset($id[_ID_RESOURCE])) {
             // Ensure that our id is curie'd
             $id[_ID_RESOURCE] = $this->labeller->uri_to_alias($id[_ID_RESOURCE]);
             if (!isset($target[_IMPACT_INDEX])) {
                 $target[_IMPACT_INDEX] = array();
             }
             if (!in_array($id, $target[_IMPACT_INDEX])) {
                 $target[_IMPACT_INDEX][] = $id;
             }
         } else {
             foreach ($id as $i) {
                 if (!isset($i[_ID_RESOURCE])) {
                     throw new \InvalidArgumentException("Invalid id format");
                 }
                 $this->addIdToImpactIndex($i, $target);
             }
         }
     }
 }
Exemplo n.º 3
0
 /**
  * Returns the context alias curie for the supplied context or default context
  * @param string|null $context
  * @return string
  */
 protected function getContextAlias($context = null)
 {
     $contextAlias = $this->labeller->uri_to_alias(empty($context) ? $this->defaultContext : $context);
     return empty($contextAlias) ? Config::getInstance()->getDefaultContextAlias() : $contextAlias;
 }
 /**
  * Returns the ids of all documents that contain and impact index entry
  * matching the resource and context specified
  * @param array $resourcesAndPredicates
  * @param string $context
  * @return array the ids of search documents that had matching entries in their impact index
  */
 public function findImpactedDocuments(array $resourcesAndPredicates, $context)
 {
     $contextAlias = $this->labeller->uri_to_alias($context);
     $specPredicates = array();
     foreach ($this->config->getSearchDocumentSpecifications($this->storeName) as $spec) {
         if (isset($spec[_ID_KEY])) {
             $specPredicates[$spec[_ID_KEY]] = $this->config->getDefinedPredicatesInSpec($this->storeName, $spec[_ID_KEY]);
         }
     }
     // build a filter - will be used for impactIndex detection and finding search types to re-gen
     $searchDocFilters = array();
     $resourceFilters = array();
     foreach ($resourcesAndPredicates as $resource => $resourcePredicates) {
         $resourceAlias = $this->labeller->uri_to_alias($resource);
         $id = array(_ID_RESOURCE => $resourceAlias, _ID_CONTEXT => $contextAlias);
         // If we don't have a working config or there are no predicates listed, remove all
         // rows associated with the resource in all search types
         if (empty($specPredicates) || empty($resourcePredicates)) {
             // build $filter for queries to impact index
             $resourceFilters[] = $id;
         } else {
             foreach ($specPredicates as $searchDocType => $predicates) {
                 // Only look for search rows if the changed predicates are actually defined in the searchDocspec
                 if (array_intersect($resourcePredicates, $predicates)) {
                     if (!isset($searchDocFilters[$searchDocType])) {
                         $searchDocFilters[$searchDocType] = array();
                     }
                     // build $filter for queries to impact index
                     $searchDocFilters[$searchDocType][] = $id;
                 }
             }
         }
     }
     $searchTypes = array();
     if (empty($searchDocFilters) && !empty($resourceFilters)) {
         $query = array(_IMPACT_INDEX => array('$in' => $resourceFilters));
     } else {
         $query = array();
         foreach ($searchDocFilters as $searchDocType => $filters) {
             // first re-gen views where resources appear in the impact index
             $query[] = array(_IMPACT_INDEX => array('$in' => $filters), '_id.' . _ID_TYPE => $searchDocType);
             $searchTypes[] = $searchDocType;
         }
         if (!empty($resourceFilters)) {
             $query[] = array(_IMPACT_INDEX => array('$in' => $resourceFilters));
         }
         if (count($query) === 1) {
             $query = $query[0];
         } elseif (count($query) > 1) {
             $query = array('$or' => $query);
         }
     }
     if (empty($query)) {
         return array();
     }
     $searchDocs = array();
     foreach ($this->config->getCollectionsForSearch($this->storeName, $searchTypes) as $collection) {
         $cursor = $collection->find($query, array('projection' => array('_id' => true)));
         foreach ($cursor as $d) {
             $searchDocs[] = $d;
         }
     }
     return $searchDocs;
 }
Exemplo n.º 5
-1
 /**
  * @param string $cbdSubject
  * @param MongoGraph $cbdGraph
  * @param Collection $collection
  * @param string $context
  * @throws \Exception
  */
 protected function saveCBD($cbdSubject, MongoGraph $cbdGraph, Collection $collection, $context)
 {
     $cbdSubject = $this->labeller->uri_to_alias($cbdSubject);
     if ($cbdGraph == null || $cbdGraph->is_empty()) {
         throw new \Exception("graph for {$cbdSubject} was null");
     }
     try {
         $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1));
         print ".";
     } catch (\Exception $e) {
         if (preg_match('/E11000/', $e->getMessage())) {
             print "M";
             // key already exists, merge it
             $criteria = array("_id" => array("r" => $cbdSubject, "c" => $context));
             $existingGraph = new MongoGraph();
             $existingGraph->add_tripod_array($collection->findOne($criteria));
             $existingGraph->add_graph($cbdGraph);
             try {
                 $collection->updateOne($criteria, ['$set' => $existingGraph->to_tripod_array($cbdSubject, $context)], array("w" => 1));
             } catch (\Exception $e2) {
                 throw new \Exception($e2->getMessage());
                 // todo: would be good to have typed exception
             }
         } else {
             // retry
             print "CursorException on update: " . $e->getMessage() . ", retrying\n";
             try {
                 $collection->insertOne($cbdGraph->to_tripod_array($cbdSubject, $context), array("w" => 1));
             } catch (\Exception $e2) {
                 throw new \Exception($e2->getMessage());
                 // todo: would be good to have typed exception
             }
         }
     }
 }