Version 1
[yaffs-website] / vendor / easyrdf / easyrdf / lib / EasyRdf / Sparql / Client.php
diff --git a/vendor/easyrdf/easyrdf/lib/EasyRdf/Sparql/Client.php b/vendor/easyrdf/easyrdf/lib/EasyRdf/Sparql/Client.php
new file mode 100644 (file)
index 0000000..5f97138
--- /dev/null
@@ -0,0 +1,309 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package    EasyRdf
+ * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license    http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class for making SPARQL queries using the SPARQL 1.1 Protocol
+ *
+ * @package    EasyRdf
+ * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license    http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Sparql_Client
+{
+    /** The query/read address of the SPARQL Endpoint */
+    private $queryUri = null;
+
+    private $queryUri_has_params = false;
+
+    /** The update/write address of the SPARQL Endpoint */
+    private $updateUri = null;
+
+    /** Create a new SPARQL endpoint client
+     *
+     * If the query and update endpoints are the same, then you
+     * only need to give a single URI.
+     *
+     * @param string $queryUri The address of the SPARQL Query Endpoint
+     * @param string $updateUri Optional address of the SPARQL Update Endpoint
+     */
+    public function __construct($queryUri, $updateUri = null)
+    {
+        $this->queryUri = $queryUri;
+
+        if (strlen(parse_url($queryUri, PHP_URL_QUERY)) > 0) {
+            $this->queryUri_has_params = true;
+        } else {
+            $this->queryUri_has_params = false;
+        }
+
+        if ($updateUri) {
+            $this->updateUri = $updateUri;
+        } else {
+            $this->updateUri = $queryUri;
+        }
+    }
+
+    /** Get the URI of the SPARQL query endpoint
+     *
+     * @return string The query URI of the SPARQL endpoint
+     */
+    public function getQueryUri()
+    {
+        return $this->queryUri;
+    }
+
+    /** Get the URI of the SPARQL update endpoint
+     *
+     * @return string The query URI of the SPARQL endpoint
+     */
+    public function getUpdateUri()
+    {
+        return $this->updateUri;
+    }
+
+    /**
+     * @depredated
+     * @ignore
+     */
+    public function getUri()
+    {
+        return $this->queryUri;
+    }
+
+    /** Make a query to the SPARQL endpoint
+     *
+     * SELECT and ASK queries will return an object of type
+     * EasyRdf_Sparql_Result.
+     *
+     * CONSTRUCT and DESCRIBE queries will return an object
+     * of type EasyRdf_Graph.
+     *
+     * @param string $query The query string to be executed
+     * @return object EasyRdf_Sparql_Result|EasyRdf_Graph Result of the query.
+     */
+    public function query($query)
+    {
+        return $this->request('query', $query);
+    }
+
+    /** Count the number of triples in a SPARQL 1.1 endpoint
+     *
+     * Performs a SELECT query to estriblish the total number of triples.
+     *
+     * Counts total number of triples by default but a conditional triple pattern
+     * can be given to count of a subset of all triples.
+     *
+     * @param string $condition Triple-pattern condition for the count query
+     * @return integer The number of triples
+     */
+    public function countTriples($condition = '?s ?p ?o')
+    {
+        // SELECT (COUNT(*) AS ?count)
+        // WHERE {
+        //   {?s ?p ?o}
+        //   UNION
+        //   {GRAPH ?g {?s ?p ?o}}
+        // }
+        $result = $this->query('SELECT (COUNT(*) AS ?count) {'.$condition.'}');
+        return $result[0]->count->getValue();
+    }
+
+    /** Get a list of named graphs from a SPARQL 1.1 endpoint
+     *
+     * Performs a SELECT query to get a list of the named graphs
+     *
+     * @param string $limit Optional limit to the number of results
+     * @return array Array of EasyRdf_Resource objects for each named graph
+     */
+    public function listNamedGraphs($limit = null)
+    {
+        $query = "SELECT DISTINCT ?g WHERE {GRAPH ?g {?s ?p ?o}}";
+        if (!is_null($limit)) {
+            $query .= " LIMIT ".(int)$limit;
+        }
+        $result = $this->query($query);
+
+        // Convert the result object into an array of resources
+        $graphs = array();
+        foreach ($result as $row) {
+            array_push($graphs, $row->g);
+        }
+        return $graphs;
+    }
+
+    /** Make an update request to the SPARQL endpoint
+     *
+     * Successful responses will return the HTTP response object
+     *
+     * Unsuccessful responses will throw an exception
+     *
+     * @param string $query The update query string to be executed
+     * @return object EasyRdf_Http_Response HTTP response
+     */
+    public function update($query)
+    {
+        return $this->request('update', $query);
+    }
+
+    public function insert($data, $graphUri = null)
+    {
+        #$this->updateData('INSET',
+        $query = 'INSERT DATA {';
+        if ($graphUri) {
+            $query .= "GRAPH <$graphUri> {";
+        }
+        $query .= $this->convertToTriples($data);
+        if ($graphUri) {
+            $query .= "}";
+        }
+        $query .= '}';
+        return $this->update($query);
+    }
+
+    protected function updateData($operation, $data, $graphUri = null)
+    {
+        $query = "$operation DATA {";
+        if ($graphUri) {
+            $query .= "GRAPH <$graphUri> {";
+        }
+        $query .= $this->convertToTriples($data);
+        if ($graphUri) {
+            $query .= "}";
+        }
+        $query .= '}';
+        return $this->update($query);
+    }
+
+    public function clear($graphUri, $silent = false)
+    {
+        $query = "CLEAR";
+        if ($silent) {
+            $query .= " SILENT";
+        }
+        if (preg_match('/^all|named|default$/i', $graphUri)) {
+            $query .= " $graphUri";
+        } else {
+            $query .= " GRAPH <$graphUri>";
+        }
+        return $this->update($query);
+    }
+
+    /*
+     * Internal function to make an HTTP request to SPARQL endpoint
+     *
+     * @ignore
+     */
+    protected function request($type, $query)
+    {
+        // Check for undefined prefixes
+        $prefixes = '';
+        foreach (EasyRdf_Namespace::namespaces() as $prefix => $uri) {
+            if (strpos($query, "$prefix:") !== false and
+                strpos($query, "PREFIX $prefix:") === false) {
+                $prefixes .=  "PREFIX $prefix: <$uri>\n";
+            }
+        }
+
+        $client = EasyRdf_Http::getDefaultHttpClient();
+        $client->resetParameters();
+
+        // Tell the server which response formats we can parse
+        $accept = EasyRdf_Format::getHttpAcceptHeader(
+            array(
+              'application/sparql-results+json' => 1.0,
+              'application/sparql-results+xml' => 0.8
+            )
+        );
+        $client->setHeaders('Accept', $accept);
+
+        if ($type == 'update') {
+            $client->setMethod('POST');
+            $client->setUri($this->updateUri);
+            $client->setRawData($prefixes . $query);
+            $client->setHeaders('Content-Type', 'application/sparql-update');
+        } elseif ($type == 'query') {
+            // Use GET if the query is less than 2kB
+            // 2046 = 2kB minus 1 for '?' and 1 for NULL-terminated string on server
+            $encodedQuery = 'query='.urlencode($prefixes . $query);
+            if (strlen($encodedQuery) + strlen($this->queryUri) <= 2046) {
+                $delimiter = $this->queryUri_has_params ? '&' : '?';
+
+                $client->setMethod('GET');
+                $client->setUri($this->queryUri.$delimiter.$encodedQuery);
+            } else {
+                // Fall back to POST instead (which is un-cacheable)
+                $client->setMethod('POST');
+                $client->setUri($this->queryUri);
+                $client->setRawData($encodedQuery);
+                $client->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
+            }
+        }
+
+        $response = $client->request();
+        if ($response->getStatus() == 204) {
+            // No content
+            return $response;
+        } elseif ($response->isSuccessful()) {
+            list($type, $params) = EasyRdf_Utils::parseMimeType(
+                $response->getHeader('Content-Type')
+            );
+            if (strpos($type, 'application/sparql-results') === 0) {
+                return new EasyRdf_Sparql_Result($response->getBody(), $type);
+            } else {
+                return new EasyRdf_Graph($this->queryUri, $response->getBody(), $type);
+            }
+        } else {
+            throw new EasyRdf_Exception(
+                "HTTP request for SPARQL query failed: ".$response->getBody()
+            );
+        }
+    }
+
+    protected function convertToTriples($data)
+    {
+        if (is_string($data)) {
+            return $data;
+        } elseif (is_object($data) and $data instanceof EasyRdf_Graph) {
+            # FIXME: insert Turtle when there is a way of seperateing out the prefixes
+            return $data->serialise('ntriples');
+        } else {
+            throw new EasyRdf_Exception(
+                "Don't know how to convert to triples for SPARQL query: ".$response->getBody()
+            );
+        }
+    }
+}