LCOV - code coverage report
Current view: directory - slv2/src - query.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 91 84 92.3 %
Date: 2009-05-26 Functions: 12 12 100.0 %

       1                 : /* SLV2
       2                 :  * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
       3                 :  *
       4                 :  * This library is free software; you can redistribute it and/or modify it
       5                 :  * under the terms of the GNU General Public License as published by the Free
       6                 :  * Software Foundation; either version 2 of the License, or (at your option)
       7                 :  * any later version.
       8                 :  *
       9                 :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10                 :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      11                 :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      12                 :  * for more details.
      13                 :  *
      14                 :  * You should have received a copy of the GNU General Public License along
      15                 :  * with this program; if not, write to the Free Software Foundation, Inc.,
      16                 :  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      17                 :  */
      18                 : 
      19                 : #define _XOPEN_SOURCE 500
      20                 : #include <assert.h>
      21                 : #include <librdf.h>
      22                 : #include <limits.h>
      23                 : #include <locale.h>
      24                 : #include <stdlib.h>
      25                 : #include <string.h>
      26                 : #include "slv2/types.h"
      27                 : #include "slv2/collections.h"
      28                 : #include "slv2/plugin.h"
      29                 : #include "slv2/query.h"
      30                 : #include "slv2/util.h"
      31                 : #include "slv2_internal.h"
      32                 : 
      33                 : 
      34                 : static const char* slv2_query_prefixes =
      35                 :         "PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
      36                 :         "PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>\n"
      37                 :         "PREFIX doap:   <http://usefulinc.com/ns/doap#>\n"
      38                 :         "PREFIX foaf:   <http://xmlns.com/foaf/0.1/>\n"
      39                 :         "PREFIX lv2:    <http://lv2plug.in/ns/lv2core#>\n"
      40                 :         "PREFIX lv2ev:  <http://lv2plug.in/ns/ext/event#>\n";
      41                 : 
      42                 : 
      43                 : /** Create a new SLV2Value from a librdf_node, or return NULL if impossible */
      44                 : SLV2Value
      45                 : slv2_value_from_librdf_node(SLV2World world, librdf_node* node)
      46              51 : {
      47              51 :         SLV2Value result = NULL;
      48                 : 
      49              51 :         librdf_uri* datatype_uri = NULL;
      50              51 :         SLV2ValueType type = SLV2_VALUE_STRING;
      51                 : 
      52              51 :         switch (librdf_node_get_type(node)) {
      53                 :         case LIBRDF_NODE_TYPE_RESOURCE:
      54              25 :                 type = SLV2_VALUE_URI;
      55              25 :                 result = slv2_value_new_librdf_uri(world, librdf_node_get_uri(node));
      56              25 :                 break;
      57                 :         case LIBRDF_NODE_TYPE_LITERAL:
      58              25 :                 datatype_uri = librdf_node_get_literal_value_datatype_uri(node);
      59              25 :                 if (datatype_uri) {
      60               8 :                         if (!strcmp((const char*)librdf_uri_as_string(datatype_uri),
      61                 :                                                 "http://www.w3.org/2001/XMLSchema#integer"))
      62               6 :                                 type = SLV2_VALUE_INT;
      63               2 :                         else if (!strcmp((const char*)librdf_uri_as_string(datatype_uri),
      64                 :                                                 "http://www.w3.org/2001/XMLSchema#decimal"))
      65               2 :                                 type = SLV2_VALUE_FLOAT;
      66                 :                         else
      67               0 :                                 fprintf(stderr, "Unknown datatype %s\n", librdf_uri_as_string(datatype_uri));
      68                 :                 }
      69              25 :                 result = slv2_value_new(world, type, (const char*)librdf_node_get_literal_value(node));
      70              25 :                 break;
      71                 :         case LIBRDF_NODE_TYPE_BLANK:
      72               1 :                 type = SLV2_VALUE_STRING;
      73               1 :                 result = slv2_value_new(world, type, (const char*)librdf_node_get_blank_identifier(node));
      74               1 :                 break;
      75                 :         case LIBRDF_NODE_TYPE_UNKNOWN:
      76                 :         default:
      77               0 :                 fprintf(stderr, "Unknown RDF node type %d\n", librdf_node_get_type(node));
      78                 :                 break;
      79                 :         }
      80                 : 
      81              51 :         return result;
      82                 : }
      83                 : 
      84                 : 
      85                 : SLV2Values
      86                 : slv2_query_get_variable_bindings(SLV2World   world,
      87                 :                                  SLV2Results results,
      88                 :                                  int         variable)
      89              45 : {
      90              45 :         SLV2Values result = NULL;
      91                 : 
      92              45 :     if (!librdf_query_results_finished(results->rdf_results))
      93              42 :                 result = slv2_values_new();
      94                 : 
      95             133 :         while (!librdf_query_results_finished(results->rdf_results)) {
      96              43 :                 librdf_node* node = librdf_query_results_get_binding_value(results->rdf_results, variable);
      97                 : 
      98              43 :                 if (node == NULL) {
      99               0 :                         fprintf(stderr, "SLV2 ERROR: Variable %d bound to NULL.\n", variable);
     100               0 :                         librdf_query_results_next(results->rdf_results);
     101               0 :                         continue;
     102                 :                 }
     103                 : 
     104              43 :                 SLV2Value val = slv2_value_from_librdf_node(world, node);
     105              43 :                 if (val)
     106              43 :                         raptor_sequence_push(result, val);
     107                 : 
     108              43 :                 librdf_free_node(node);
     109              43 :                 librdf_query_results_next(results->rdf_results);
     110                 :         }
     111                 : 
     112              45 :     return result;
     113                 : }
     114                 : 
     115                 : 
     116                 : unsigned
     117                 : slv2_results_size(SLV2Results results)
     118               2 : {
     119               2 :         size_t count = 0;
     120                 : 
     121               5 :         while (!slv2_results_finished(results)) {
     122               1 :                 ++count;
     123               1 :                 slv2_results_next(results);
     124                 :         }
     125                 : 
     126               2 :     return count;
     127                 : }
     128                 : 
     129                 : 
     130                 : SLV2Results
     131                 : slv2_plugin_query_sparql(SLV2Plugin  plugin,
     132                 :                          const char* sparql_str)
     133              61 : {
     134              61 :         slv2_plugin_load_if_necessary(plugin);
     135                 : 
     136              61 :         librdf_uri* base_uri = slv2_value_as_librdf_uri(plugin->plugin_uri);
     137                 : 
     138              61 :         char* query_str = slv2_strjoin(slv2_query_prefixes, sparql_str, NULL);
     139                 : 
     140                 :         //printf("******** Query \n%s********\n", query_str);
     141                 : 
     142                 :         librdf_query* query = librdf_new_query(plugin->world->world, "sparql", NULL,
     143              61 :                         (const unsigned char*)query_str, base_uri);
     144                 : 
     145              61 :         if (!query) {
     146               0 :                 fprintf(stderr, "ERROR: Could not create query\n");
     147               0 :                 return NULL;
     148                 :         }
     149                 : 
     150                 :         // FIXME: locale kludges to work around librdf bug
     151              61 :         char* locale = strdup(setlocale(LC_NUMERIC, NULL));
     152                 : 
     153              61 :         setlocale(LC_NUMERIC, "POSIX");
     154              61 :         librdf_query_results* results = librdf_query_execute(query, plugin->rdf);
     155              61 :         setlocale(LC_NUMERIC, locale);
     156                 : 
     157              61 :         free(locale);
     158                 : 
     159              61 :         librdf_free_query(query);
     160              61 :         free(query_str);
     161                 : 
     162              61 :         SLV2Results ret = (SLV2Results)malloc(sizeof(struct _SLV2Results));
     163              61 :         ret->world = plugin->world;
     164              61 :         ret->rdf_results = results;
     165                 : 
     166              61 :         return ret;
     167                 : }
     168                 : 
     169                 : 
     170                 : void
     171                 : slv2_results_free(SLV2Results results)
     172              61 : {
     173              61 :         librdf_free_query_results(results->rdf_results);
     174              61 :         free(results);
     175              61 : }
     176                 : 
     177                 : 
     178                 : bool
     179                 : slv2_results_finished(SLV2Results results)
     180               9 : {
     181               9 :         return librdf_query_results_finished(results->rdf_results);
     182                 : }
     183                 : 
     184                 : 
     185                 : SLV2Value
     186                 : slv2_results_get_binding_value(SLV2Results results, unsigned index)
     187               6 : {
     188               6 :         return slv2_value_from_librdf_node(results->world,
     189                 :                         librdf_query_results_get_binding_value(
     190                 :                                         results->rdf_results, index));
     191                 : }
     192                 : 
     193                 : 
     194                 : SLV2Value
     195                 : slv2_results_get_binding_value_by_name(SLV2Results results, const char* name)
     196               2 : {
     197               2 :         return slv2_value_from_librdf_node(results->world,
     198                 :                         librdf_query_results_get_binding_value_by_name(
     199                 :                                         results->rdf_results, name));
     200                 : }
     201                 : 
     202                 : 
     203                 : const char*
     204                 : slv2_results_get_binding_name(SLV2Results results, unsigned index)
     205               2 : {
     206               2 :         return librdf_query_results_get_binding_name(results->rdf_results, index);
     207                 : }
     208                 : 
     209                 : 
     210                 : void
     211                 : slv2_results_next(SLV2Results results)
     212               3 : {
     213               3 :         librdf_query_results_next(results->rdf_results);
     214               3 : }
     215                 : 
     216                 : 
     217                 : /** Query a single variable */
     218                 : SLV2Values
     219                 : slv2_plugin_query_variable(SLV2Plugin  plugin,
     220                 :                            const char* sparql_str,
     221                 :                            unsigned    variable)
     222              45 : {
     223              45 :         assert(variable < INT_MAX);
     224                 : 
     225              45 :         SLV2Results results = slv2_plugin_query_sparql(plugin, sparql_str);
     226                 : 
     227                 :         SLV2Values ret = slv2_query_get_variable_bindings(plugin->world,
     228              45 :                         results, (int)variable);
     229                 : 
     230              45 :         slv2_results_free(results);
     231                 : 
     232              45 :         return ret;
     233                 : }
     234                 : 
     235                 : 
     236                 : /** Run a query and count number of matches.
     237                 :  *
     238                 :  * More efficient than slv2_plugin_simple_query if you're only interested
     239                 :  * in the number of results (ie slv2_plugin_num_ports).
     240                 :  *
     241                 :  * Note the result of this function is probably meaningless unless the query
     242                 :  * is a SELECT DISTINCT.
     243                 :  */
     244                 : unsigned
     245                 : slv2_plugin_query_count(SLV2Plugin  plugin,
     246                 :                         const char* sparql_str)
     247               2 : {
     248               2 :         SLV2Results results = slv2_plugin_query_sparql(plugin, sparql_str);
     249                 : 
     250               2 :         unsigned ret = 0;
     251                 : 
     252               2 :         if (results) {
     253               2 :                 ret = slv2_results_size(results);
     254               2 :                 slv2_results_free(results);
     255                 :         }
     256                 : 
     257               2 :         return ret;
     258                 : }
     259                 : 

Generated by: LCOV version 1.7