annotate sparql/librdf/src/rdf_storage_audiodb.c @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 98db3bff21a0
children
rev   line source
mas01mj@585 1 #include <stdlib.h>
mas01mj@584 2 #include <unistd.h>
mas01mj@584 3 #include <fcntl.h>
mas01mj@584 4 #include <stdio.h>
mas01mj@584 5 #include <string.h>
mas01mj@584 6 #ifdef HAVE_STDLIB_H
mas01mj@584 7 #include <stdlib.h> /* for abort() as used in errors */
mas01mj@584 8 #endif
mas01mj@584 9 #include <sys/types.h>
mas01mj@585 10 #include <librdf.h>
mas01mj@584 11 #include <audioDB_API.h>
mas01mj@584 12
mas01mj@599 13 /**
mas01mj@599 14 * NB : This is pulled through from librdf internals. Not ideal, but
mas01mj@599 15 * otherwise we'd need to compile against their source tree!
mas01mj@599 16 **/
mas01mj@599 17
mas01mj@585 18 #define LIBRDF_SIGN_KEY 0x04Ed1A7D
mas01mj@584 19
mas01mj@603 20 #define AF_DIMENSION "http://purl.org/ontology/af/dimension"
mas01mj@603 21 #define AF_VECTORS "http://purl.org/ontology/af/vectors"
mas01mj@603 22 #define MO_SIGNAL "http://purl.org/ontology/mo/Signal"
mas01mj@603 23 #define RDF_TYPE "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
mas01mj@660 24 #define SIMILARITY_ELEMENT "http://purl.org/ontology/similarity/element"
mas01mj@660 25 #define SIMILARITY_DISTANCE "http://purl.org/ontology/similarity/distance"
mas01mj@660 26 #define SIMILARITY_SIMILARITY "http://purl.org/ontology/similarity/Similarity"
mas01mj@599 27
mas01mj@584 28 typedef struct {
mas01mj@584 29 librdf_model* model;
mas01mj@584 30 librdf_storage* storage;
mas01mj@599 31 char* name;
mas01mj@584 32 size_t name_len;
mas01mj@584 33 int is_new;
mas01mj@599 34 adb_t* adb;
mas01mj@584 35
mas01mj@584 36 } librdf_storage_audiodb_instance;
mas01mj@584 37
mas01mj@584 38
mas01mj@584 39 static int librdf_storage_audiodb_init(librdf_storage* storage, const char *name, librdf_hash* options);
mas01mj@584 40 static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model);
mas01mj@584 41 static int librdf_storage_audiodb_close(librdf_storage* storage);
mas01mj@584 42 static int librdf_storage_audiodb_size(librdf_storage* storage);
mas01mj@584 43 static int librdf_storage_audiodb_add_statement(librdf_storage* storage, librdf_statement* statement);
mas01mj@584 44 static int librdf_storage_audiodb_add_statements(librdf_storage* storage, librdf_stream* statement_stream);
mas01mj@584 45 static int librdf_storage_audiodb_remove_statement(librdf_storage* storage, librdf_statement* statement);
mas01mj@584 46 static int librdf_storage_audiodb_contains_statement(librdf_storage* storage, librdf_statement* statement);
mas01mj@584 47 static librdf_stream* librdf_storage_audiodb_serialise(librdf_storage* storage);
mas01mj@584 48 static librdf_stream* librdf_storage_audiodb_find_statements(librdf_storage* storage, librdf_statement* statement);
mas01mj@584 49
mas01mj@584 50 /* find_statements implementing functions */
mas01mj@584 51 static int librdf_storage_audiodb_find_statements_end_of_stream(void* context);
mas01mj@584 52 static int librdf_storage_audiodb_find_statements_next_statement(void* context);
mas01mj@584 53 static void* librdf_storage_audiodb_find_statements_get_statement(void* context, int flags);
mas01mj@584 54 static void librdf_storage_audiodb_find_statements_finished(void* context);
mas01mj@584 55
mas01mj@584 56 static int librdf_storage_audiodb_sync(librdf_storage *storage);
mas01mj@584 57
mas01mj@584 58 static void librdf_storage_audiodb_register_factory(librdf_storage_factory *factory);
mas01mj@584 59 void librdf_storage_module_register_factory(librdf_world *world);
mas01mj@585 60
mas01mj@599 61 /**
mas01mj@599 62 * These 3 are from librdf's rdf_internals - simplify the mallocing/freeing a bit.
mas01mj@599 63 */
mas01mj@599 64
mas01mj@585 65 void librdf_sign_free(void *ptr)
mas01mj@585 66 {
mas01mj@585 67 int *p;
mas01mj@585 68
mas01mj@585 69 if(!ptr)
mas01mj@585 70 return;
mas01mj@585 71
mas01mj@585 72 p=(int*)ptr;
mas01mj@585 73 p--;
mas01mj@585 74
mas01mj@585 75 if(*p != LIBRDF_SIGN_KEY)
mas01mj@585 76 return;
mas01mj@585 77
mas01mj@585 78 free(p);
mas01mj@585 79 }
mas01mj@585 80
mas01mj@585 81
mas01mj@585 82 void* librdf_sign_calloc(size_t nmemb, size_t size)
mas01mj@585 83 {
mas01mj@585 84 int *p;
mas01mj@585 85
mas01mj@585 86 /* turn into bytes */
mas01mj@585 87 size = nmemb*size + sizeof(int);
mas01mj@585 88
mas01mj@585 89 p=(int*)calloc(1, size);
mas01mj@585 90 *p++ = LIBRDF_SIGN_KEY;
mas01mj@585 91 return p;
mas01mj@585 92 }
mas01mj@585 93
mas01mj@585 94 void* librdf_sign_malloc(size_t size)
mas01mj@585 95 {
mas01mj@585 96 int *p;
mas01mj@585 97
mas01mj@585 98 size += sizeof(int);
mas01mj@585 99
mas01mj@585 100 p=(int*)malloc(size);
mas01mj@585 101 *p++ = LIBRDF_SIGN_KEY;
mas01mj@585 102 return p;
mas01mj@585 103 }
mas01mj@584 104
mas01mj@584 105
mas01mj@584 106 static int librdf_storage_audiodb_init(librdf_storage* storage, const char *name, librdf_hash* options) {
mas01mj@584 107
mas01mj@584 108 librdf_storage_audiodb_instance* context;
mas01mj@584 109 char* name_copy;
mas01mj@584 110
mas01mj@585 111 context = (librdf_storage_audiodb_instance*)librdf_sign_calloc(1, sizeof(librdf_storage_audiodb_instance));
mas01mj@584 112
mas01mj@584 113 if(!context)
mas01mj@584 114 {
mas01mj@584 115 if(options)
mas01mj@584 116 librdf_free_hash(options);
mas01mj@584 117 return 1;
mas01mj@584 118 }
mas01mj@584 119
mas01mj@584 120 librdf_storage_set_instance(storage, context);
mas01mj@584 121
mas01mj@584 122 context->storage = storage;
mas01mj@584 123
mas01mj@584 124 // Store the name of the db
mas01mj@584 125 context->name_len=strlen(name);
mas01mj@585 126 name_copy=(char*)librdf_sign_malloc(context->name_len+1);
mas01mj@584 127 if(!name_copy) {
mas01mj@584 128 if(options)
mas01mj@584 129 librdf_free_hash(options);
mas01mj@584 130 return 1;
mas01mj@584 131 }
mas01mj@584 132 strncpy(name_copy, name, context->name_len+1);
mas01mj@584 133 context->name=name_copy;
mas01mj@584 134
mas01mj@584 135 if(librdf_hash_get_as_boolean(options, "new") > 0)
mas01mj@584 136 context->is_new = 1;
mas01mj@584 137
mas01mj@584 138 if(options)
mas01mj@584 139 librdf_free_hash(options);
mas01mj@584 140
mas01mj@585 141 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 142 "Initialised!");
mas01mj@584 143
mas01mj@584 144 return 0;
mas01mj@584 145 }
mas01mj@584 146
mas01mj@584 147 static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model) {
mas01mj@585 148 librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage);
mas01mj@584 149 int db_file_exists = 0;
mas01mj@584 150
mas01mj@585 151 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 152 "open");
mas01mj@584 153
mas01mj@584 154 if(!access((const char*)context->name, F_OK))
mas01mj@584 155 db_file_exists = 1;
mas01mj@584 156 else
mas01mj@584 157 context->is_new = 1;
mas01mj@584 158
mas01mj@584 159 if(context->is_new && db_file_exists)
mas01mj@584 160 unlink(context->name);
mas01mj@584 161
mas01mj@584 162 context->adb = NULL;
mas01mj@608 163 context->model = librdf_new_model(librdf_storage_get_world(storage),
mas01mj@608 164 librdf_new_storage(librdf_storage_get_world(storage), "memory", NULL, NULL), NULL);
mas01mj@608 165
mas01mj@584 166 if(context->is_new) {
mas01mj@584 167 if(!(context->adb = audiodb_create(context->name, 0, 0, 0))) {
mas01mj@585 168 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 169 "Unable to create %s", context->name);
mas01mj@584 170 return 1;
mas01mj@584 171 }
mas01mj@584 172 }
mas01mj@584 173 else
mas01mj@584 174 {
mas01mj@608 175 if(!(context->adb = audiodb_open(context->name, O_RDONLY))) {
mas01mj@585 176 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 177 "Unable to open %s", context->name);
mas01mj@584 178 return 1;
mas01mj@584 179 }
mas01mj@584 180 }
mas01mj@584 181
mas01mj@584 182 return 0;
mas01mj@584 183 }
mas01mj@584 184
mas01mj@584 185 static int librdf_storage_audiodb_close(librdf_storage* storage) {
mas01mj@585 186 librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage);
mas01mj@584 187
mas01mj@585 188 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 189 "close");
mas01mj@584 190
mas01mj@584 191 if(context->adb)
mas01mj@584 192 {
mas01mj@584 193 audiodb_close(context->adb);
mas01mj@584 194 context->adb = NULL;
mas01mj@584 195 }
mas01mj@584 196
mas01mj@584 197 return 0;
mas01mj@584 198 }
mas01mj@584 199
mas01mj@584 200 static int librdf_storage_audiodb_size(librdf_storage* storage) {
mas01mj@585 201 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 202 "size");
mas01mj@584 203 return 0;
mas01mj@584 204 }
mas01mj@584 205
mas01mj@584 206 static int librdf_storage_audiodb_add_statement(librdf_storage* storage, librdf_statement* statement) {
mas01mj@585 207 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 208 "add statement");
mas01mj@584 209 return 0;
mas01mj@584 210 }
mas01mj@584 211
mas01mj@584 212 static int librdf_storage_audiodb_add_statements(librdf_storage* storage, librdf_stream* statement_stream) {
mas01mj@585 213 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 214 "add statements");
mas01mj@584 215 return 0;
mas01mj@584 216 }
mas01mj@584 217
mas01mj@584 218 static int librdf_storage_audiodb_remove_statement(librdf_storage* storage, librdf_statement* statement) {
mas01mj@585 219 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 220 "remove statement");
mas01mj@584 221 return 0;
mas01mj@584 222 }
mas01mj@584 223
mas01mj@584 224 static int librdf_storage_audiodb_contains_statement(librdf_storage* storage, librdf_statement* statement) {
mas01mj@599 225
mas01mj@599 226 librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage);
mas01mj@599 227 librdf_world* world = librdf_storage_get_world(storage);
mas01mj@599 228
mas01mj@599 229 librdf_node* subject = librdf_statement_get_subject(statement);
mas01mj@599 230 librdf_node* object = librdf_statement_get_object(statement);
mas01mj@599 231 librdf_node* predicate = librdf_statement_get_predicate(statement);
mas01mj@603 232 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@603 233 "Contains statement %s?", librdf_statement_to_string(statement));
mas01mj@599 234
mas01mj@599 235
mas01mj@599 236 if(subject && object && predicate)
mas01mj@599 237 {
mas01mj@599 238 // audioDBs only contain Signals (tracks are held in a separate store).
mas01mj@599 239
mas01mj@599 240 librdf_uri* type_uri = librdf_new_uri(world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
mas01mj@599 241 librdf_uri* signal_uri = librdf_new_uri(world, "http://purl.org/ontology/mo/Signal");
mas01mj@599 242 if(librdf_uri_equals(type_uri, librdf_node_get_uri(predicate)))
mas01mj@599 243 {
mas01mj@599 244 librdf_uri* object_uri = librdf_node_get_uri(object);
mas01mj@599 245 if(librdf_uri_equals(object_uri, signal_uri))
mas01mj@599 246 {
mas01mj@599 247 // Grab the track via audioDB
mas01mj@599 248 adb_datum_t datum = {0};
mas01mj@599 249 int result = audiodb_retrieve_datum(
mas01mj@599 250 context->adb,
mas01mj@599 251 librdf_uri_as_string(librdf_node_get_uri(subject)),
mas01mj@599 252 &datum);
mas01mj@599 253 if(result == 0)
mas01mj@599 254 {
mas01mj@599 255 // Found it! Free up the datum.
mas01mj@599 256 audiodb_free_datum(context->adb, &datum);
mas01mj@599 257 return 1;
mas01mj@599 258 }
mas01mj@599 259 }
mas01mj@599 260 }
mas01mj@599 261 librdf_free_uri(type_uri);
mas01mj@599 262 librdf_free_uri(signal_uri);
mas01mj@599 263 }
mas01mj@584 264 return 0;
mas01mj@584 265 }
mas01mj@584 266
mas01mj@584 267 static librdf_stream* librdf_storage_audiodb_serialise(librdf_storage* storage) {
mas01mj@585 268 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 269 "serialise");
mas01mj@584 270 return NULL;
mas01mj@584 271 }
mas01mj@584 272
mas01mj@599 273 /**
mas01mj@599 274 * Linked list bits
mas01mj@599 275 */
mas01mj@599 276
mas01mj@599 277
mas01mj@599 278 struct list_node_s
mas01mj@599 279 {
mas01mj@599 280 struct list_node_s* next;
mas01mj@599 281 struct list_node_s* prev;
mas01mj@599 282 librdf_statement* statement;
mas01mj@599 283 };
mas01mj@599 284
mas01mj@599 285 typedef struct list_node_s list_node;
mas01mj@599 286
mas01mj@599 287 struct list_s {
mas01mj@599 288 list_node* head;
mas01mj@599 289 list_node* tail;
mas01mj@599 290 };
mas01mj@599 291
mas01mj@599 292 typedef struct list_s result_list;
mas01mj@599 293
mas01mj@599 294 result_list* result_data_new()
mas01mj@599 295 {
mas01mj@599 296 result_list* list = (result_list*)calloc(1, sizeof(result_list));
mas01mj@599 297 if(!list)
mas01mj@599 298 return NULL;
mas01mj@599 299 return list;
mas01mj@599 300 }
mas01mj@599 301
mas01mj@599 302 int result_data_add(librdf_world* world, result_list* list) {
mas01mj@599 303
mas01mj@599 304 // First create the node
mas01mj@599 305 list_node* node = (list_node*)calloc(1, sizeof(list_node));
mas01mj@599 306
mas01mj@599 307 if(!node)
mas01mj@599 308 return 1;
mas01mj@599 309
mas01mj@599 310 if(list->tail)
mas01mj@599 311 {
mas01mj@599 312 node->prev = list->tail;
mas01mj@599 313 list->tail->next = node;
mas01mj@599 314 }
mas01mj@599 315
mas01mj@599 316 list->tail = node;
mas01mj@599 317 if(!list->head)
mas01mj@599 318 list->head = node;
mas01mj@599 319 return 0;
mas01mj@599 320 }
mas01mj@599 321
mas01mj@599 322 /**
mas01mj@599 323 * Querying bits.
mas01mj@599 324 **/
mas01mj@599 325
mas01mj@599 326 typedef struct {
mas01mj@599 327 librdf_storage* storage;
mas01mj@599 328 librdf_storage_audiodb_instance* audiodb_context;
mas01mj@599 329 int finished;
mas01mj@599 330 librdf_statement* statement;
mas01mj@599 331 librdf_node* context;
mas01mj@599 332 result_list *results;
mas01mj@599 333
mas01mj@599 334 } librdf_storage_audiodb_find_statements_stream_context;
mas01mj@599 335
mas01mj@599 336
mas01mj@599 337
mas01mj@599 338
mas01mj@584 339 static librdf_stream* librdf_storage_audiodb_find_statements(librdf_storage* storage, librdf_statement* statement) {
mas01mj@584 340
mas01mj@585 341 librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage);
mas01mj@584 342 librdf_storage_audiodb_find_statements_stream_context* scontext;
mas01mj@584 343 librdf_stream* stream;
mas01mj@599 344
mas01mj@599 345
mas01mj@599 346 librdf_world* world = librdf_storage_get_world(storage);
mas01mj@599 347
mas01mj@585 348 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@599 349 "find statements %s", librdf_statement_to_string(statement));
mas01mj@584 350
mas01mj@599 351 // Create stream context
mas01mj@585 352 scontext = (librdf_storage_audiodb_find_statements_stream_context*)librdf_sign_calloc(1, sizeof(librdf_storage_audiodb_find_statements_stream_context));
mas01mj@584 353
mas01mj@584 354 if(!scontext)
mas01mj@584 355 return NULL;
mas01mj@584 356
mas01mj@584 357 scontext->storage = storage;
mas01mj@584 358 librdf_storage_add_reference(scontext->storage);
mas01mj@599 359
mas01mj@599 360 // Store a reference to the storage instance.
mas01mj@584 361 scontext->audiodb_context = context;
mas01mj@584 362
mas01mj@599 363 scontext->results = result_data_new();
mas01mj@608 364
mas01mj@599 365 // This will need factoring out
mas01mj@599 366 librdf_node* subject = librdf_statement_get_subject(statement);
mas01mj@599 367 librdf_node* object = librdf_statement_get_object(statement);
mas01mj@599 368 librdf_node* predicate = librdf_statement_get_predicate(statement);
mas01mj@599 369
mas01mj@603 370 librdf_uri* dimension = librdf_new_uri(world, AF_DIMENSION);
mas01mj@603 371 librdf_uri* vectors = librdf_new_uri(world, AF_VECTORS);
mas01mj@603 372 librdf_uri* signal = librdf_new_uri(world, MO_SIGNAL);
mas01mj@603 373 librdf_uri* type = librdf_new_uri(world, RDF_TYPE);
mas01mj@660 374 librdf_uri* element = librdf_new_uri(world, SIMILARITY_ELEMENT);
mas01mj@660 375 librdf_uri* distance = librdf_new_uri(world, SIMILARITY_DISTANCE);
mas01mj@660 376 librdf_uri* similarity = librdf_new_uri(world, SIMILARITY_SIMILARITY);
mas01mj@603 377
mas01mj@608 378 // SPX (given a resource and a predicate, but no object)
mas01mj@608 379 if(subject && librdf_node_is_resource(subject) &&
mas01mj@608 380 predicate && librdf_node_is_resource(predicate) &&
mas01mj@608 381 (!object || object && librdf_node_is_blank(object))) {
mas01mj@603 382 librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Got SPX");
mas01mj@599 383 librdf_uri* predicate_uri = librdf_node_get_uri(predicate);
mas01mj@603 384 librdf_uri* subject_uri = librdf_node_get_uri(subject);
mas01mj@608 385
mas01mj@608 386 // Need dimension or vectors - so get the track datum and populate.
mas01mj@599 387 if(librdf_uri_equals(predicate_uri, dimension) || librdf_uri_equals(predicate_uri, vectors))
mas01mj@599 388 {
mas01mj@599 389 adb_datum_t datum = {0};
mas01mj@599 390 int result = audiodb_retrieve_datum(
mas01mj@599 391 context->adb,
mas01mj@603 392 librdf_uri_as_string(subject_uri),
mas01mj@599 393 &datum);
mas01mj@599 394 if(result == 0)
mas01mj@599 395 {
mas01mj@599 396 librdf_node* value;
mas01mj@608 397 char buffer[16];
mas01mj@599 398
mas01mj@599 399 if(librdf_uri_equals(predicate_uri, dimension))
mas01mj@608 400 snprintf(buffer, 16, "%d", datum.dim);
mas01mj@599 401 else if(librdf_uri_equals(predicate_uri, vectors))
mas01mj@608 402 snprintf(buffer, 16, "%d", datum.nvectors);
mas01mj@603 403
mas01mj@608 404 value = librdf_new_node_from_typed_literal(world, buffer, NULL, librdf_new_uri(world, "http://www.w3.org/2001/XMLSchema#integer"));
mas01mj@599 405
mas01mj@599 406 result_data_add(world, scontext->results);
mas01mj@599 407
mas01mj@599 408 result_list* list = scontext->results;
mas01mj@599 409
mas01mj@599 410 list->tail->statement = librdf_new_statement(world);
mas01mj@599 411 librdf_statement_set_subject(list->tail->statement, subject);
mas01mj@599 412 librdf_statement_set_object(list->tail->statement, value);
mas01mj@599 413 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 414 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Return statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@599 415 }
mas01mj@608 416 }
mas01mj@608 417 } // XPO (given a predicate and an object, but no subject)
mas01mj@608 418 else if(!subject &&
mas01mj@608 419 predicate && librdf_node_is_resource(predicate) &&
mas01mj@608 420 object && librdf_node_is_resource(object)) {
mas01mj@599 421
mas01mj@603 422 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "XPO");
mas01mj@603 423 librdf_uri* predicate_uri = librdf_node_get_uri(predicate);
mas01mj@603 424 librdf_uri* object_uri = librdf_node_get_uri(object);
mas01mj@603 425
mas01mj@608 426 if(librdf_uri_equals(predicate_uri, type)) {
mas01mj@608 427 // Need everything of type mo:Signal - currently all track IDs.
mas01mj@608 428 if(librdf_uri_equals(object_uri, signal)) {
mas01mj@608 429 adb_liszt_results_t* liszt_results = audiodb_liszt(context->adb);
mas01mj@608 430
mas01mj@608 431 uint32_t k;
mas01mj@608 432 for(k = 0; k < liszt_results->nresults; k++) {
mas01mj@608 433 result_data_add(world, scontext->results);
mas01mj@608 434 result_list* list = scontext->results;
mas01mj@608 435 list->tail->statement = librdf_new_statement(world);
mas01mj@608 436 librdf_statement_set_subject(list->tail->statement, librdf_new_node_from_uri(world, librdf_new_uri(world, liszt_results->entries[k].key)));
mas01mj@608 437
mas01mj@608 438 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 439 librdf_statement_set_object(list->tail->statement, object);
mas01mj@608 440 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Return statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 441 }
mas01mj@608 442
mas01mj@608 443 audiodb_liszt_free_results(context->adb, liszt_results);
mas01mj@608 444 }
mas01mj@608 445 else if(librdf_uri_equals(object_uri, similarity)) {
mas01mj@608 446 // mo:Similarity doesn't actually exist in our store - so we create one
mas01mj@608 447 // and put it into an in-memory store.
mas01mj@608 448 result_data_add(world, scontext->results);
mas01mj@608 449 result_list* list = scontext->results;
mas01mj@608 450 list->tail->statement = librdf_new_statement(world);
mas01mj@608 451 librdf_statement_set_subject(list->tail->statement, librdf_new_node_from_blank_identifier(world, NULL));
mas01mj@608 452 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 453 librdf_statement_set_object(list->tail->statement, object);
mas01mj@608 454 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Cache statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 455 librdf_model_add_statement(context->model, list->tail->statement);
mas01mj@608 456 }
mas01mj@608 457 }
mas01mj@608 458 } // sPO (given a blank identifier as the subject, a predicate and an object - this just stores them in the cache).
mas01mj@608 459 else if(subject && librdf_node_is_blank(subject) &&
mas01mj@608 460 predicate && librdf_node_is_resource(predicate) &&
mas01mj@608 461 object && librdf_node_is_resource(object)) {
mas01mj@608 462
mas01mj@608 463 // TODO : Verify that the contents are plausible entries in the store.
mas01mj@608 464
mas01mj@608 465 result_data_add(world, scontext->results);
mas01mj@608 466 result_list* list = scontext->results;
mas01mj@608 467 list->tail->statement = librdf_new_statement(world);
mas01mj@608 468
mas01mj@608 469 librdf_statement_set_subject(list->tail->statement, subject);
mas01mj@608 470 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 471 librdf_statement_set_object(list->tail->statement, object);
mas01mj@608 472
mas01mj@608 473 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Cache statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 474 librdf_model_add_statement(context->model, list->tail->statement);
mas01mj@608 475 } // sPX (given a blank identifier as the subject, a predicate, and no object)
mas01mj@608 476 else if(subject && (librdf_node_is_blank(subject) || librdf_node_is_resource(subject)) &&
mas01mj@608 477 predicate && librdf_node_is_resource(predicate) &&
mas01mj@608 478 !object) {
mas01mj@608 479 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "sPX");
mas01mj@608 480 librdf_uri* predicate_uri = librdf_node_get_uri(predicate);
mas01mj@608 481
mas01mj@608 482 if(librdf_uri_equals(predicate_uri, element))
mas01mj@603 483 {
mas01mj@608 484 // Fill in all possible elements, and cache the statements.
mas01mj@603 485 adb_liszt_results_t* liszt_results = audiodb_liszt(context->adb);
mas01mj@603 486
mas01mj@603 487 uint32_t k;
mas01mj@603 488 for(k = 0; k < liszt_results->nresults; k++) {
mas01mj@603 489 result_data_add(world, scontext->results);
mas01mj@603 490 result_list* list = scontext->results;
mas01mj@603 491 list->tail->statement = librdf_new_statement(world);
mas01mj@603 492
mas01mj@608 493 librdf_statement_set_subject(list->tail->statement, subject);
mas01mj@608 494 librdf_statement_set_object(list->tail->statement, librdf_new_node_from_uri(world, librdf_new_uri(world, liszt_results->entries[k].key)));
mas01mj@603 495 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 496
mas01mj@608 497 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Cache statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 498 librdf_model_add_statement(context->model, list->tail->statement);
mas01mj@603 499 }
mas01mj@608 500
mas01mj@608 501 audiodb_liszt_free_results(context->adb, liszt_results);
mas01mj@608 502
mas01mj@608 503 }
mas01mj@608 504 if(librdf_uri_equals(predicate_uri, distance))
mas01mj@608 505 {
mas01mj@608 506 // This requires both elements to be defined - check those first,
mas01mj@608 507 // and use a blank identifier if not.
mas01mj@608 508 librdf_statement* element_search = librdf_new_statement(world);
mas01mj@608 509 librdf_statement_set_subject(element_search, subject);
mas01mj@608 510 librdf_statement_set_predicate(element_search, librdf_new_node_from_uri(world, element));
mas01mj@608 511 librdf_stream* elements = librdf_model_find_statements(context->model, element_search);
mas01mj@608 512 int count = 0;
mas01mj@608 513
mas01mj@608 514 char* keys[2];
mas01mj@608 515
mas01mj@608 516 while (!librdf_stream_end(elements) && count < 2) {
mas01mj@608 517 keys[count] = librdf_uri_as_string(
mas01mj@608 518 librdf_node_get_uri(
mas01mj@608 519 librdf_statement_get_object(
mas01mj@608 520 librdf_new_statement_from_statement(
mas01mj@608 521 librdf_stream_get_object(elements)))));
mas01mj@608 522 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Key %d %s", count, keys[count]);
mas01mj@608 523 librdf_stream_next(elements);
mas01mj@608 524 count++;
mas01mj@608 525 }
mas01mj@608 526
mas01mj@608 527 double dist = 0;
mas01mj@603 528
mas01mj@608 529 // TODO : Trigger an error case here.
mas01mj@608 530
mas01mj@608 531 if(count == 2)
mas01mj@608 532 {
mas01mj@608 533 // Calculate the distance
mas01mj@608 534 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Calculate distance");
mas01mj@608 535
mas01mj@608 536 adb_query_spec_t qspec = {0};
mas01mj@608 537 adb_datum_t datum = {0};
mas01mj@608 538 datum.key = keys[0];
mas01mj@608 539
mas01mj@608 540 qspec.refine.flags = ADB_REFINE_INCLUDE_KEYLIST;
mas01mj@608 541 qspec.refine.include.nkeys = 1;
mas01mj@608 542 qspec.refine.include.keys = &keys[1];
mas01mj@608 543 qspec.refine.hopsize = 1;
mas01mj@608 544
mas01mj@608 545 qspec.qid.datum = &datum;
mas01mj@608 546 qspec.qid.sequence_length = 10;
mas01mj@608 547 qspec.qid.flags = ADB_QID_FLAG_EXHAUSTIVE;
mas01mj@608 548 qspec.qid.sequence_start = 0;
mas01mj@608 549
mas01mj@608 550 qspec.params.accumulation = ADB_ACCUMULATION_PER_TRACK;
mas01mj@608 551 qspec.params.distance = ADB_DISTANCE_EUCLIDEAN;
mas01mj@608 552 qspec.params.npoints = 1;
mas01mj@608 553 qspec.params.ntracks = 1;
mas01mj@608 554
mas01mj@608 555 adb_query_results_t* results = audiodb_query_spec(context->adb, &qspec);
mas01mj@608 556 dist = results->results[0].dist;
mas01mj@608 557
mas01mj@608 558 char value[16];
mas01mj@608 559 snprintf(value, 16, "%f", dist);
mas01mj@608 560
mas01mj@608 561 result_data_add(world, scontext->results);
mas01mj@608 562 result_list* list = scontext->results;
mas01mj@608 563 list->tail->statement = librdf_new_statement(world);
mas01mj@608 564
mas01mj@608 565 librdf_statement_set_subject(list->tail->statement, subject);
mas01mj@608 566 librdf_statement_set_predicate(list->tail->statement, predicate);
mas01mj@608 567 librdf_statement_set_object(list->tail->statement,
mas01mj@608 568 librdf_new_node_from_typed_literal(world, value, NULL, librdf_new_uri(world, "http://www.w3.org/2001/XMLSchema#decimal")));
mas01mj@608 569
mas01mj@608 570 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Cache statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 571 librdf_model_add_statement(context->model, list->tail->statement);
mas01mj@608 572 }
mas01mj@603 573 }
mas01mj@608 574
mas01mj@608 575 }
mas01mj@608 576 else if(subject && predicate && object)
mas01mj@608 577 {
mas01mj@608 578 result_data_add(world, scontext->results);
mas01mj@608 579 result_list* list = scontext->results;
mas01mj@608 580 list->tail->statement = librdf_new_statement_from_statement(statement);
mas01mj@608 581 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Cache statement %s", librdf_statement_to_string(list->tail->statement));
mas01mj@608 582 librdf_model_add_statement(context->model, list->tail->statement);
mas01mj@603 583 }
mas01mj@603 584 else
mas01mj@603 585 {
mas01mj@603 586 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, "Halp?");
mas01mj@603 587 }
mas01mj@608 588
mas01mj@599 589 librdf_free_uri(dimension);
mas01mj@599 590 librdf_free_uri(vectors);
mas01mj@603 591 librdf_free_uri(signal);
mas01mj@603 592 librdf_free_uri(type);
mas01mj@608 593 librdf_free_uri(element);
mas01mj@608 594 librdf_free_uri(distance);
mas01mj@608 595 librdf_free_uri(similarity);
mas01mj@603 596
mas01mj@599 597 stream = librdf_new_stream(world,
mas01mj@599 598 (void*)scontext,
mas01mj@599 599 &librdf_storage_audiodb_find_statements_end_of_stream,
mas01mj@599 600 &librdf_storage_audiodb_find_statements_next_statement,
mas01mj@599 601 &librdf_storage_audiodb_find_statements_get_statement,
mas01mj@599 602 &librdf_storage_audiodb_find_statements_finished);
mas01mj@584 603
mas01mj@584 604 if(!stream) {
mas01mj@599 605 librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@599 606 "Couldn't create stream!");
mas01mj@584 607 librdf_storage_audiodb_find_statements_finished((void*)scontext);
mas01mj@584 608 return NULL;
mas01mj@584 609 }
mas01mj@584 610
mas01mj@584 611 return stream;
mas01mj@584 612 }
mas01mj@584 613
mas01mj@584 614 static void librdf_storage_audiodb_find_statements_finished(void* context) {
mas01mj@584 615 librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context;
mas01mj@599 616
mas01mj@584 617 if(scontext->storage)
mas01mj@584 618 librdf_storage_remove_reference(scontext->storage);
mas01mj@584 619
mas01mj@584 620 if(scontext->statement)
mas01mj@584 621 librdf_free_statement(scontext->statement);
mas01mj@584 622
mas01mj@584 623 if(scontext->context)
mas01mj@584 624 librdf_free_node(scontext->context);
mas01mj@584 625
mas01mj@585 626 librdf_sign_free(scontext);
mas01mj@584 627 }
mas01mj@584 628
mas01mj@584 629 static int librdf_storage_audiodb_find_statements_end_of_stream(void* context) {
mas01mj@584 630 librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context;
mas01mj@599 631 librdf_world* world = librdf_storage_get_world(scontext->storage);
mas01mj@599 632 librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@603 633 "Finished? %d", (scontext->results->head == NULL));
mas01mj@584 634
mas01mj@599 635 return (scontext->results->head == NULL);
mas01mj@584 636 }
mas01mj@584 637
mas01mj@584 638 static int librdf_storage_audiodb_find_statements_next_statement(void* context) {
mas01mj@584 639 librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context;
mas01mj@584 640
mas01mj@599 641 librdf_world* world = librdf_storage_get_world(scontext->storage);
mas01mj@599 642 librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@599 643 "to next");
mas01mj@599 644
mas01mj@599 645 if(scontext->results->head->next)
mas01mj@599 646 {
mas01mj@599 647 scontext->results->head = scontext->results->head->next;
mas01mj@599 648 return 0;
mas01mj@599 649 }
mas01mj@599 650 else
mas01mj@599 651 {
mas01mj@584 652 return 1;
mas01mj@584 653 }
mas01mj@584 654 }
mas01mj@584 655
mas01mj@584 656 static void* librdf_storage_audiodb_find_statements_get_statement(void* context, int flags) {
mas01mj@584 657 librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context;
mas01mj@599 658 librdf_world* world = librdf_storage_get_world(scontext->storage);
mas01mj@599 659 librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL,
mas01mj@599 660 "Get next");
mas01mj@603 661
mas01mj@584 662 switch(flags) {
mas01mj@584 663 case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
mas01mj@599 664 return scontext->results->head->statement;
mas01mj@584 665 case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
mas01mj@584 666 return scontext->context;
mas01mj@584 667 default:
mas01mj@599 668 librdf_log(world,
mas01mj@584 669 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
mas01mj@584 670 "Unknown iterator method flag %d", flags);
mas01mj@584 671 return NULL;
mas01mj@584 672 }
mas01mj@584 673 }
mas01mj@584 674
mas01mj@584 675
mas01mj@584 676
mas01mj@584 677 static int librdf_storage_audiodb_sync(librdf_storage *storage) {
mas01mj@584 678 return 0;
mas01mj@584 679 }
mas01mj@584 680
mas01mj@584 681 static void
mas01mj@584 682 librdf_storage_audiodb_register_factory(librdf_storage_factory *factory) {
mas01mj@584 683 factory->version = LIBRDF_STORAGE_INTERFACE_VERSION;
mas01mj@584 684 factory->init = librdf_storage_audiodb_init;
mas01mj@584 685 factory->open = librdf_storage_audiodb_open;
mas01mj@584 686 factory->close = librdf_storage_audiodb_close;
mas01mj@584 687 factory->size = librdf_storage_audiodb_size;
mas01mj@584 688 factory->add_statement = librdf_storage_audiodb_add_statement;
mas01mj@584 689 factory->remove_statement = librdf_storage_audiodb_remove_statement;
mas01mj@584 690 factory->contains_statement = librdf_storage_audiodb_contains_statement;
mas01mj@584 691 factory->serialise = librdf_storage_audiodb_serialise;
mas01mj@584 692 factory->find_statements = librdf_storage_audiodb_find_statements;
mas01mj@584 693 }
mas01mj@584 694
mas01mj@584 695 /** Entry point for dynamically loaded storage module */
mas01mj@584 696 void librdf_storage_module_register_factory(librdf_world *world) {
mas01mj@584 697 librdf_storage_register_factory(world, "audiodb", "AudioDB",
mas01mj@584 698 &librdf_storage_audiodb_register_factory);
mas01mj@584 699 }