PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/store/ARC2_RemoteStore.php

https://github.com/haschek/arc2
PHP | 211 lines | 159 code | 26 blank | 26 comment | 40 complexity | cb1cef9b319b7df942ff1fbbd5582032 MD5 | raw file
  1. <?php
  2. /**
  3. * ARC2 Remote RDF Store
  4. *
  5. * @author Benjamin Nowack <bnowack@semsol.com>
  6. * @license http://arc.semsol.org/license
  7. * @package ARC2
  8. * @version 2010-11-16
  9. */
  10. ARC2::inc('Class');
  11. class ARC2_RemoteStore extends ARC2_Class {
  12. function __construct($a, &$caller) {
  13. parent::__construct($a, $caller);
  14. $this->is_remote = 1;
  15. }
  16. function __init() {
  17. parent::__init();
  18. }
  19. /* */
  20. function isSetUp() {
  21. return 1;
  22. }
  23. function setUp() {}
  24. function killDBProcesses() {}
  25. /* */
  26. function reset() {}
  27. function drop() {}
  28. function insert($doc, $g, $keep_bnode_ids = 0) {
  29. return $this->query('INSERT INTO <' . $g . '> { ' . $this->toNTriples($doc, '', 1) . ' }');
  30. }
  31. function delete($doc, $g) {
  32. if (!$doc) {
  33. return $this->query('DELETE FROM <' . $g . '>');
  34. }
  35. else {
  36. return $this->query('DELETE FROM <' . $g . '> { ' . $this->toNTriples($doc, '', 1) . ' }');
  37. }
  38. }
  39. function replace($doc, $g, $doc_2) {
  40. return array($this->delete($doc, $g), $this->insert($doc_2, $g));
  41. }
  42. /* */
  43. function query($q, $result_format = '', $src = '', $keep_bnode_ids = 0, $log_query = 0) {
  44. if ($log_query) $this->logQuery($q);
  45. ARC2::inc('SPARQLPlusParser');
  46. $p = new ARC2_SPARQLPlusParser($this->a, $this);
  47. $p->parse($q, $src);
  48. $infos = $p->getQueryInfos();
  49. $t1 = ARC2::mtime();
  50. if (!$errs = $p->getErrors()) {
  51. $qt = $infos['query']['type'];
  52. $r = array('query_type' => $qt, 'result' => $this->runQuery($q, $qt, $infos));
  53. }
  54. else {
  55. $r = array('result' => '');
  56. }
  57. $t2 = ARC2::mtime();
  58. $r['query_time'] = $t2 - $t1;
  59. /* query result */
  60. if ($result_format == 'raw') {
  61. return $r['result'];
  62. }
  63. if ($result_format == 'rows') {
  64. return $this->v('rows', array(), $r['result']);
  65. }
  66. if ($result_format == 'row') {
  67. if (!isset($r['result']['rows'])) return array();
  68. return $r['result']['rows'] ? $r['result']['rows'][0] : array();
  69. }
  70. return $r;
  71. }
  72. function runQuery($q, $qt = '', $infos = '') {
  73. /* ep */
  74. $ep = $this->v('remote_store_endpoint', 0, $this->a);
  75. if (!$ep) return false;
  76. /* prefixes */
  77. $q = $this->completeQuery($q);
  78. /* custom handling */
  79. $mthd = 'run' . $this->camelCase($qt) . 'Query';
  80. if (method_exists($this, $mthd)) {
  81. return $this->$mthd($q, $infos);
  82. }
  83. /* http verb */
  84. $mthd = in_array($qt, array('load', 'insert', 'delete')) ? 'POST' : 'GET';
  85. /* reader */
  86. ARC2::inc('Reader');
  87. $reader = new ARC2_Reader($this->a, $this);
  88. $reader->setAcceptHeader('Accept: application/sparql-results+xml; q=0.9, application/rdf+xml; q=0.9, */*; q=0.1');
  89. if ($mthd == 'GET') {
  90. $url = $ep;
  91. $url .= strpos($ep, '?') ? '&' : '?';
  92. $url .= 'query=' . urlencode($q);
  93. if ($k = $this->v('store_read_key', '', $this->a)) $url .= '&key=' . urlencode($k);
  94. }
  95. else {
  96. $url = $ep;
  97. $reader->setHTTPMethod($mthd);
  98. $reader->setCustomHeaders("Content-Type: application/x-www-form-urlencoded");
  99. $suffix = ($k = $this->v('store_write_key', '', $this->a)) ? '&key=' . rawurlencode($k) : '';
  100. $reader->setMessageBody('query=' . rawurlencode($q) . $suffix);
  101. }
  102. $to = $this->v('remote_store_timeout', 0, $this->a);
  103. $reader->activate($url, '', 0, $to);
  104. $format = $reader->getFormat();
  105. $resp = '';
  106. while ($d = $reader->readStream()) {
  107. $resp .= $this->toUTF8($d);
  108. }
  109. $reader->closeStream();
  110. $ers = $reader->getErrors();
  111. $this->a['reader_auth_infos'] = $reader->getAuthInfos();
  112. unset($this->reader);
  113. if ($ers) return array('errors' => $ers);
  114. $mappings = array('rdfxml' => 'RDFXML', 'sparqlxml' => 'SPARQLXMLResult', 'turtle' => 'Turtle');
  115. if (!$format || !isset($mappings[$format])) {
  116. return $resp;
  117. //return $this->addError('No parser available for "' . $format . '" SPARQL result');
  118. }
  119. // Return raw data from endpoint if passthrough_FORMAT specified
  120. $passthrough = $this->v('passthrough_sparqlxml', false, $this->a);
  121. if ($passthrough && isset($infos['output']) && $infos['output'] == 'SPARQLXML') {
  122. return $resp;
  123. }
  124. /* format parser */
  125. $suffix = $mappings[$format] . 'Parser';
  126. ARC2::inc($suffix);
  127. $cls = 'ARC2_' . $suffix;
  128. $parser = new $cls($this->a, $this);
  129. $parser->parse($ep, $resp);
  130. /* ask|load|insert|delete */
  131. if (in_array($qt, array('ask', 'load', 'insert', 'delete'))) {
  132. $bid = $parser->getBooleanInsertedDeleted();
  133. if ($qt == 'ask') {
  134. $r = $bid['boolean'];
  135. }
  136. else {
  137. $r = $bid;
  138. }
  139. }
  140. /* select */
  141. elseif (($qt == 'select') && !method_exists($parser, 'getRows')) {
  142. $r = $resp;
  143. }
  144. elseif ($qt == 'select') {
  145. $r = array('rows' => $parser->getRows(), 'variables' => $parser->getVariables());
  146. }
  147. /* any other */
  148. else {
  149. $r = $parser->getSimpleIndex(0);
  150. }
  151. unset($parser);
  152. return $r;
  153. }
  154. /* */
  155. function optimizeTables() {}
  156. /* */
  157. function getResourceLabel($res, $unnamed_label = 'An unnamed resource') {
  158. if (!isset($this->resource_labels)) $this->resource_labels = array();
  159. if (isset($this->resource_labels[$res])) return $this->resource_labels[$res];
  160. if (!preg_match('/^[a-z0-9\_]+\:[^\s]+$/si', $res)) return $res;/* literal */
  161. $r = '';
  162. if (preg_match('/^\_\:/', $res)) {
  163. return $unnamed_label;
  164. }
  165. $row = $this->query('SELECT ?o WHERE { <' . $res . '> ?p ?o . FILTER(REGEX(str(?p), "(label|name)$", "i"))}', 'row');
  166. if ($row) {
  167. $r = $row['o'];
  168. }
  169. else {
  170. $r = preg_replace("/^(.*[\/\#])([^\/\#]+)$/", '\\2', str_replace('#self', '', $res));
  171. $r = str_replace('_', ' ', $r);
  172. $r = preg_replace('/([a-z])([A-Z])/e', '"\\1 " . strtolower("\\2")', $r);
  173. }
  174. $this->resource_labels[$res] = $r;
  175. return $r;
  176. }
  177. function getDomains($p) {
  178. $r = array();
  179. foreach($this->query('SELECT DISTINCT ?type WHERE {?s <' . $p . '> ?o ; a ?type . }', 'rows') as $row) {
  180. $r[] = $row['type'];
  181. }
  182. return $r;
  183. }
  184. /* */
  185. }