annotate examples/runner-rdf/populate.c @ 601:82d23418d867

Fix some fd leaks in the command-line binary Strictly speaking, they're not really leaks, because the only codepath that suffers from these leaks exits immediately afterwards. On the other hand, this fix makes valgrind on e.g. tests/0025 happier, going from 5 errors to none.
author mas01cr
date Fri, 14 Aug 2009 16:39:32 +0000
parents 46673db7c6a4
children 404222029e27
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
mas01mj@583 17 " SELECT ?key ?value ?sample_rate ?window_length ?hop_size ?dimensions ?typetitle"
mas01mj@583 18 " FROM <file:///home/csr21/tmp/rdf/test2.n3> "
mas01cr@553 19
mas01cr@553 20 " WHERE { "
mas01mj@583 21 " ?key a mo:AudioFile . "
mas01mj@583 22 " ?signal a mo:Signal . "
mas01mj@583 23 " ?key mo:encodes ?signal ."
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 . "
mas01mj@583 38 " ?feature af:dimensions ?dimensions ."
mas01cr@553 39
mas01mj@583 40 " ?feature_signal_type dc:title ?typetitle "
mas01cr@553 41
mas01cr@553 42 " } "
mas01cr@553 43 ;
mas01cr@553 44
mas01cr@553 45 double *parse_value_string(const char *value_string, size_t *nelements) {
mas01cr@553 46 /* What error checking? */
mas01cr@553 47
mas01mj@583 48
mas01cr@553 49 *nelements = 0;
mas01cr@553 50
mas01cr@553 51 const char *current = value_string;
mas01cr@553 52 char *next = 0;
mas01cr@553 53
mas01cr@553 54 size_t size = 1;
mas01cr@553 55 double *buf = (double *) malloc(size * sizeof(double));
mas01cr@553 56 double value = strtod(current, &next);
mas01cr@553 57 while(next != current) {
mas01cr@553 58 buf[(*nelements)++] = value;
mas01cr@553 59 if((*nelements) == size) {
mas01cr@553 60 size *= 2;
mas01cr@553 61 buf = (double *) realloc(buf, 2 * size * sizeof(double));
mas01cr@553 62 }
mas01cr@553 63 current = next;
mas01cr@553 64 value = strtod(current, &next);
mas01cr@553 65 }
mas01cr@571 66 return buf;
mas01cr@553 67 }
mas01cr@553 68
mas01mj@583 69 int main(int argc, char* argv[]) {
mas01mj@583 70
mas01mj@583 71 if(argc != 3)
mas01mj@583 72 {
mas01mj@583 73 fprintf(stderr, "Usage: %s <n3file> <dbfile>\n", argv[0]);
mas01mj@583 74 return 2;
mas01mj@583 75 }
mas01mj@583 76
mas01mj@583 77 char* n3file = argv[1];
mas01mj@583 78 char* dbfile = argv[2];
mas01mj@583 79
mas01cr@554 80 librdf_world *world;
mas01cr@554 81 if (!(world = librdf_new_world()))
mas01cr@554 82 goto librdf_error;
mas01cr@553 83
mas01cr@554 84 librdf_storage *storage;
mas01cr@554 85 if (!(storage = librdf_new_storage(world, "memory", NULL, NULL)))
mas01cr@554 86 goto librdf_error;
mas01cr@553 87
mas01cr@554 88 librdf_model *model;
mas01cr@554 89 if (!(model = librdf_new_model(world, storage, NULL)))
mas01cr@554 90 goto librdf_error;
mas01mj@583 91
mas01mj@583 92
mas01mj@583 93 char *fileUri = malloc(sizeof(char)*(strlen(n3file)+6));
mas01mj@583 94 sprintf(fileUri, "file:%s\0", n3file);
mas01cr@553 95
mas01cr@554 96 librdf_uri *uri;
mas01mj@583 97 if (!(uri = librdf_new_uri(world, fileUri)))
mas01cr@554 98 goto librdf_error;
mas01cr@553 99
mas01mj@583 100 free(fileUri);
mas01mj@583 101
mas01cr@554 102 librdf_parser *parser;
mas01cr@554 103 if (!(parser = librdf_new_parser(world, "guess", NULL, NULL)))
mas01cr@554 104 goto librdf_error;
mas01cr@553 105
mas01cr@554 106 if(librdf_parser_parse_into_model(parser, uri, NULL, model))
mas01cr@554 107 goto librdf_error;
mas01cr@553 108
mas01cr@554 109 librdf_query *query;
mas01cr@554 110 if (!(query = librdf_new_query(world, "sparql", NULL, qstring, NULL)))
mas01cr@554 111 goto librdf_error;
mas01cr@553 112
mas01cr@554 113 librdf_query_results *results;
mas01cr@554 114 if (!(results = librdf_query_execute(query, model)))
mas01cr@554 115 goto librdf_error;
mas01cr@553 116
mas01cr@554 117 if(!librdf_query_results_is_bindings(results))
mas01cr@554 118 goto librdf_error;
mas01cr@554 119
mas01cr@554 120 adb_t *adb;
mas01mj@583 121 if(!(adb = audiodb_open(dbfile, O_RDWR))) {
mas01mj@583 122
mas01cr@554 123 struct stat st;
mas01mj@583 124 if(!(stat(dbfile, &st))) {
mas01mj@583 125 fprintf(stderr, "%s not opened.\n", dbfile);
mas01cr@554 126 return 1;
mas01cr@554 127 } else {
mas01cr@554 128 /* FIXME: if we are doing a proper SPARQL query over a
mas01cr@554 129 * potentially unbounded number of results, we could use
mas01cr@554 130 * librdf_query_results_get_count() to estimate how much space
mas01cr@554 131 * our database will need.
mas01cr@554 132
mas01cr@554 133 * If we're doing a SPARQL query over a number of RDF files,
mas01cr@554 134 * with an expected number of datasets per file of 1 (as might
mas01cr@554 135 * be produced by runner(?)) then obviously we can use that as
mas01cr@554 136 * an estimate of number of tracks instead.
mas01cr@554 137
mas01cr@554 138 * Specifying the data dimensionality should be easy from the
mas01cr@554 139 * semantics of the feature being inserted; it's not immediately
mas01cr@554 140 * obvious to me how to estimate the data size required, unless
mas01cr@554 141 * we maybe do a preliminary query to find out the total time
mas01cr@554 142 * (or similar) of all the tracks we're about to insert.
mas01cr@554 143
mas01cr@554 144 * (also NOTE: this audiodb_create() interface is scheduled for
mas01cr@554 145 * being made less inelegant.) */
mas01mj@583 146 if(!(adb = audiodb_create(dbfile, 0, 0, 0))) {
mas01mj@583 147 fprintf(stderr, "failed to create %s.\n", dbfile);
mas01cr@554 148 return 1;
mas01cr@554 149 }
mas01cr@554 150 }
mas01cr@553 151 }
mas01cr@554 152
mas01mj@583 153 if(librdf_query_results_finished(results))
mas01mj@583 154 {
mas01mj@583 155 fprintf(stderr, "No features found!\n");
mas01mj@583 156 return 3;
mas01mj@583 157 }
mas01mj@583 158
mas01mj@583 159
mas01cr@553 160 while(!librdf_query_results_finished(results)) {
mas01mj@583 161
mas01cr@553 162 adb_datum_t datum = {0};
mas01mj@583 163
mas01mj@583 164 // Pull out the dimension
mas01mj@583 165
mas01mj@583 166 librdf_node *node = librdf_query_results_get_binding_value_by_name(results, "dimensions");
mas01mj@583 167 char* dimensions = librdf_node_get_literal_value(node);
mas01mj@583 168
mas01mj@583 169 int dimension = 0;
mas01mj@583 170 sscanf(dimensions, "%d", &dimension);
mas01mj@583 171 datum.dim = dimension;
mas01mj@583 172
mas01mj@583 173 node = librdf_query_results_get_binding_value_by_name(results, "typetitle");
mas01mj@583 174 printf("Insert feature of type %s\n", librdf_node_get_literal_value(node));
mas01mj@583 175
mas01mj@583 176 // Grab key and value
mas01mj@583 177
mas01mj@583 178 node = librdf_query_results_get_binding_value_by_name(results, "key");
mas01mj@583 179 datum.key = librdf_uri_as_string(librdf_node_get_uri(node));
mas01mj@583 180
mas01mj@583 181 size_t nelements = 0;
mas01mj@583 182 node = librdf_query_results_get_binding_value_by_name(results, "value");
mas01mj@583 183 datum.data = parse_value_string(librdf_node_get_literal_value(node), &nelements);
mas01mj@583 184
mas01mj@583 185 // Validate that we have the correct number of elements
mas01mj@583 186
mas01mj@583 187 if(nelements % dimension) return 4;
mas01mj@583 188 datum.nvectors = nelements / dimension;
mas01mj@583 189
mas01mj@583 190 printf("Dimension: %d\n", dimension);
mas01mj@583 191 printf("Key: %s\n", datum.key);
mas01mj@583 192 printf("Vectors: %d\n", datum.nvectors);
mas01mj@583 193
mas01mj@583 194 librdf_free_node(node);
mas01mj@583 195
mas01cr@553 196 if(audiodb_insert_datum(adb, &datum)) {
mas01cr@554 197 fprintf(stderr, "failed to insert datum with key %s.\n", datum.key);
mas01cr@554 198 return 1;
mas01cr@553 199 }
mas01cr@571 200 free(datum.data);
mas01cr@553 201 librdf_query_results_next(results);
mas01cr@553 202 }
mas01cr@553 203
mas01cr@553 204 audiodb_close(adb);
mas01cr@553 205 librdf_free_query_results(results);
mas01cr@553 206 librdf_free_query(query);
mas01cr@571 207 librdf_free_parser(parser);
mas01cr@553 208 librdf_free_uri(uri);
mas01cr@553 209 librdf_free_model(model);
mas01cr@553 210 librdf_free_storage(storage);
mas01cr@553 211 librdf_free_world(world);
mas01cr@554 212
mas01cr@554 213 return 0;
mas01cr@554 214
mas01cr@554 215 librdf_error:
mas01cr@554 216 fprintf(stderr, "Something went wrong in librdf.\n");
mas01cr@554 217 return 1;
mas01cr@553 218 }