annotate examples/runner-rdf/populate.c @ 554:600b87550b83

Improve the behaviour of the RDF example a little bit. Automatically create the database if it doesn't exist yet. Write a little explanatory comment about how we could be cleverer.
author mas01cr
date Fri, 13 Feb 2009 11:23:13 +0000
parents ea341e68649f
children d25eb017b68e
rev   line source
mas01cr@554 1 #include <sys/types.h>
mas01cr@553 2 #include <sys/stat.h>
mas01cr@554 3 #include <unistd.h>
mas01cr@553 4 #include <librdf.h>
mas01cr@553 5 #include <fcntl.h>
mas01cr@553 6 #include <string.h>
mas01cr@553 7 #include <stdlib.h>
mas01cr@553 8
mas01cr@553 9 #include <audioDB_API.h>
mas01cr@553 10
mas01cr@553 11 const char * qstring =
mas01cr@553 12 " PREFIX af: <http://purl.org/ontology/af/>"
mas01cr@553 13 " PREFIX dc: <http://purl.org/dc/elements/1.1/>"
mas01cr@553 14 " PREFIX mo: <http://purl.org/ontology/mo/>"
mas01cr@553 15 " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>"
mas01cr@553 16
mas01cr@553 17 " SELECT ?key ?value ?sample_rate ?window_length ?hop_size"
mas01cr@553 18 " FROM <file:///home/csr21/tmp/rdf/test.n3> "
mas01cr@553 19
mas01cr@553 20 " WHERE { "
mas01cr@553 21
mas01cr@553 22 " ?signal mo:available_as ?key ."
mas01cr@553 23
mas01cr@553 24 " ?signal mo:time [ tl:onTimeLine ?signal_timeline ] . "
mas01cr@553 25
mas01cr@553 26 " ?timeline_map a tl:UniformSamplingWindowingMap ; "
mas01cr@553 27 " tl:rangeTimeLine ?feature_timeline ; "
mas01cr@553 28 " tl:domainTimeLine ?signal_timeline ; "
mas01cr@553 29 " tl:sampleRate ?sample_rate ; "
mas01cr@553 30 " tl:windowLength ?window_length ; "
mas01cr@553 31 " tl:hopSize ?hop_size . "
mas01cr@553 32
mas01cr@553 33 " ?signal af:signal_feature ?feature . "
mas01cr@553 34
mas01cr@553 35 " ?feature a ?feature_signal_type ; "
mas01cr@553 36 " mo:time [ tl:onTimeLine ?feature_timeline ] ; "
mas01cr@553 37 " af:value ?value . "
mas01cr@553 38
mas01cr@553 39 " ?feature_signal_type dc:title \"Key Strength Plot\""
mas01cr@553 40
mas01cr@553 41 " } "
mas01cr@553 42 ;
mas01cr@553 43
mas01cr@553 44 double *parse_value_string(const char *value_string, size_t *nelements) {
mas01cr@553 45 /* What error checking? */
mas01cr@553 46
mas01cr@553 47 *nelements = 0;
mas01cr@553 48
mas01cr@553 49 const char *current = value_string;
mas01cr@553 50 char *next = 0;
mas01cr@553 51
mas01cr@553 52 size_t size = 1;
mas01cr@553 53 double *buf = (double *) malloc(size * sizeof(double));
mas01cr@553 54 double value = strtod(current, &next);
mas01cr@553 55 while(next != current) {
mas01cr@553 56 buf[(*nelements)++] = value;
mas01cr@553 57 if((*nelements) == size) {
mas01cr@553 58 size *= 2;
mas01cr@553 59 buf = (double *) realloc(buf, 2 * size * sizeof(double));
mas01cr@553 60 }
mas01cr@553 61 current = next;
mas01cr@553 62 value = strtod(current, &next);
mas01cr@553 63 }
mas01cr@553 64
mas01cr@553 65 }
mas01cr@553 66
mas01cr@553 67 int main() {
mas01cr@554 68 librdf_world *world;
mas01cr@554 69 if (!(world = librdf_new_world()))
mas01cr@554 70 goto librdf_error;
mas01cr@553 71
mas01cr@554 72 librdf_storage *storage;
mas01cr@554 73 if (!(storage = librdf_new_storage(world, "memory", NULL, NULL)))
mas01cr@554 74 goto librdf_error;
mas01cr@553 75
mas01cr@554 76 librdf_model *model;
mas01cr@554 77 if (!(model = librdf_new_model(world, storage, NULL)))
mas01cr@554 78 goto librdf_error;
mas01cr@553 79
mas01cr@554 80 librdf_uri *uri;
mas01cr@554 81 if (!(uri = librdf_new_uri(world, "file:data/test.n3")))
mas01cr@554 82 goto librdf_error;
mas01cr@553 83
mas01cr@554 84 librdf_parser *parser;
mas01cr@554 85 if (!(parser = librdf_new_parser(world, "guess", NULL, NULL)))
mas01cr@554 86 goto librdf_error;
mas01cr@553 87
mas01cr@554 88 if(librdf_parser_parse_into_model(parser, uri, NULL, model))
mas01cr@554 89 goto librdf_error;
mas01cr@553 90
mas01cr@554 91 librdf_query *query;
mas01cr@554 92 if (!(query = librdf_new_query(world, "sparql", NULL, qstring, NULL)))
mas01cr@554 93 goto librdf_error;
mas01cr@553 94
mas01cr@554 95 librdf_query_results *results;
mas01cr@554 96 if (!(results = librdf_query_execute(query, model)))
mas01cr@554 97 goto librdf_error;
mas01cr@553 98
mas01cr@554 99 if(!librdf_query_results_is_bindings(results))
mas01cr@554 100 goto librdf_error;
mas01cr@554 101
mas01cr@554 102 adb_t *adb;
mas01cr@554 103 if(!(adb = audiodb_open("keyplot.adb", O_RDWR))) {
mas01cr@554 104 struct stat st;
mas01cr@554 105 if(!(stat("keyplot.adb", &st))) {
mas01cr@554 106 fprintf(stderr, "keyplot.adb not opened.\n");
mas01cr@554 107 return 1;
mas01cr@554 108 } else {
mas01cr@554 109 /* FIXME: if we are doing a proper SPARQL query over a
mas01cr@554 110 * potentially unbounded number of results, we could use
mas01cr@554 111 * librdf_query_results_get_count() to estimate how much space
mas01cr@554 112 * our database will need.
mas01cr@554 113
mas01cr@554 114 * If we're doing a SPARQL query over a number of RDF files,
mas01cr@554 115 * with an expected number of datasets per file of 1 (as might
mas01cr@554 116 * be produced by runner(?)) then obviously we can use that as
mas01cr@554 117 * an estimate of number of tracks instead.
mas01cr@554 118
mas01cr@554 119 * Specifying the data dimensionality should be easy from the
mas01cr@554 120 * semantics of the feature being inserted; it's not immediately
mas01cr@554 121 * obvious to me how to estimate the data size required, unless
mas01cr@554 122 * we maybe do a preliminary query to find out the total time
mas01cr@554 123 * (or similar) of all the tracks we're about to insert.
mas01cr@554 124
mas01cr@554 125 * (also NOTE: this audiodb_create() interface is scheduled for
mas01cr@554 126 * being made less inelegant.) */
mas01cr@554 127 if(!(adb = audiodb_create("keyplot.adb", 0, 0, 0))) {
mas01cr@554 128 fprintf(stderr, "failed to create keyplot.adb.\n");
mas01cr@554 129 return 1;
mas01cr@554 130 }
mas01cr@554 131 }
mas01cr@553 132 }
mas01cr@554 133
mas01cr@553 134 while(!librdf_query_results_finished(results)) {
mas01cr@553 135 int count = librdf_query_results_get_bindings_count(results);
mas01cr@553 136 adb_datum_t datum = {0};
mas01cr@553 137 datum.dim = 25;
mas01cr@553 138 for (int i = 0; i < count; i++) {
mas01cr@553 139 const char *name = librdf_query_results_get_binding_name(results, i);
mas01cr@553 140 librdf_node *node = librdf_query_results_get_binding_value(results, i);
mas01cr@553 141 if(!node) return 2;
mas01cr@553 142
mas01cr@553 143 if(!strcmp(name, "key")) {
mas01cr@553 144 datum.key = librdf_uri_as_string(librdf_node_get_uri(node));
mas01cr@553 145 } else if(!strcmp(name, "value")) {
mas01cr@553 146 size_t nelements = 0;
mas01cr@553 147 datum.data = parse_value_string(librdf_node_get_literal_value(node), &nelements);
mas01cr@553 148 if(nelements % 25) return 4;
mas01cr@553 149 datum.nvectors = nelements / 25;
mas01cr@553 150 } else {
mas01cr@554 151 /* do something with the timeline (and other) information */
mas01cr@553 152 printf("%s: %s\n", name, librdf_node_get_literal_value(node));
mas01cr@553 153 }
mas01cr@553 154 librdf_free_node(node);
mas01cr@553 155 }
mas01cr@553 156 if(audiodb_insert_datum(adb, &datum)) {
mas01cr@554 157 fprintf(stderr, "failed to insert datum with key %s.\n", datum.key);
mas01cr@554 158 return 1;
mas01cr@553 159 }
mas01cr@553 160 librdf_query_results_next(results);
mas01cr@553 161 }
mas01cr@553 162
mas01cr@553 163 audiodb_close(adb);
mas01cr@553 164 librdf_free_query_results(results);
mas01cr@553 165 librdf_free_query(query);
mas01cr@553 166 librdf_free_uri(uri);
mas01cr@553 167 librdf_free_model(model);
mas01cr@553 168 librdf_free_storage(storage);
mas01cr@553 169 librdf_free_world(world);
mas01cr@554 170
mas01cr@554 171 return 0;
mas01cr@554 172
mas01cr@554 173 librdf_error:
mas01cr@554 174 fprintf(stderr, "Something went wrong in librdf.\n");
mas01cr@554 175 return 1;
mas01cr@553 176 }