mas01mj@585: #include mas01mj@584: #include mas01mj@584: #include mas01mj@584: #include mas01mj@584: #include mas01mj@584: #ifdef HAVE_STDLIB_H mas01mj@584: #include /* for abort() as used in errors */ mas01mj@584: #endif mas01mj@584: #include mas01mj@585: #include mas01mj@584: #include mas01mj@584: mas01mj@585: #define LIBRDF_SIGN_KEY 0x04Ed1A7D mas01mj@584: mas01mj@584: typedef struct { mas01mj@584: librdf_model* model; mas01mj@584: librdf_storage* storage; mas01mj@584: char *name; mas01mj@584: size_t name_len; mas01mj@584: int is_new; mas01mj@584: mas01mj@584: adb_t *adb; mas01mj@584: mas01mj@584: } librdf_storage_audiodb_instance; mas01mj@584: mas01mj@584: typedef struct { mas01mj@584: librdf_storage* storage; mas01mj@584: librdf_storage_audiodb_instance* audiodb_context; mas01mj@584: int finished; mas01mj@584: librdf_statement* statement; mas01mj@584: librdf_statement* query_statement; mas01mj@584: librdf_node* context; mas01mj@584: mas01mj@584: } librdf_storage_audiodb_find_statements_stream_context; mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_init(librdf_storage* storage, const char *name, librdf_hash* options); mas01mj@584: static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model); mas01mj@584: static int librdf_storage_audiodb_close(librdf_storage* storage); mas01mj@584: static int librdf_storage_audiodb_size(librdf_storage* storage); mas01mj@584: static int librdf_storage_audiodb_add_statement(librdf_storage* storage, librdf_statement* statement); mas01mj@584: static int librdf_storage_audiodb_add_statements(librdf_storage* storage, librdf_stream* statement_stream); mas01mj@584: static int librdf_storage_audiodb_remove_statement(librdf_storage* storage, librdf_statement* statement); mas01mj@584: static int librdf_storage_audiodb_contains_statement(librdf_storage* storage, librdf_statement* statement); mas01mj@584: static librdf_stream* librdf_storage_audiodb_serialise(librdf_storage* storage); mas01mj@584: static librdf_stream* librdf_storage_audiodb_find_statements(librdf_storage* storage, librdf_statement* statement); mas01mj@584: mas01mj@584: /* find_statements implementing functions */ mas01mj@584: static int librdf_storage_audiodb_find_statements_end_of_stream(void* context); mas01mj@584: static int librdf_storage_audiodb_find_statements_next_statement(void* context); mas01mj@584: static void* librdf_storage_audiodb_find_statements_get_statement(void* context, int flags); mas01mj@584: static void librdf_storage_audiodb_find_statements_finished(void* context); mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_sync(librdf_storage *storage); mas01mj@584: mas01mj@584: static void librdf_storage_audiodb_register_factory(librdf_storage_factory *factory); mas01mj@584: void librdf_storage_module_register_factory(librdf_world *world); mas01mj@585: mas01mj@585: void librdf_sign_free(void *ptr) mas01mj@585: { mas01mj@585: int *p; mas01mj@585: mas01mj@585: if(!ptr) mas01mj@585: return; mas01mj@585: mas01mj@585: p=(int*)ptr; mas01mj@585: p--; mas01mj@585: mas01mj@585: if(*p != LIBRDF_SIGN_KEY) mas01mj@585: return; mas01mj@585: mas01mj@585: free(p); mas01mj@585: } mas01mj@585: mas01mj@585: mas01mj@585: void* librdf_sign_calloc(size_t nmemb, size_t size) mas01mj@585: { mas01mj@585: int *p; mas01mj@585: mas01mj@585: /* turn into bytes */ mas01mj@585: size = nmemb*size + sizeof(int); mas01mj@585: mas01mj@585: p=(int*)calloc(1, size); mas01mj@585: *p++ = LIBRDF_SIGN_KEY; mas01mj@585: return p; mas01mj@585: } mas01mj@585: mas01mj@585: void* librdf_sign_malloc(size_t size) mas01mj@585: { mas01mj@585: int *p; mas01mj@585: mas01mj@585: size += sizeof(int); mas01mj@585: mas01mj@585: p=(int*)malloc(size); mas01mj@585: *p++ = LIBRDF_SIGN_KEY; mas01mj@585: return p; mas01mj@585: } mas01mj@584: mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_init(librdf_storage* storage, const char *name, librdf_hash* options) { mas01mj@584: mas01mj@584: librdf_storage_audiodb_instance* context; mas01mj@584: char* name_copy; mas01mj@584: mas01mj@585: context = (librdf_storage_audiodb_instance*)librdf_sign_calloc(1, sizeof(librdf_storage_audiodb_instance)); mas01mj@584: mas01mj@584: if(!context) mas01mj@584: { mas01mj@584: if(options) mas01mj@584: librdf_free_hash(options); mas01mj@584: return 1; mas01mj@584: } mas01mj@584: mas01mj@584: librdf_storage_set_instance(storage, context); mas01mj@584: mas01mj@584: context->storage = storage; mas01mj@584: mas01mj@584: // Store the name of the db mas01mj@584: context->name_len=strlen(name); mas01mj@585: name_copy=(char*)librdf_sign_malloc(context->name_len+1); mas01mj@584: if(!name_copy) { mas01mj@584: if(options) mas01mj@584: librdf_free_hash(options); mas01mj@584: return 1; mas01mj@584: } mas01mj@584: strncpy(name_copy, name, context->name_len+1); mas01mj@584: context->name=name_copy; mas01mj@584: mas01mj@584: if(librdf_hash_get_as_boolean(options, "new") > 0) mas01mj@584: context->is_new = 1; mas01mj@584: mas01mj@584: if(options) mas01mj@584: librdf_free_hash(options); mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Initialised!"); mas01mj@584: mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_open(librdf_storage* storage, librdf_model* model) { mas01mj@584: mas01mj@585: librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); mas01mj@584: int db_file_exists = 0; mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "open"); mas01mj@584: mas01mj@584: if(!access((const char*)context->name, F_OK)) mas01mj@584: db_file_exists = 1; mas01mj@584: else mas01mj@584: context->is_new = 1; mas01mj@584: mas01mj@584: if(context->is_new && db_file_exists) mas01mj@584: unlink(context->name); mas01mj@584: mas01mj@584: context->adb = NULL; mas01mj@584: mas01mj@584: if(context->is_new) { mas01mj@584: if(!(context->adb = audiodb_create(context->name, 0, 0, 0))) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Unable to create %s", context->name); mas01mj@584: return 1; mas01mj@584: } mas01mj@584: } mas01mj@584: else mas01mj@584: { mas01mj@584: if(!(context->adb = audiodb_open(context->name, O_RDWR))) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Unable to open %s", context->name); mas01mj@584: return 1; mas01mj@584: } mas01mj@584: } mas01mj@584: mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_close(librdf_storage* storage) { mas01mj@585: librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "close"); mas01mj@584: mas01mj@584: if(context->adb) mas01mj@584: { mas01mj@584: audiodb_close(context->adb); mas01mj@584: context->adb = NULL; mas01mj@584: } mas01mj@584: mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_size(librdf_storage* storage) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "size"); mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_add_statement(librdf_storage* storage, librdf_statement* statement) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "add statement"); mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_add_statements(librdf_storage* storage, librdf_stream* statement_stream) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "add statements"); mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_remove_statement(librdf_storage* storage, librdf_statement* statement) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "remove statement"); mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_contains_statement(librdf_storage* storage, librdf_statement* statement) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Contains statement"); mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static librdf_stream* librdf_storage_audiodb_serialise(librdf_storage* storage) { mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "serialise"); mas01mj@584: return NULL; mas01mj@584: } mas01mj@584: mas01mj@584: static librdf_stream* librdf_storage_audiodb_find_statements(librdf_storage* storage, librdf_statement* statement) { mas01mj@584: mas01mj@585: librdf_storage_audiodb_instance* context = (librdf_storage_audiodb_instance*)librdf_storage_get_instance(storage); mas01mj@584: librdf_storage_audiodb_find_statements_stream_context* scontext; mas01mj@584: librdf_stream* stream; mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "find statements %s", librdf_statement_to_string(statement)); mas01mj@584: mas01mj@585: scontext = (librdf_storage_audiodb_find_statements_stream_context*)librdf_sign_calloc(1, sizeof(librdf_storage_audiodb_find_statements_stream_context)); mas01mj@584: mas01mj@584: if(!scontext) mas01mj@584: return NULL; mas01mj@584: mas01mj@584: scontext->storage = storage; mas01mj@584: librdf_storage_add_reference(scontext->storage); mas01mj@584: mas01mj@584: scontext->audiodb_context = context; mas01mj@584: mas01mj@584: scontext->query_statement = librdf_new_statement_from_statement(statement); mas01mj@584: if(!scontext->query_statement) { mas01mj@584: librdf_storage_audiodb_find_statements_finished((void*)scontext); mas01mj@584: return NULL; mas01mj@584: } mas01mj@584: mas01mj@585: stream = librdf_new_stream(librdf_storage_get_world(storage), mas01mj@584: (void*)scontext, mas01mj@584: &librdf_storage_audiodb_find_statements_end_of_stream, mas01mj@584: &librdf_storage_audiodb_find_statements_next_statement, mas01mj@584: &librdf_storage_audiodb_find_statements_get_statement, mas01mj@584: &librdf_storage_audiodb_find_statements_finished); mas01mj@584: mas01mj@584: if(!stream) { mas01mj@584: librdf_storage_audiodb_find_statements_finished((void*)scontext); mas01mj@584: return NULL; mas01mj@584: } mas01mj@584: mas01mj@584: return stream; mas01mj@584: } mas01mj@584: mas01mj@584: static void librdf_storage_audiodb_find_statements_finished(void* context) { mas01mj@584: librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; mas01mj@584: mas01mj@584: if(scontext->storage) mas01mj@584: librdf_storage_remove_reference(scontext->storage); mas01mj@584: mas01mj@584: if(scontext->query_statement) mas01mj@584: librdf_free_statement(scontext->query_statement); mas01mj@584: mas01mj@584: if(scontext->statement) mas01mj@584: librdf_free_statement(scontext->statement); mas01mj@584: mas01mj@584: if(scontext->context) mas01mj@584: librdf_free_node(scontext->context); mas01mj@584: mas01mj@585: librdf_sign_free(scontext); mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_get_next_common(librdf_storage_audiodb_instance* scontext, mas01mj@584: librdf_statement **statement, mas01mj@584: librdf_node **context_node) { mas01mj@584: mas01mj@584: librdf_node* node; mas01mj@584: mas01mj@584: mas01mj@584: if(!*statement) { mas01mj@585: if(!(*statement = librdf_new_statement(librdf_storage_get_world(scontext->storage)))) mas01mj@584: return 1; mas01mj@584: } mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@585: "Handle statement %s", librdf_statement_to_string(*statement)); mas01mj@584: mas01mj@584: librdf_statement_clear(*statement); mas01mj@584: mas01mj@585: node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "testing"); mas01mj@584: mas01mj@584: if(!node) mas01mj@584: return 1; mas01mj@584: mas01mj@584: librdf_statement_set_subject(*statement, node); mas01mj@584: mas01mj@585: node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "foootle"); mas01mj@584: mas01mj@584: if(!node) mas01mj@584: return 1; mas01mj@584: mas01mj@584: librdf_statement_set_predicate(*statement, node); mas01mj@584: mas01mj@585: node = librdf_new_node_from_uri_string(librdf_storage_get_world(scontext->storage), "barble"); mas01mj@584: mas01mj@584: if(!node) mas01mj@584: return 1; mas01mj@584: mas01mj@584: librdf_statement_set_object(*statement, node); mas01mj@584: mas01mj@584: return -1; mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_find_statements_end_of_stream(void* context) { mas01mj@584: librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; mas01mj@584: mas01mj@584: if(scontext->finished) mas01mj@584: return 1; mas01mj@584: mas01mj@584: if(scontext->statement == NULL) { mas01mj@584: int result; mas01mj@584: result = librdf_storage_audiodb_get_next_common(scontext->audiodb_context, mas01mj@584: &scontext->statement, mas01mj@584: &scontext->context); mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Handle eos statement %s %d", librdf_statement_to_string(scontext->query_statement), result); mas01mj@584: mas01mj@584: if(result) { mas01mj@584: scontext->finished = 1; mas01mj@584: } mas01mj@584: } mas01mj@584: return scontext->finished; mas01mj@584: mas01mj@584: } mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_find_statements_next_statement(void* context) { mas01mj@584: librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; mas01mj@584: int result; mas01mj@584: mas01mj@584: mas01mj@584: if(scontext->finished) mas01mj@584: return 1; mas01mj@584: mas01mj@584: result = librdf_storage_audiodb_get_next_common(scontext->audiodb_context, mas01mj@584: &scontext->statement, mas01mj@584: &scontext->context); mas01mj@584: mas01mj@585: librdf_log(librdf_storage_get_world(scontext->storage), 0, LIBRDF_LOG_INFO, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Handle next statement %s %d", librdf_statement_to_string(scontext->query_statement), result); mas01mj@584: mas01mj@584: if(result) { mas01mj@584: scontext->finished = 1; mas01mj@584: } mas01mj@584: mas01mj@584: return result; mas01mj@584: } mas01mj@584: mas01mj@584: static void* librdf_storage_audiodb_find_statements_get_statement(void* context, int flags) { mas01mj@584: librdf_storage_audiodb_find_statements_stream_context* scontext=(librdf_storage_audiodb_find_statements_stream_context*)context; mas01mj@584: mas01mj@584: switch(flags) { mas01mj@584: case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT: mas01mj@584: return scontext->statement; mas01mj@584: case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT: mas01mj@584: return scontext->context; mas01mj@584: default: mas01mj@585: librdf_log(librdf_storage_get_world(scontext->storage), mas01mj@584: 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, mas01mj@584: "Unknown iterator method flag %d", flags); mas01mj@584: return NULL; mas01mj@584: } mas01mj@584: mas01mj@584: } mas01mj@584: mas01mj@584: mas01mj@584: mas01mj@584: static int librdf_storage_audiodb_sync(librdf_storage *storage) { mas01mj@584: return 0; mas01mj@584: } mas01mj@584: mas01mj@584: static void mas01mj@584: librdf_storage_audiodb_register_factory(librdf_storage_factory *factory) { mas01mj@584: factory->version = LIBRDF_STORAGE_INTERFACE_VERSION; mas01mj@584: factory->init = librdf_storage_audiodb_init; mas01mj@584: factory->open = librdf_storage_audiodb_open; mas01mj@584: factory->close = librdf_storage_audiodb_close; mas01mj@584: factory->size = librdf_storage_audiodb_size; mas01mj@584: factory->add_statement = librdf_storage_audiodb_add_statement; mas01mj@584: factory->remove_statement = librdf_storage_audiodb_remove_statement; mas01mj@584: factory->contains_statement = librdf_storage_audiodb_contains_statement; mas01mj@584: factory->serialise = librdf_storage_audiodb_serialise; mas01mj@584: factory->find_statements = librdf_storage_audiodb_find_statements; mas01mj@584: } mas01mj@584: mas01mj@584: /** Entry point for dynamically loaded storage module */ mas01mj@584: void librdf_storage_module_register_factory(librdf_world *world) { mas01mj@584: librdf_storage_register_factory(world, "audiodb", "AudioDB", mas01mj@584: &librdf_storage_audiodb_register_factory); mas01mj@584: }