<?php
namespace CorpusParole\Repositories;
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;
public function __construct(SparqlClient $sparqlClient) {
$this->sparqlClient = $sparqlClient;
}
public function getSparqlClient() {
return $this->sparqlClient;
}
private function queryDocs($query) {
$docs = $this->sparqlClient->query($query);
$data = [];
foreach ($docs as $doc) {
array_push($data, new Document($doc->uri->getUri()));
}
return $data;
}
public function all() {
return $this->queryDocs("SELECT DISTINCT ?uri WHERE { GRAPH ?uri { ?s ?p ?o } } ORDER BY ?uri");
}
public function get($id) {
$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(
"CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <$docUri> { ?s ?p ?o } }"
);
//TODO: return null if not found
if($doc->isEmpty()) {
return null;
}
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,
]);
}
}