Index: trunk/extensions/SemanticMediaWiki/RELEASE-NOTES |
— | — | @@ -4,6 +4,8 @@ |
5 | 5 | == SMW 1.6.3 == |
6 | 6 | |
7 | 7 | * Added native "internal objects" that can be set using #setobject. |
| 8 | +* Added support for selecting a default graph when using RDF stores, |
| 9 | + configuration called $smwgSparqlDefaultGraph |
8 | 10 | * Fixed the default result format for #show. |
9 | 11 | * Fixed display of table headers when they are all empty. |
10 | 12 | * Migrated all query printers to use the new param handling, |
Index: trunk/extensions/SemanticMediaWiki/includes/sparql/SMW_SparqlDatabase.php |
— | — | @@ -111,6 +111,7 @@ |
112 | 112 | |
113 | 113 | /** |
114 | 114 | * The URL of the endpoint for executing read queries. |
| 115 | + * |
115 | 116 | * @var string |
116 | 117 | */ |
117 | 118 | protected $m_queryEndpoint; |
— | — | @@ -118,6 +119,7 @@ |
119 | 120 | /** |
120 | 121 | * The URL of the endpoint for executing update queries, or empty if |
121 | 122 | * update is not allowed/supported. |
| 123 | + * |
122 | 124 | * @var string |
123 | 125 | */ |
124 | 126 | protected $m_updateEndpoint; |
— | — | @@ -125,24 +127,44 @@ |
126 | 128 | /** |
127 | 129 | * The URL of the endpoint for using the SPARQL Graph Store HTTP |
128 | 130 | * Protocol with, or empty if this method is not allowed/supported. |
| 131 | + * |
129 | 132 | * @var string |
130 | 133 | */ |
131 | 134 | protected $m_dataEndpoint; |
132 | 135 | |
133 | 136 | /** |
| 137 | + * The URI of the default graph that is used to store data. |
| 138 | + * Can be the empty string to omit this information in all requests |
| 139 | + * (not supported by all stores). |
| 140 | + * |
| 141 | + * @var string |
| 142 | + */ |
| 143 | + protected $m_defaultGraph; |
| 144 | + |
| 145 | + /** |
134 | 146 | * The curl handle we use for communicating. We reuse the same handle |
135 | 147 | * throughout as this safes some initialization effort. |
| 148 | + * |
136 | 149 | * @var resource |
137 | 150 | */ |
138 | 151 | protected $m_curlhandle; |
139 | 152 | |
140 | 153 | /** |
141 | | - * Constructor |
| 154 | + * Constructor. |
142 | 155 | * |
| 156 | + * Normally, you should call smwfGetSparqlDatabase() to obtain a |
| 157 | + * suitable instance of a SPARQL database handler rather than |
| 158 | + * constructing one directly. |
| 159 | + * |
| 160 | + * @param $graph string of URI of the default graph to store data to; |
| 161 | + * can be the empty string to omit this information in all requests |
| 162 | + * (not supported by all stores) |
143 | 163 | * @param $queryEndpoint string of URL of query service (reading) |
144 | 164 | * @param $updateEndpoint string of URL of update service (writing) |
| 165 | + * @param $dataEndpoint string of URL of POST service (writing, optional) |
145 | 166 | */ |
146 | | - public function __construct( $queryEndpoint, $updateEndpoint = '', $dataEndpoint = '' ) { |
| 167 | + public function __construct( $graph, $queryEndpoint, $updateEndpoint = '', $dataEndpoint = '' ) { |
| 168 | + $this->m_defaultGraph = $graph; |
147 | 169 | $this->m_queryEndpoint = $queryEndpoint; |
148 | 170 | $this->m_updateEndpoint = $updateEndpoint; |
149 | 171 | $this->m_dataEndpoint = $dataEndpoint; |
— | — | @@ -155,6 +177,17 @@ |
156 | 178 | } |
157 | 179 | |
158 | 180 | /** |
| 181 | + * Get the URI of the default graph that this database connector is |
| 182 | + * using, or the empty string if none is used (no graph related |
| 183 | + * statements in queries/updates). |
| 184 | + * |
| 185 | + * @return string graph UIR or empty |
| 186 | + */ |
| 187 | + public function getDefaultGraph() { |
| 188 | + return $this->m_defaultGraph; |
| 189 | + } |
| 190 | + |
| 191 | + /** |
159 | 192 | * Check if the database can be contacted. |
160 | 193 | * |
161 | 194 | * @param $pingQueryEndpoint boolean true if the query endpoint should |
— | — | @@ -313,7 +346,8 @@ |
314 | 347 | */ |
315 | 348 | public function delete( $deletePattern, $where, $extraNamespaces = array() ) { |
316 | 349 | $sparql = self::getPrefixString( $extraNamespaces ) . |
317 | | - "DELETE { $deletePattern } WHERE { $where }"; |
| 350 | + ( ( $this->m_defaultGraph != '' )? "WITH <{$this->m_defaultGraph}> " : '' ) . |
| 351 | + "DELETE { $deletePattern } WHERE { $where }"; |
318 | 352 | return $this->doUpdate( $sparql ); |
319 | 353 | } |
320 | 354 | |
— | — | @@ -351,7 +385,8 @@ |
352 | 386 | */ |
353 | 387 | public function insertDelete( $insertPattern, $deletePattern, $where, $extraNamespaces = array() ) { |
354 | 388 | $sparql = self::getPrefixString( $extraNamespaces ) . |
355 | | - "INSERT { $insertPattern } DELETE { $deletePattern } WHERE { $where }"; |
| 389 | + ( ( $this->m_defaultGraph != '' )? "WITH <{$this->m_defaultGraph}> " : '' ) . |
| 390 | + "DELETE { $deletePattern } INSERT { $insertPattern } WHERE { $where }"; |
356 | 391 | return $this->doUpdate( $sparql ); |
357 | 392 | } |
358 | 393 | |
— | — | @@ -370,7 +405,10 @@ |
371 | 406 | $turtle = self::getPrefixString( $extraNamespaces, false ) . $triples; |
372 | 407 | return $this->doHttpPost( $turtle ); |
373 | 408 | } else { |
374 | | - $sparql = self::getPrefixString( $extraNamespaces, true ) . "INSERT DATA { $triples }"; |
| 409 | + $sparql = self::getPrefixString( $extraNamespaces, true ) . |
| 410 | + "INSERT DATA { " . |
| 411 | + ( ( $this->m_defaultGraph != '' )? "GRAPH <{$this->m_defaultGraph}> " : '' ) . |
| 412 | + "{ $triples } }"; |
375 | 413 | return $this->doUpdate( $sparql ); |
376 | 414 | } |
377 | 415 | } |
— | — | @@ -386,7 +424,10 @@ |
387 | 425 | * @return boolean stating whether the operations succeeded |
388 | 426 | */ |
389 | 427 | public function deleteData( $triples, $extraNamespaces = array() ) { |
390 | | - $sparql = self::getPrefixString( $extraNamespaces ) . "DELETE DATA { $triples }"; |
| 428 | + $sparql = self::getPrefixString( $extraNamespaces ) . |
| 429 | + "DELETE DATA { " . |
| 430 | + ( ( $this->m_defaultGraph != '' )? "GRAPH <{$this->m_defaultGraph}> " : '' ) . |
| 431 | + "{ $triples } }"; |
391 | 432 | return $this->doUpdate( $sparql ); |
392 | 433 | } |
393 | 434 | |
— | — | @@ -398,6 +439,9 @@ |
399 | 440 | * method does not throw anything, then an empty result with an error |
400 | 441 | * code is returned. |
401 | 442 | * |
| 443 | + * @note This function sets the graph that is to be used as part of the |
| 444 | + * request. Queries should not include additional graph information. |
| 445 | + * |
402 | 446 | * @param $sparql string with the complete SPARQL query (SELECT or ASK) |
403 | 447 | * @return SMWSparqlResultWrapper |
404 | 448 | */ |
— | — | @@ -405,7 +449,8 @@ |
406 | 450 | //debug_zval_dump( $sparql ); |
407 | 451 | curl_setopt( $this->m_curlhandle, CURLOPT_URL, $this->m_queryEndpoint ); |
408 | 452 | curl_setopt( $this->m_curlhandle, CURLOPT_POST, true ); |
409 | | - $parameterString = "query=" . urlencode( $sparql ); |
| 453 | + $parameterString = "query=" . urlencode( $sparql ) . |
| 454 | + ( ( $this->m_defaultGraph != '' )? 'default-graph-uri=' . urlencode( $this->m_defaultGraph ) : '' ); |
410 | 455 | curl_setopt( $this->m_curlhandle, CURLOPT_POSTFIELDS, $parameterString ); |
411 | 456 | |
412 | 457 | $xmlResult = curl_exec( $this->m_curlhandle ); |
— | — | @@ -425,6 +470,12 @@ |
426 | 471 | * SMWSparqlDatabase::throwSparqlErrors(). If errors occur and this |
427 | 472 | * method does not throw anything, then false is returned. |
428 | 473 | * |
| 474 | + * @note When this is written, it is not clear if the update protocol |
| 475 | + * supports a default-graph-uri parameter. Hence the target graph for |
| 476 | + * all updates is generally encoded in the query string and not fixed |
| 477 | + * when sending the query. Direct callers to this function must include |
| 478 | + * the graph information in the queries that they build. |
| 479 | + * |
429 | 480 | * @param $sparql string with the complete SPARQL update query (INSERT or DELETE) |
430 | 481 | * @return boolean |
431 | 482 | */ |
— | — | @@ -455,9 +506,13 @@ |
456 | 507 | * method does not throw anything, then an empty result with an error |
457 | 508 | * code is returned. |
458 | 509 | * |
459 | | - * @note This method has not been tesetd sufficiently since 4Store uses |
460 | | - * another post encoding. To avoid using it, simply do not provide a |
461 | | - * data endpoint URL when configuring the SPARQL database. |
| 510 | + * @note This protocol is not part of the SPARQL standard and may not |
| 511 | + * be supported by all stores. To avoid using it, simply do not provide |
| 512 | + * a data endpoint URL when configuring the SPARQL database. If used, |
| 513 | + * the protocol might lead to a better performance since there is less |
| 514 | + * parsing required to fetch the data from the request. |
| 515 | + * @note Some stores (e.g. 4Store) support another mode of posting data |
| 516 | + * that may be implemented in a special database handler. |
462 | 517 | * |
463 | 518 | * @param $payload string Turtle serialization of data to send |
464 | 519 | * @return SMWSparqlResultWrapper |
— | — | @@ -466,7 +521,8 @@ |
467 | 522 | if ( $this->m_dataEndpoint == '' ) { |
468 | 523 | throw new SMWSparqlDatabaseError( SMWSparqlDatabaseError::ERROR_NOSERVICE, "SPARQL POST with data: $payload", 'not specified' ); |
469 | 524 | } |
470 | | - curl_setopt( $this->m_curlhandle, CURLOPT_URL, $this->m_dataEndpoint ); |
| 525 | + curl_setopt( $this->m_curlhandle, CURLOPT_URL, $this->m_dataEndpoint . |
| 526 | + ( ( $this->m_defaultGraph != '' )? '?graph=' . urlencode( $this->m_defaultGraph ) : '?default' ) ); |
471 | 527 | curl_setopt( $this->m_curlhandle, CURLOPT_POST, true ); |
472 | 528 | |
473 | 529 | // POST as file (fails in 4Store) |
Index: trunk/extensions/SemanticMediaWiki/includes/sparql/SMW_SparqlDatabase4Store.php |
— | — | @@ -37,9 +37,9 @@ |
38 | 38 | //$result = parent::doQuery( $sparql ); |
39 | 39 | curl_setopt( $this->m_curlhandle, CURLOPT_URL, $this->m_queryEndpoint ); |
40 | 40 | curl_setopt( $this->m_curlhandle, CURLOPT_POST, true ); |
41 | | - $parameterString = "query=" . urlencode( $sparql ) . "&restricted=1"; |
| 41 | + $parameterString = "query=" . urlencode( $sparql ) . "&restricted=1" . |
| 42 | + ( ( $this->m_defaultGraph != '' )? '&default-graph-uri=' . urlencode( $this->m_defaultGraph ) : '' ); |
42 | 43 | curl_setopt( $this->m_curlhandle, CURLOPT_POSTFIELDS, $parameterString ); |
43 | | - |
44 | 44 | $xmlResult = curl_exec( $this->m_curlhandle ); |
45 | 45 | |
46 | 46 | if ( curl_errno( $this->m_curlhandle ) == 0 ) { |
— | — | @@ -101,7 +101,9 @@ |
102 | 102 | } |
103 | 103 | curl_setopt( $this->m_curlhandle, CURLOPT_URL, $this->m_dataEndpoint ); |
104 | 104 | curl_setopt( $this->m_curlhandle, CURLOPT_POST, true ); |
105 | | - $parameterString = "data=" . urlencode( $payload ) . '&graph=default&mime-type=application/x-turtle'; |
| 105 | + $parameterString = "data=" . urlencode( $payload ) . '&graph=' . |
| 106 | + ( ( $this->m_defaultGraph != '' )? urlencode( $this->m_defaultGraph ) : 'default' ) . |
| 107 | + '&mime-type=application/x-turtle'; |
106 | 108 | curl_setopt( $this->m_curlhandle, CURLOPT_POSTFIELDS, $parameterString ); |
107 | 109 | |
108 | 110 | curl_exec( $this->m_curlhandle ); |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_GlobalFunctions.php |
— | — | @@ -310,10 +310,11 @@ |
311 | 311 | * @return SMWSparqlDatabase or null |
312 | 312 | */ |
313 | 313 | function &smwfGetSparqlDatabase() { |
314 | | - global $smwgSparqlDatabase, $smwgSparqlQueryEndpoint, $smwgSparqlUpdateEndpoint, |
315 | | - $smwgSparqlDataEndpoint, $smwgSparqlDatabaseMaster; |
| 314 | + global $smwgSparqlDatabase, $smwgSparqlDefaultGraph, $smwgSparqlQueryEndpoint, |
| 315 | + $smwgSparqlUpdateEndpoint, $smwgSparqlDataEndpoint, $smwgSparqlDatabaseMaster; |
316 | 316 | if ( !isset( $smwgSparqlDatabaseMaster ) ) { |
317 | | - $smwgSparqlDatabaseMaster = new $smwgSparqlDatabase( $smwgSparqlQueryEndpoint, $smwgSparqlUpdateEndpoint, $smwgSparqlDataEndpoint ); |
| 317 | + $smwgSparqlDatabaseMaster = new $smwgSparqlDatabase( $smwgSparqlDefaultGraph, |
| 318 | + $smwgSparqlQueryEndpoint, $smwgSparqlUpdateEndpoint, $smwgSparqlDataEndpoint ); |
318 | 319 | } |
319 | 320 | return $smwgSparqlDatabaseMaster; |
320 | 321 | } |
Index: trunk/extensions/SemanticMediaWiki/SMW_Settings.php |
— | — | @@ -58,11 +58,19 @@ |
59 | 59 | # This will lead to reduced functionality (e.g. the SMWSparqlStore will not |
60 | 60 | # work if Update is not available). The data endpoint is always optional, but |
61 | 61 | # in some SPARQL databases this method is more efficient than update. |
| 62 | +# |
| 63 | +# The default graph is similar to a database name in relational databases. It |
| 64 | +# can be set to any URI (e.g. the main page uri of your wiki with |
| 65 | +# "#graph" appended). Leaving the default graph URI empty only works if the |
| 66 | +# store is configure to use some default default graph or if it generally |
| 67 | +# supports this. Different wikis should normally use different default graphs |
| 68 | +# unless there is a good reason to share one graph. |
62 | 69 | ## |
63 | 70 | $smwgSparqlDatabase = 'SMWSparqlDatabase'; |
64 | 71 | $smwgSparqlQueryEndpoint = 'http://localhost:8080/sparql/'; |
65 | 72 | $smwgSparqlUpdateEndpoint = 'http://localhost:8080/update/'; |
66 | 73 | $smwgSparqlDataEndpoint = 'http://localhost:8080/data/'; |
| 74 | +$smwgSparqlDefaultGraph = ''; |
67 | 75 | ## |
68 | 76 | |
69 | 77 | // load global constants and setup functions |