Mercurial > hg > audiodb
changeset 599:c6debbac3216
End-to-end functioning SPARQL with audioDB storage module
* AudioDB RDF storage module now works correctly with dimension and vectors
* Apache module now returns a sparql version of the query results.
* (including cleanup close/free calls).
author | mas01mj |
---|---|
date | Thu, 13 Aug 2009 11:20:56 +0000 |
parents | b2a941a372fb |
children | 337e5962218a |
files | sparql/librdf/src/rdf_storage_audiodb.c sparql/mod_audiodb/Makefile.am sparql/mod_audiodb/mod_audiodb.c |
diffstat | 3 files changed, 235 insertions(+), 111 deletions(-) [+] |
line wrap: on
line diff
--- a/sparql/librdf/src/rdf_storage_audiodb.c Wed Aug 12 14:57:11 2009 +0000 +++ b/sparql/librdf/src/rdf_storage_audiodb.c Thu Aug 13 11:20:56 2009 +0000 @@ -10,28 +10,25 @@ #include <librdf.h> #include <audioDB_API.h> +/** + * NB : This is pulled through from librdf internals. Not ideal, but + * otherwise we'd need to compile against their source tree! + **/ + #define LIBRDF_SIGN_KEY 0x04Ed1A7D + typedef struct { librdf_model* model; librdf_storage* storage; - char *name; + char* name; size_t name_len; int is_new; - adb_t *adb; + adb_t* adb; } librdf_storage_audiodb_instance; -typedef struct { - librdf_storage* storage; - librdf_storage_audiodb_instance* audiodb_context; - int finished; - librdf_statement* statement; - librdf_statement* query_statement; - librdf_node* context; - -} librdf_storage_audiodb_find_statements_stream_context; static int librdf_storage_audiodb_init(librdf_storage* storage, const char *name, librdf_hash* options); static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model); @@ -55,6 +52,10 @@ static void librdf_storage_audiodb_register_factory(librdf_storage_factory *factory); void librdf_storage_module_register_factory(librdf_world *world); +/** + * These 3 are from librdf's rdf_internals - simplify the mallocing/freeing a bit. + */ + void librdf_sign_free(void *ptr) { int *p; @@ -138,7 +139,6 @@ } static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model) { - librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); int db_file_exists = 0; @@ -214,8 +214,50 @@ } static int librdf_storage_audiodb_contains_statement(librdf_storage* storage, librdf_statement* statement) { - librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, - "Contains statement"); + + librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); + librdf_world* world = librdf_storage_get_world(storage); + + librdf_node* subject = librdf_statement_get_subject(statement); + librdf_node* object = librdf_statement_get_object(statement); + librdf_node* predicate = librdf_statement_get_predicate(statement); + + + if(subject && object && predicate) + { + // audioDBs only contain Signals (tracks are held in a separate store). + + librdf_uri* type_uri = librdf_new_uri(world, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + librdf_uri* signal_uri = librdf_new_uri(world, "http://purl.org/ontology/mo/Signal"); + if(librdf_uri_equals(type_uri, librdf_node_get_uri(predicate))) + { + librdf_uri* object_uri = librdf_node_get_uri(object); + if(librdf_uri_equals(object_uri, signal_uri)) + { + // Grab the track via audioDB + adb_datum_t datum = {0}; + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Retrieve datum"); + int result = audiodb_retrieve_datum( + context->adb, + librdf_uri_as_string(librdf_node_get_uri(subject)), + &datum); + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Back..."); + if(result == 0) + { + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Found datum"); + + // Found it! Free up the datum. + audiodb_free_datum(context->adb, &datum); + return 1; + } + } + } + librdf_free_uri(type_uri); + librdf_free_uri(signal_uri); + } return 0; } @@ -225,15 +267,86 @@ return NULL; } +/** + * Linked list bits + */ + + +struct list_node_s +{ + struct list_node_s* next; + struct list_node_s* prev; + librdf_statement* statement; +}; + +typedef struct list_node_s list_node; + +struct list_s { + list_node* head; + list_node* tail; +}; + +typedef struct list_s result_list; + +result_list* result_data_new() +{ + result_list* list = (result_list*)calloc(1, sizeof(result_list)); + if(!list) + return NULL; + return list; +} + +int result_data_add(librdf_world* world, result_list* list) { + + // First create the node + list_node* node = (list_node*)calloc(1, sizeof(list_node)); + + if(!node) + return 1; + + if(list->tail) + { + node->prev = list->tail; + list->tail->next = node; + } + + list->tail = node; + if(!list->head) + list->head = node; + return 0; +} + +/** + * Querying bits. + **/ + +typedef struct { + librdf_storage* storage; + librdf_storage_audiodb_instance* audiodb_context; + int finished; + librdf_statement* statement; + librdf_statement* query_statement; + librdf_node* context; + result_list *results; + +} librdf_storage_audiodb_find_statements_stream_context; + + + + static librdf_stream* librdf_storage_audiodb_find_statements(librdf_storage* storage, librdf_statement* statement) { librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); librdf_storage_audiodb_find_statements_stream_context* scontext; librdf_stream* stream; - + + + librdf_world* world = librdf_storage_get_world(storage); + librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, - "find statements %s", librdf_statement_to_string(statement)); + "find statements %s", librdf_statement_to_string(statement)); + // Create stream context scontext = (librdf_storage_audiodb_find_statements_stream_context*)librdf_sign_calloc(1, sizeof(librdf_storage_audiodb_find_statements_stream_context)); if(!scontext) @@ -241,23 +354,88 @@ scontext->storage = storage; librdf_storage_add_reference(scontext->storage); - + + // Store a reference to the storage instance. scontext->audiodb_context = context; + // Clone the query statement and store away. scontext->query_statement = librdf_new_statement_from_statement(statement); if(!scontext->query_statement) { librdf_storage_audiodb_find_statements_finished((void*)scontext); return NULL; } - stream = librdf_new_stream(librdf_storage_get_world(storage), - (void*)scontext, - &librdf_storage_audiodb_find_statements_end_of_stream, - &librdf_storage_audiodb_find_statements_next_statement, - &librdf_storage_audiodb_find_statements_get_statement, - &librdf_storage_audiodb_find_statements_finished); + scontext->results = result_data_new(); + + // This will need factoring out + librdf_node* subject = librdf_statement_get_subject(statement); + librdf_node* object = librdf_statement_get_object(statement); + librdf_node* predicate = librdf_statement_get_predicate(statement); + + librdf_uri* dimension = librdf_new_uri(world, "http://purl.org/ontology/af/dimension"); + librdf_uri* vectors = librdf_new_uri(world, "http://purl.org/ontology/af/vectors"); + + if(librdf_node_is_resource(subject) && librdf_node_is_resource(predicate)) + { + librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Got SPX"); + librdf_uri* predicate_uri = librdf_node_get_uri(predicate); + if(librdf_uri_equals(predicate_uri, dimension) || librdf_uri_equals(predicate_uri, vectors)) + { + // Need dimension or vectors - so get the track datum. + adb_datum_t datum = {0}; + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Retrieve datum"); + int result = audiodb_retrieve_datum( + context->adb, + librdf_uri_as_string(librdf_node_get_uri(subject)), + &datum); + if(result == 0) + { + librdf_node* value; + raptor_stringbuffer* buffer = raptor_new_stringbuffer(); + + if(librdf_uri_equals(predicate_uri, dimension)) + { + raptor_stringbuffer_append_decimal(buffer, datum.dim); + value = librdf_new_node_from_typed_literal(world, raptor_stringbuffer_as_string(buffer), NULL, librdf_new_uri(world, "xsd:integer")); + } + else if(librdf_uri_equals(predicate_uri, vectors)) + { + raptor_stringbuffer_append_decimal(buffer, datum.nvectors); + value = librdf_new_node_from_typed_literal(world, raptor_stringbuffer_as_string(buffer), NULL, librdf_new_uri(world, "xsd:integer")); + } + + // raptor_free_stringbuffer(value); + + result_data_add(world, scontext->results); + + result_list* list = scontext->results; + + + list->tail->statement = librdf_new_statement(world); + librdf_statement_set_subject(list->tail->statement, subject); + librdf_statement_set_object(list->tail->statement, value); + librdf_statement_set_predicate(list->tail->statement, predicate); + } + + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Done!"); + } + } + librdf_free_uri(dimension); + librdf_free_uri(vectors); + + stream = librdf_new_stream(world, + (void*)scontext, + &librdf_storage_audiodb_find_statements_end_of_stream, + &librdf_storage_audiodb_find_statements_next_statement, + &librdf_storage_audiodb_find_statements_get_statement, + &librdf_storage_audiodb_find_statements_finished); if(!stream) { + librdf_log(world, 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Couldn't create stream!"); librdf_storage_audiodb_find_statements_finished((void*)scontext); return NULL; } @@ -267,6 +445,9 @@ static void librdf_storage_audiodb_find_statements_finished(void* context) { librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; + + librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Finished!"); if(scontext->storage) librdf_storage_remove_reference(scontext->storage); @@ -283,102 +464,46 @@ librdf_sign_free(scontext); } -static int librdf_storage_audiodb_get_next_common(librdf_storage_audiodb_instance* scontext, - librdf_statement **statement, - librdf_node **context_node) { - - librdf_node* node; - - - if(!*statement) { - if(!(*statement = librdf_new_statement(librdf_storage_get_world(scontext->storage)))) - return 1; - } - - librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, - "Handle statement %s", librdf_statement_to_string(*statement)); - - librdf_statement_clear(*statement); - - node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "testing"); - - if(!node) - return 1; - - librdf_statement_set_subject(*statement, node); - - node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "foootle"); - - if(!node) - return 1; - - librdf_statement_set_predicate(*statement, node); - - node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "barble"); - - if(!node) - return 1; - - librdf_statement_set_object(*statement, node); - - return -1; -} - static int librdf_storage_audiodb_find_statements_end_of_stream(void* context) { librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; + librdf_world* world = librdf_storage_get_world(scontext->storage); + librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Finished?"); - if(scontext->finished) - return 1; - - if(scontext->statement == NULL) { - int result; - result = librdf_storage_audiodb_get_next_common(scontext->audiodb_context, - &scontext->statement, - &scontext->context); - - librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, - "Handle eos statement %s %d", librdf_statement_to_string(scontext->query_statement), result); - - if(result) { - scontext->finished = 1; - } - } - return scontext->finished; - + return (scontext->results->head == NULL); } static int librdf_storage_audiodb_find_statements_next_statement(void* context) { librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; - int result; - - if(scontext->finished) + librdf_world* world = librdf_storage_get_world(scontext->storage); + librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "to next"); + + if(scontext->results->head->next) + { + scontext->results->head = scontext->results->head->next; + return 0; + } + else + { return 1; - - result = librdf_storage_audiodb_get_next_common(scontext->audiodb_context, - &scontext->statement, - &scontext->context); - - librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, - "Handle next statement %s %d", librdf_statement_to_string(scontext->query_statement), result); - - if(result) { - scontext->finished = 1; } - - return result; } static void* librdf_storage_audiodb_find_statements_get_statement(void* context, int flags) { librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; - + librdf_world* world = librdf_storage_get_world(scontext->storage); + librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, + "Get next"); + switch(flags) { case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT: - return scontext->statement; + return scontext->results->head->statement; case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT: return scontext->context; default: - librdf_log(librdf_storage_get_world(scontext->storage), + librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "Unknown iterator method flag %d", flags); return NULL;
--- a/sparql/mod_audiodb/Makefile.am Wed Aug 12 14:57:11 2009 +0000 +++ b/sparql/mod_audiodb/Makefile.am Thu Aug 13 11:20:56 2009 +0000 @@ -7,7 +7,7 @@ EXTRA_DIST = $(SOURCE) $(HEAD) mod_audiodb.so: $(SOURCE) $(HEAD) - @APXS@ -Wc,-g\ -Wall `@APREQ2@ --ldflags --libs --includes` -lrdf -laudioDB -I/usr/include/ $(GLIB_CFLAGS) -c $(SOURCE) + @APXS@ -Wc,-g\ -Wall `@APREQ2@ --ldflags --libs --includes` `pkg-config rasqal --cflags --libs` -lrdf -laudioDB -I/usr/include/ $(GLIB_CFLAGS) -c $(SOURCE) install: mod_audiodb.so @APXS@ -i -a `test -f mod_audiodb.so && echo "mod_audiodb.so" || echo "mod_audiodb.la"`
--- a/sparql/mod_audiodb/mod_audiodb.c Wed Aug 12 14:57:11 2009 +0000 +++ b/sparql/mod_audiodb/mod_audiodb.c Thu Aug 13 11:20:56 2009 +0000 @@ -9,6 +9,7 @@ #include <apreq_parser.h> #include <apreq_param.h> #include "apreq2/apreq_module_apache2.h" +#include <rasqal.h> static int ap_dump_table(void *baton, const char *key, const char *value) { @@ -46,18 +47,10 @@ const unsigned char *query_string = apr_table_get(form_table, "query"); int rc = 0; - librdf_world* world = librdf_new_world(); - if(!world) - { - rc = 1; - goto error; - } - - librdf_world_open(world); librdf_world_set_logger(world, NULL, log_out); - librdf_storage* storage = librdf_new_storage(world, "audiodb", "/tmp/test.adb", "new='yes'"); + librdf_storage* storage = librdf_new_storage(world, "audiodb", "/tmp/test_database.adb", NULL); if(!storage) { rc = 2; @@ -85,7 +78,13 @@ goto error; } - ap_rprintf(r, "Everything went awesomely!"); + librdf_uri *sparql_uri = librdf_new_uri( world, "http://www.w3.org/TR/2006/WD-rdf-sparql-XMLres-20070614/"); + + unsigned char* out = librdf_query_results_to_string(results, sparql_uri, librdf_new_uri(world, "http://purl.org/ontology/af/")); + librdf_storage_close(storage); + librdf_free_storage(storage); + librdf_free_world(world); + ap_rprintf(r, out); rc = 0; return r->status;