/* Copyright 2006 david reid * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* To build use this command line * * cc -Wall `redland-config --cflags --libs` -o sparql2 sparql2.c * * Run using ./sparql2 , ie ./sparql2 test2.rq */ #include #include #include #include #include #include typedef struct { int enabled; /* are we enabled? */ int remote; /* remote queries OK? 1 = yes, 0 = no */ int fileUris; /* Do we allow URI's of the file:/// format? */ /* Storage */ char *st_name; /* default location for data - how ? */ char *st_type; /* type of storage to use */ char *st_opts; /* store options string */ librdf_storage *store; /* RDF storage pointer */ librdf_model *model; /* the model that represents the data */ /* Query Language */ char *ql_name; /* query language name */ librdf_uri *ql_uri; /* query language URI */ /* Outputs */ int resFormat; /* index of outputFormats[] */ librdf_uri *outputUri; /* URI for output format */ } mod_sparql_state_t; static char *defaultQL = "sparql"; static librdf_world *world = NULL; static librdf_storage *sparqlMakeStorage(mod_sparql_state_t *st, int defaultOK) { librdf_storage *store = NULL; printf("sparqlMakeStorage()\n"); if (st->st_name && st->st_type) { store = librdf_new_storage(world, st->st_type, st->st_name, st->st_opts); } else if (st->st_type) { store = librdf_new_storage(world, st->st_type, NULL, st->st_opts); } else if (st->st_name) { store = librdf_new_storage(world, "hashes", st->st_name, st->st_opts); } else if (defaultOK) { store = librdf_new_storage(world, "hashes", "store/test", "hash-type='bdb'"); } return store; } static librdf_model *fillStoreFromQuery(mod_sparql_state_t *st, unsigned char *query_string, librdf_uri *base_uri, raptor_sequence *source_uris) { librdf_model *model = NULL; librdf_parser *parser = NULL; int i = 0; const char *parser_name = NULL; rasqal_data_graph *graph = NULL; raptor_uri *buri = NULL; rasqal_query *rq = rasqal_new_query(st->ql_name, librdf_uri_to_string(st->ql_uri)); printf("\nfillStoreFromQuery()\n"); if (!rq) { printf("Unable to create new rasqual query\n"); return NULL; } /* Prepare the query */ if (base_uri) buri = raptor_new_uri(librdf_uri_to_string(base_uri)); if (rasqal_query_prepare(rq, query_string, buri)) { printf("Unable to prepare query! '%s'\n", query_string); return NULL; } graph = rasqal_query_get_data_graph(rq, 0); if (base_uri) { parser_name = raptor_guess_parser_name(NULL, NULL, NULL, 0, librdf_uri_as_string(base_uri)); } else if (graph) { parser_name = raptor_guess_parser_name(NULL, NULL, NULL, 0, raptor_uri_as_string(graph->uri)); } if (! parser_name) { printf("Unable to guess parser name\n"); return NULL; } printf("parser_name guessed as '%s'\n", parser_name); parser = librdf_new_parser(world, parser_name, NULL, NULL); if (!parser) { printf("Unable to create a parser for '%s'\n", parser_name); return NULL; } model = librdf_new_model(world, st->store, NULL); if (!model) { librdf_free_parser(parser); printf("Unable to create a model\n"); return NULL; } printf("\nTrying to add required URI's to model...\n"); if (graph) { do { librdf_uri *uri = NULL; uri = librdf_new_uri(world, raptor_uri_as_string(graph->uri)); if (uri) { if (librdf_parser_parse_into_model(parser, uri, base_uri, model)) printf("\tFailed to parse '%s'\n", librdf_uri_as_string(uri)); else printf("\tAdded '%s'\n", librdf_uri_as_string(uri)); librdf_free_uri(uri); } } while ((graph = rasqal_query_get_data_graph(rq, ++i))); } if (source_uris) { printf("adding source uris\n"); while (raptor_sequence_size(source_uris)) { raptor_uri *src = raptor_sequence_pop(source_uris); librdf_uri *uri = librdf_new_uri(world, raptor_uri_as_string(src)); if (uri) { if (librdf_parser_parse_into_model(parser, uri, base_uri, model)) printf("\tFailed to parse '%s'\n", librdf_uri_as_string(uri)); else printf("\tAdded '%s'\n", librdf_uri_as_string(uri)); librdf_free_uri(uri); } raptor_free_uri(src); } } printf("\nFinished adding URI's\nmodel size() = %d\n", librdf_model_size(model)); librdf_free_parser(parser); return model; } static int setQueryLanguage(mod_sparql_state_t *st, const char *mode) { unsigned int i = 0; const char *name = NULL; const char *label = NULL; unsigned const char *uri = NULL; if (st->ql_uri) { librdf_free_uri(st->ql_uri); st->ql_uri = NULL; } st->ql_name = NULL; if (mode) { while (rasqal_languages_enumerate(i, &name, &label, &uri) == 0) { if (strcasecmp(name, mode) == 0) { printf("Found query language '%s' -> %s [%s]\n", name, label, uri); st->ql_name = strdup(name); st->ql_uri = librdf_new_uri(world, uri); return 1; } i++; } } /* Now try for default... */ i = 0; while (rasqal_languages_enumerate(i, &name, &label, &uri) == 0) { if (strcasecmp(name, defaultQL) == 0) { printf("Found DEFAULT query language '%s' -> %s [%s]\n", name, label, uri); st->ql_name = strdup(name); st->ql_uri = librdf_new_uri(world, uri); return 1; } i++; } return 0; } static int rdfError(void *uData, librdf_log_message *msg) { const char *msgStr = librdf_log_message_message(msg); raptor_locator *loc = librdf_log_message_locator(msg); if (loc && loc->file) printf("Redland: %s @ line %d: %s\n", raptor_locator_file(loc), raptor_locator_line(loc), msgStr); else if (msg) printf("Redland: %s\n", msgStr); return 1; } static void usage(void) { printf("Usage: sparql2 \n"); exit(1); } int main(int argc, char **argv) { mod_sparql_state_t st; raptor_sequence *source_uris = NULL; unsigned char *outputStr; char *queryFn = NULL; struct stat stt; FILE *f; unsigned char *buffer = NULL; char *fromptr = NULL; librdf_uri *base_uri = NULL; librdf_model *model = NULL; librdf_query *query; librdf_query_results *results; if (argc < 2) usage(); /* Get query string from file... */ queryFn = argv[1]; printf("queryFn = %s\n", queryFn); if (stat(queryFn, &stt) != 0) { printf("Invalid file specified!\n"); exit(1); } buffer = (unsigned char *)calloc(1, stt.st_size + 1); f = fopen(queryFn, "r"); fread(buffer, 1, stt.st_size, f); fclose(f); buffer[stt.st_size] = '\0'; printf("Query:\n%s\n", buffer); /* Now do SPARQL processing */ world = librdf_new_world(); if (!world) { printf("Unable to create a world!\n"); exit(1); } librdf_world_open(world); librdf_world_set_logger(world, NULL, rdfError); memset(&st, 0, sizeof(st)); setQueryLanguage(&st, NULL); st.store = sparqlMakeStorage(&st, 1); st.outputUri = librdf_new_uri(world, "http://www.w3.org/2005/sparql-results#"); if (!st.store) { printf("Unable to make RDF storage!\n"); exit(1); } /* model = fillStoreFromQuery(&st, buffer, base_uri, source_uris); printf("model = %p\n", model); if (!model) { printf("No graph data configured and unable to create " "data store for query\n"); exit(1); } */ model = st->model; fromptr = strstr(buffer, "FROM"); if (fromptr) { char *end = buffer + stt.st_size + 1; char *ptr = fromptr; while (*ptr != '\n' && *ptr != '\0') ptr++; if (*ptr == '\n') memmove(fromptr, ptr, end - ptr); } printf("Query:\n%s\n", buffer); printf("Creating query...\n"); query = librdf_new_query(world, st.ql_name, st.ql_uri, buffer, base_uri); printf("\tquery = %p\n", query); printf("Executing query against model...\n"); results = librdf_model_query_execute(model, query); if (!results) { printf("Query execution failed\n"); exit(1); } printf("SPARQL query executed OK\n"); printf("results = %p\n", results); printf("outputURI = %p\n", st.outputUri); printf("base_uri = %p\n", base_uri); outputStr = librdf_query_results_to_string(results, st.outputUri, base_uri); if (outputStr != NULL) printf("Output: %p\n%s\n", outputStr, outputStr); else printf("No output created!\n"); exit(0); }