Exemple #1
0
 /**
  * This method sends a SPARQL query to the store.
  *
  * @param  string     $query            The SPARQL query to send to the store.
  * @param  array      $options optional It contains key-value pairs and should provide additional
  *                                      introductions for the store and/or its adapter(s).
  * @return Result     Returns result of the query. Its type depends on the type of the query.
  * @throws \Exception If query is no string.
  * @throws \Exception If query is malformed.
  * @throws \Exception If query is a DELETE query and contains quads, where the graph of one quad is of type var
  * @throws \Exception If a non-graph query contains no triples and quads.
  * @todo handle multiple graphs in FROM clause
  */
 public function query($query, array $options = array())
 {
     $queryObject = $this->queryFactory->createInstanceByQueryString($query);
     $queryParts = $queryObject->getQueryParts();
     // if a non-graph query was given, we assume triples or quads. If neither quads nor triples were found,
     // throw an exception.
     if (false === $queryObject->isGraphQuery() && false === isset($queryParts['triple_pattern']) && false === isset($queryParts['quad_pattern'])) {
         throw new \Exception('Non-graph queries must have triples or quads.');
     }
     // execute query on the store
     $result = $this->store->query($query);
     /*
     * special case: if you execute a SELECT COUNT(*) query, ARC2 will return the number of triples
                   instead of a result set
     */
     $countCheck = preg_match('/selectcount\\([a-z*]\\)(from|where)/si', preg_replace('/\\s+/', '', $query));
     if (1 == $countCheck) {
         $variable = 'callret-0';
         // build a set result, because the user expects it as result type because a SELECT query
         // was sent.
         $setResult = $this->resultFactory->createSetResult(array(array($variable => $this->nodeFactory->createLiteral($result, 'http://www.w3.org/2001/XMLSchema#int'))));
         $setResult->setVariables(array($variable));
         return $setResult;
         /*
          * ARC2 does not support quads, especially not in DELETE queries. The following code construct
          * tries to close that gap by transforming the query in a one which ARC2 can understand.
          *
          * This part transform queries of the kind:
          *
          *      DELETE WHERE {
          *          Graph <http://localhost/Saft/TestGraph/> {
          *              ?s ?p ?o .
          *          }
          *      }
          *
          * to SPARQL+ ones:
          *
          *      DELETE FROM <http://localhost/Saft/TestGraph/> {
          *          ?s ?p ?o .
          *      }
          *      WHERE {
          *          ?s ?p ?o .
          *      }
          *
          *
          * IMPORTANT: Please adapt
          *            https://github.com/SaftIng/safting.github.io/blob/master/doc/phpframework/addition/ARC2.md
          *            if you change the support for SPARQL 1.0/1.1 here!
          */
     } elseif ($queryObject->isUpdateQuery() && isset($queryParts['quad_pattern']) && 'deleteWhere' === $queryParts['sub_type']) {
         foreach ($queryParts['quad_pattern'] as $quad) {
             if ('uri' != $quad['g_type']) {
                 throw new \Exception('The graph of a quad must be an URI here.');
             }
             // subject
             $s = NodeUtils::createNodeInstance($this->nodeFactory, $quad['s'], $quad['s_type']);
             $s = SparqlUtils::getNodeInSparqlFormat($s);
             // predicate
             $p = NodeUtils::createNodeInstance($this->nodeFactory, $quad['p'], $quad['p_type']);
             $p = SparqlUtils::getNodeInSparqlFormat($p);
             // object
             $o = NodeUtils::createNodeInstance($this->nodeFactory, $quad['o'], $quad['o_type'], $quad['o_datatype'], $quad['o_lang']);
             $o = SparqlUtils::getNodeInSparqlFormat($o);
             return $this->query('DELETE FROM <' . $quad['g'] . '> {' . $s . ' ' . $p . ' ' . $o . ' }
                 WHERE {' . $s . ' ' . $p . ' ' . $o . ' }');
         }
         /*
          * SELECT query
          */
     } elseif ('selectQuery' === AbstractQuery::getQueryType($query)) {
         /*
          * For a SELECT query the result looks like:
          *
          * array(
          *      'query_time' => 0.2
          *      'query_type' => 'select',
          *      'result' => array(
          *          'variables' => array('s', 'o')
          *          'rows' =>
          *              array(
          *                  's' => "http://s/"
          *                  's type' => 'uri',
          *                  'o' => '42',
          *                  'o type' => "literal"
          *                  'o datatype' => "http://www.w3.org/2001/XMLSchema#string"
          *              )
          */
         $entries = array();
         // go through all rows
         foreach ($result['result']['rows'] as $row) {
             $newEntry = array();
             foreach ($result['result']['variables'] as $variable) {
                 // checks for variable type
                 // example: $row['s type']
                 switch ($row[$variable . ' type']) {
                     // ARC2 does not differenciate between typed literal and literal, like Virtuoso does
                     // for instance. You have to check for lang and datatype key by yourself.
                     case 'literal':
                         // if language is set
                         if (isset($row[$variable . ' lang'])) {
                             $newEntry[$variable] = $this->nodeFactory->createLiteral($row[$variable], 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', $row[$variable . ' lang']);
                             // if datatype is set
                         } elseif (isset($row[$variable . ' datatype'])) {
                             $newEntry[$variable] = $this->nodeFactory->createLiteral($row[$variable], $row[$variable . ' datatype']);
                             // if neither one is set, we assume its a string and use xsd:string as datatype
                         } else {
                             $newEntry[$variable] = $this->nodeFactory->createLiteral($row[$variable], 'http://www.w3.org/2001/XMLSchema#string');
                         }
                         break;
                     case 'uri':
                         $newEntry[$variable] = $this->nodeFactory->createNamedNode($row[$variable]);
                         break;
                 }
             }
             $entries[] = $newEntry;
         }
         // Create and fill SetResult instance
         $setResult = $this->resultFactory->createSetResult($entries);
         $setResult->setVariables($result['result']['variables']);
         return $setResult;
     } else {
         if ('askQuery' === AbstractQuery::getQueryType($query)) {
             return $this->resultFactory->createValueResult($result['result']);
         } else {
             return $this->resultFactory->createEmptyResult();
         }
     }
 }
 /**
  * Returns the Statement-Data in sparql-Format.
  *
  * @param StatementIterator $statements   List of statements to format as SPARQL string.
  * @param string            $graphUri     Use if each statement is a triple and to use another graph as
  *                                        the default.
  * @return string, part of query
  */
 protected function sparqlFormat(StatementIterator $statements, Node $graph = null)
 {
     return SparqlUtils::statementIteratorToSparqlFormat($statements, $graph);
 }
 public function testQueryDeleteMultipleStatementsStatementsWithLiteral()
 {
     /**
      * create test data
      */
     $this->fixture->query('CLEAR GRAPH <' . $this->testGraph->getUri() . '>');
     $this->assertEquals(0, $this->countTriples($this->testGraph));
     $subject2 = new NamedNodeImpl('http://saft/test/s1');
     $predicate2 = new NamedNodeImpl('http://saft/test/p2');
     $object2 = new LiteralImpl('Emma');
     $statement = new StatementImpl($subject2, $predicate2, $object2);
     // add two statements with literal
     $statements = array($this->getTestStatementWithLiteral(), $statement);
     $this->fixture->addStatements($statements, $this->testGraph);
     // check that test data was created
     $this->assertEquals(2, $this->countTriples($this->testGraph));
     /*
      * remove test data via query
      */
     $triplePart = SparqlUtils::statementsToSparqlFormat(array($this->getTestPatternStatement()));
     $query = 'DELETE WHERE { Graph <' . $this->testGraph . '> {' . $triplePart . '}}';
     $this->assertTrue($this->fixture->query($query)->isEmptyResult());
     // check that test data was removed
     $this->assertEquals(0, $this->countTriples($this->testGraph));
 }
 public function testHasMatchingStatementTripleRecognition()
 {
     $triple = $this->getTestTriple();
     $this->fixture->addStatements(array($triple), $this->testGraph);
     $query = 'ASK { ' . SparqlUtils::statementsToSparqlFormat(array($triple), $this->testGraph) . '}';
     $this->assertTrue($this->fixture->query($query));
 }
Exemple #5
0
 public function testStatementIteratorToSparqlFormatTripleAndQuad()
 {
     $triple = new StatementImpl(new NamedNodeImpl('http://saft/test/s1'), new NamedNodeImpl('http://saft/test/p1'), new LiteralImpl("42"));
     $quad = new StatementImpl(new NamedNodeImpl('http://saft/test/s1'), new NamedNodeImpl('http://saft/test/p1'), new LiteralImpl("42"), $this->testGraph);
     $this->assertEquals('<http://saft/test/s1> <http://saft/test/p1> "42"^^<http://www.w3.org/2001/XMLSchema#string> .  ' . 'Graph <http://localhost/Saft/TestGraph/> {<http://saft/test/s1> <http://saft/test/p1> ' . '"42"^^<http://www.w3.org/2001/XMLSchema#string> . }', trim(SparqlUtils::statementIteratorToSparqlFormat(array($triple, $quad))));
 }