3 namespace CorpusParole\Repositories; |
3 namespace CorpusParole\Repositories; |
4 |
4 |
5 use Config; |
5 use Config; |
6 use Log; |
6 use Log; |
7 use CorpusParole\Models\Document; |
7 use CorpusParole\Models\Document; |
|
8 use CorpusParole\Libraries\CorpusParoleException; |
|
9 use CorpusParole\Libraries\Sparql\SparqlClient; |
|
10 |
|
11 use Illuminate\Pagination\LengthAwarePaginator; |
|
12 use Illuminate\Pagination\Paginator; |
8 |
13 |
9 /** |
14 /** |
10 * Implement the DocumentRepository using EasyRdf |
15 * Implement the DocumentRepository using EasyRdf |
|
16 * TODO: cetainly split the transaction management (+add, +delete +transaction ) to an extarnal class -> for this extend the sparql client. |
11 */ |
17 */ |
12 class RdfDocumentRepository implements DocumentRepository { |
18 class RdfDocumentRepository implements DocumentRepository { |
13 |
19 |
14 private $sparqlClient; |
20 private $sparqlClient; |
15 |
21 |
16 function __construct() { |
22 public function __construct(SparqlClient $sparqlClient) { |
17 $this->sparqlClient = new \EasyRdf_Sparql_Client(Config::get('corpusparole.sesame_query_url'), Config::get('corpusparole.sesame_update_url')); |
23 $this->sparqlClient = $sparqlClient; |
18 } |
24 } |
19 |
25 |
20 public function all() { |
26 public function getSparqlClient() { |
|
27 return $this->sparqlClient; |
|
28 } |
21 |
29 |
22 $docs = $this->sparqlClient->query( |
30 private function queryDocs($query) { |
23 'SELECT * WHERE {'. |
31 $docs = $this->sparqlClient->query($query); |
24 ' ?uri <http://xmlns.com/foaf/0.1/primaryTopic> ?b;'. |
|
25 '} ORDER BY ?uri' |
|
26 ); |
|
27 |
32 |
28 $data = []; |
33 $data = []; |
29 |
34 |
30 foreach ($docs as $doc) { |
35 foreach ($docs as $doc) { |
31 array_push($data, new Document($doc->uri->getUri())); |
36 array_push($data, new Document($doc->uri->getUri())); |
32 } |
37 } |
33 |
38 |
34 return $data; |
39 return $data; |
35 } |
40 } |
36 |
41 |
|
42 public function all() { |
|
43 |
|
44 return $this->queryDocs("SELECT DISTINCT ?uri WHERE { GRAPH ?uri { ?s ?p ?o } } ORDER BY ?uri"); |
|
45 |
|
46 } |
|
47 |
37 public function get($id) { |
48 public function get($id) { |
38 |
49 |
39 $doc_uri = Config::get('corpusparole.cocoon_doc_id_base_uri').$id; |
50 $docUri = Config::get('corpusparole.cocoon_doc_id_base_uri').$id; |
40 |
|
41 //$doc = $sparql->query( |
|
42 // "CONSTRUCT {". |
|
43 // " ?doc ?p ?v.". |
|
44 // "}". |
|
45 // "WHERE {". |
|
46 // " <$doc_uri> <http://xmlns.com/foaf/0.1/primaryTopic> ?doc.". |
|
47 // " ?doc ?p ?v;". |
|
48 // "}" |
|
49 //); |
|
50 |
51 |
51 // We want the CBD (Concise Bounded Description, cf. http://www.w3.org/Submission/CBD/) |
52 // We want the CBD (Concise Bounded Description, cf. http://www.w3.org/Submission/CBD/) |
52 // WARNING: This seems to work in sesame for our dataset. |
53 // WARNING: This seems to work in sesame for our dataset. |
53 $doc = $this->sparqlClient->query( |
54 $doc = $this->sparqlClient->query( |
54 'DESCRIBE ?doc '. |
55 "CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <$docUri> { ?s ?p ?o } }" |
55 'WHERE {'. |
|
56 " <$doc_uri> <http://xmlns.com/foaf/0.1/primaryTopic> ?doc;". |
|
57 '}' |
|
58 ); |
56 ); |
|
57 //TODO: return null if not found |
|
58 if($doc->isEmpty()) { |
|
59 return null; |
|
60 } |
59 |
61 |
60 return new Document($doc_uri, $doc); |
62 return new Document($docUri, $doc); |
61 |
63 |
62 } |
64 } |
63 |
65 |
|
66 /** |
|
67 * save document. |
|
68 * @return boolean true if a transaction was started, false otherwise |
|
69 * @throws CorpusParoleException if one of the operation could not be performed |
|
70 */ |
|
71 public function save(Document $doc) { |
|
72 |
|
73 $transactionStarted = $this->sparqlClient->startTransaction(); |
|
74 |
|
75 try { |
|
76 foreach($doc->getDeltaList() as $delta) { |
|
77 $this->sparqlClient->delete($delta->getDeletedGraph()); |
|
78 $this->sparqlClient->add($delta->getAddedGraph()); |
|
79 } |
|
80 if($transactionStarted) { |
|
81 $transactionStarted = false; |
|
82 return $this->sparqlClient->commit(); |
|
83 } |
|
84 else { |
|
85 return false; |
|
86 } |
|
87 } |
|
88 catch(CorpusParoleException $e) { |
|
89 if($transactionStarted) { |
|
90 $this->sparqlClient->rollback(); |
|
91 } |
|
92 throw $e; |
|
93 } |
|
94 } |
|
95 |
|
96 public function getCount() { |
|
97 $res = $this->sparqlClient->query("SELECT (COUNT (DISTINCT ?g) as ?count) WHERE { GRAPH ?g { ?s ?p ?o } }"); |
|
98 assert(!is_null($res) && $res->count()==1); |
|
99 return $res[0]->count->getValue(); |
|
100 } |
|
101 |
|
102 //SELECT ?g WHERE { GRAPH ?g { ?s ?p ?o } } |
|
103 |
|
104 /** |
|
105 * Paginate all document as a paginator. |
|
106 * |
|
107 * @param int $perPage |
|
108 * @param string $pageName |
|
109 * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator |
|
110 */ |
|
111 public function paginateAll($perPage = 15, $pageName = 'page') |
|
112 { |
|
113 $page = Paginator::resolveCurrentPage($pageName); |
|
114 |
|
115 $total = $this->getCount(); |
|
116 |
|
117 $offset = max(0,($page - 1) * $perPage); |
|
118 |
|
119 $query = "SELECT DISTINCT ?uri WHERE { GRAPH ?uri { ?s ?p ?o } } ORDER BY ?uri OFFSET $offset LIMIT $perPage"; |
|
120 |
|
121 $results = $this->queryDocs($query); |
|
122 |
|
123 return new LengthAwarePaginator($results, $total, $perPage, $page, [ |
|
124 'path' => Paginator::resolveCurrentPath(), |
|
125 'pageName' => $pageName, |
|
126 ]); |
|
127 } |
|
128 |
|
129 |
64 } |
130 } |