server/src/app/Repositories/RdfDocumentRepository.php
changeset 4 f55970e41793
parent 3 2b3247d02769
child 19 eadaf0b8f02e
--- a/server/src/app/Repositories/RdfDocumentRepository.php	Wed Jun 24 01:36:46 2015 +0200
+++ b/server/src/app/Repositories/RdfDocumentRepository.php	Mon Oct 05 17:02:10 2015 +0200
@@ -5,25 +5,30 @@
 use Config;
 use Log;
 use CorpusParole\Models\Document;
+use CorpusParole\Libraries\CorpusParoleException;
+use CorpusParole\Libraries\Sparql\SparqlClient;
+
+use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Pagination\Paginator;
 
 /**
  * Implement the DocumentRepository using EasyRdf
+ * TODO: cetainly split the transaction management (+add, +delete +transaction ) to an extarnal class -> for this extend the sparql client.
  */
 class RdfDocumentRepository implements DocumentRepository {
 
     private $sparqlClient;
 
-    function __construct() {
-        $this->sparqlClient = new \EasyRdf_Sparql_Client(Config::get('corpusparole.sesame_query_url'), Config::get('corpusparole.sesame_update_url'));
+    public function __construct(SparqlClient $sparqlClient) {
+        $this->sparqlClient = $sparqlClient;
     }
 
-    public function all() {
+    public function getSparqlClient() {
+        return $this->sparqlClient;
+    }
 
-        $docs = $this->sparqlClient->query(
-            'SELECT * WHERE {'.
-            '    ?uri <http://xmlns.com/foaf/0.1/primaryTopic> ?b;'.
-            '} ORDER BY ?uri'
-        );
+    private function queryDocs($query) {
+        $docs = $this->sparqlClient->query($query);
 
         $data = [];
 
@@ -34,31 +39,92 @@
         return $data;
     }
 
+    public function all() {
+
+        return $this->queryDocs("SELECT DISTINCT ?uri WHERE { GRAPH ?uri { ?s ?p ?o } } ORDER BY ?uri");
+
+    }
+
     public function get($id) {
 
-        $doc_uri = Config::get('corpusparole.cocoon_doc_id_base_uri').$id;
-
-        //$doc = $sparql->query(
-        //	"CONSTRUCT {".
-        //	"    ?doc ?p ?v.".
-        //	"}".
-        //	"WHERE {".
-        //	"    <$doc_uri> <http://xmlns.com/foaf/0.1/primaryTopic> ?doc.".
-        //	"    ?doc ?p ?v;".
-        //	"}"
-        //);
+        $docUri = Config::get('corpusparole.cocoon_doc_id_base_uri').$id;
 
         // We want the CBD (Concise Bounded Description, cf. http://www.w3.org/Submission/CBD/)
         // WARNING: This seems to work in sesame for our dataset.
         $doc = $this->sparqlClient->query(
-            'DESCRIBE ?doc '.
-            'WHERE {'.
-            "    <$doc_uri> <http://xmlns.com/foaf/0.1/primaryTopic> ?doc;".
-            '}'
+            "CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <$docUri> { ?s ?p ?o } }"
         );
+        //TODO: return null if not found
+        if($doc->isEmpty()) {
+            return null;
+        }
 
-        return new Document($doc_uri, $doc);
+        return new Document($docUri, $doc);
 
     }
 
+    /**
+     * save document.
+     * @return boolean true if a transaction was started, false otherwise
+     * @throws CorpusParoleException if one of the operation could not be performed
+     */
+    public function save(Document $doc) {
+
+        $transactionStarted = $this->sparqlClient->startTransaction();
+
+        try {
+            foreach($doc->getDeltaList() as $delta) {
+                $this->sparqlClient->delete($delta->getDeletedGraph());
+                $this->sparqlClient->add($delta->getAddedGraph());
+            }
+            if($transactionStarted) {
+                $transactionStarted = false;
+                return $this->sparqlClient->commit();
+            }
+            else  {
+                return false;
+            }
+        }
+        catch(CorpusParoleException $e) {
+            if($transactionStarted) {
+                $this->sparqlClient->rollback();
+            }
+            throw $e;
+        }
+    }
+
+    public function getCount() {
+        $res = $this->sparqlClient->query("SELECT (COUNT (DISTINCT ?g) as ?count) WHERE { GRAPH ?g { ?s ?p ?o } }");
+        assert(!is_null($res) && $res->count()==1);
+        return $res[0]->count->getValue();
+    }
+
+    //SELECT ?g WHERE { GRAPH ?g { ?s ?p ?o } }
+
+    /**
+     * Paginate all document as a paginator.
+     *
+     * @param  int  $perPage
+     * @param  string  $pageName
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
+     */
+    public function paginateAll($perPage = 15, $pageName = 'page')
+    {
+        $page = Paginator::resolveCurrentPage($pageName);
+
+        $total = $this->getCount();
+
+        $offset = max(0,($page - 1) * $perPage);
+
+        $query = "SELECT DISTINCT ?uri WHERE { GRAPH ?uri { ?s ?p ?o } } ORDER BY ?uri OFFSET $offset LIMIT $perPage";
+
+        $results = $this->queryDocs($query);
+
+        return new LengthAwarePaginator($results, $total, $perPage, $page, [
+            'path' => Paginator::resolveCurrentPath(),
+            'pageName' => $pageName,
+        ]);
+    }
+
+
 }