diff -r 2b3247d02769 -r f55970e41793 server/src/app/Repositories/RdfDocumentRepository.php --- 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 ?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> ?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> ?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, + ]); + } + + }