/** * librdf_new_serializer_from_factory: * @world: redland world object * @factory: the serializer factory to use to create this serializer * * Constructor - create a new #librdf_serializer object. * * Return value: new #librdf_serializer object or NULL **/ librdf_serializer* librdf_new_serializer_from_factory(librdf_world *world, librdf_serializer_factory *factory) { librdf_serializer* d; librdf_world_open(world); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(factory, librdf_serializer_factory, NULL); d=(librdf_serializer*)LIBRDF_CALLOC(librdf_serializer, 1, sizeof(librdf_serializer)); if(!d) return NULL; d->context=(char*)LIBRDF_CALLOC(serializer_context, 1, factory->context_length); if(!d->context) { librdf_free_serializer(d); return NULL; } d->world=world; d->factory=factory; if(factory->init) if(factory->init(d, d->context)) { librdf_free_serializer(d); return NULL; } return d; }
/** * librdf_init_concepts: * @world: redland world object * * INTERNAL - Initialise the concepts module. * **/ void librdf_init_concepts(librdf_world *world) { int i; /* Create the Unique URI objects */ world->concept_ms_namespace_uri=librdf_new_uri(world, librdf_concept_ms_namespace); world->concept_schema_namespace_uri=librdf_new_uri(world, librdf_concept_schema_namespace); if(!world->concept_ms_namespace_uri || !world->concept_schema_namespace_uri) LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Failed to create M&S or Schema URIs"); /* Create arrays for the M&S and Schema resource nodes and uris */ world->concept_uris= (librdf_uri**)LIBRDF_CALLOC(ptrarray, LIBRDF_CONCEPT_LAST+1, sizeof(librdf_uri*)); world->concept_resources= (librdf_node**)LIBRDF_CALLOC(ptrarray, LIBRDF_CONCEPT_LAST+1, sizeof(librdf_node*)); if(!world->concept_uris || !world->concept_resources) LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Out of memory creating node/uri arrays"); /* Create the M&S and Schema resource nodes */ for (i=0; i<= LIBRDF_CONCEPT_LAST; i++) { librdf_uri* ns_uri=(i < LIBRDF_CONCEPT_FIRST_S_ID) ? world->concept_ms_namespace_uri : world->concept_schema_namespace_uri; const unsigned char * token=(const unsigned char *)librdf_concept_tokens[i]; world->concept_resources[i]=librdf_new_node_from_uri_local_name(world, ns_uri, token); if(!world->concept_resources[i]) LIBRDF_FATAL1(world, LIBRDF_FROM_CONCEPTS, "Failed to create Node from URI\n"); /* keep shared copy of URI from node */ world->concept_uris[i]=librdf_node_get_uri(world->concept_resources[i]); } }
/** * librdf_storage_register_factory - Register a storage factory * @name: the storage factory name * @label: the storage factory label * @factory: pointer to function to call to register the factory * **/ void librdf_storage_register_factory(const char *name, const char *label, void (*factory) (librdf_storage_factory*)) { librdf_storage_factory *storage, *h; char *name_copy; char *label_copy; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Received registration for storage %s\n", name); #endif storage=(librdf_storage_factory*)LIBRDF_CALLOC(librdf_storage_factory, 1, sizeof(librdf_storage_factory)); if(!storage) LIBRDF_FATAL1(world, "Out of memory"); name_copy=(char*)LIBRDF_CALLOC(cstring, strlen(name)+1, 1); if(!name_copy) { LIBRDF_FREE(librdf_storage, storage); LIBRDF_FATAL1(world, "Out of memory"); } strcpy(name_copy, name); storage->name=name_copy; for(h = storages; h; h = h->next ) { if(!strcmp(h->name, name_copy)) { LIBRDF_FREE(cstring, name_copy); LIBRDF_FREE(librdf_storage, storage); LIBRDF_ERROR2(NULL, "storage %s already registered\n", h->name); return; } } label_copy=(char*)LIBRDF_CALLOC(cstring, strlen(label)+1, 1); if(!label_copy) { LIBRDF_FREE(librdf_storage, storage); LIBRDF_FATAL1(world, "Out of memory"); } strcpy(label_copy, label); storage->label=label_copy; /* Call the storage registration function on the new object */ (*factory)(storage); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("%s has context size %d\n", name, storage->context_length); #endif storage->next = storages; storages = storage; }
/* functions implementing storage api */ static int librdf_storage_tstore_init(librdf_storage* storage, const char *name, librdf_hash* options) { librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)LIBRDF_CALLOC( librdf_storage_tstore_instance, 1, sizeof(librdf_storage_tstore_instance)); if(!context) { if(options) librdf_free_hash(options); return 1; } librdf_storage_set_instance(storage, context); context->host=librdf_hash_get_del(options, "host"); context->db=librdf_hash_get_del(options, "database"); context->user=librdf_hash_get_del(options, "user"); context->password=librdf_hash_get_del(options, "password"); context->model=librdf_hash_get_del(options, "model"); /* no more options, might as well free them now */ if(options) librdf_free_hash(options); return 0; }
static librdf_stream* librdf_storage_tstore_serialise(librdf_storage* storage) { librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance; librdf_storage_tstore_serialise_stream_context* scontext; librdf_stream* stream; scontext=(librdf_storage_tstore_serialise_stream_context*)LIBRDF_CALLOC(librdf_storage_tstore_serialise_stream_context, 1, sizeof(librdf_storage_tstore_serialise_stream_context)); if(!scontext) return NULL; scontext->storage=storage; librdf_storage_add_reference(scontext->storage); scontext->result=rs_find_all_resources(context->rdfsql, 0, context->model); if(!scontext->result) /* empty */ scontext->triple=NULL; else scontext->triple=rs_next_triple(scontext->result); stream=librdf_new_stream(storage->world, (void*)scontext, &librdf_storage_tstore_serialise_end_of_stream, &librdf_storage_tstore_serialise_next_statement, &librdf_storage_tstore_serialise_get_statement, &librdf_storage_tstore_serialise_finished); if(!stream) { librdf_storage_tstore_serialise_finished((void*)scontext); return NULL; } return stream; }
/** * librdf_node_new_static_node_iterator: * @world: world object * @nodes: static array of #librdf_node objects * @size: size of array * * Create an iterator over an array of nodes. * * This creates an iterator for an existing static array of librdf_node * objects. It is mostly intended for testing iterator code. * * Return value: a #librdf_iterator serialization of the nodes or NULL on failure **/ librdf_iterator* librdf_node_new_static_node_iterator(librdf_world* world, librdf_node** nodes, int size) { librdf_node_static_iterator_context* context; librdf_iterator* iterator; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(nodes, librdf_node**, NULL); context = (librdf_node_static_iterator_context*)LIBRDF_CALLOC(librdf_node_static_iterator_context, 1, sizeof(*context)); if(!context) return NULL; context->nodes = nodes; context->size = size; context->current = 0; iterator = librdf_new_iterator(world, (void*)context, librdf_node_static_iterator_is_end, librdf_node_static_iterator_next_method, librdf_node_static_iterator_get_method, librdf_node_static_iterator_finished); if(!iterator) librdf_node_static_iterator_finished(context); return iterator; }
/** * librdf_new_stream: * @world: redland world object * @context: context to pass to the stream implementing objects * @is_end_method: pointer to function to test for end of stream * @next_method: pointer to function to move to the next statement in stream * @get_method: pointer to function to get the current statement * @finished_method: pointer to function to finish the stream. * * Constructor - create a new #librdf_stream. * * Creates a new stream with an implementation based on the passed in * functions. The functions next_statement and end_of_stream will be called * multiple times until either of them signify the end of stream by * returning NULL or non 0 respectively. The finished function is called * once only when the stream object is destroyed with librdf_free_stream() * * A mapping function can be set for the stream using librdf_stream_add_map() * function which allows the statements generated by the stream to be * filtered and/or altered as they are generated before passing back * to the user. * * Return value: a new #librdf_stream object or NULL on failure **/ REDLAND_EXTERN_C librdf_stream* librdf_new_stream(librdf_world *world, void* context, int (*is_end_method)(void*), int (*next_method)(void*), void* (*get_method)(void*, int), void (*finished_method)(void*)) { librdf_stream* new_stream; librdf_world_open(world); new_stream=(librdf_stream*)LIBRDF_CALLOC(librdf_stream, 1, sizeof(librdf_stream)); if(!new_stream) return NULL; new_stream->world=world; new_stream->context=context; new_stream->is_end_method=is_end_method; new_stream->next_method=next_method; new_stream->get_method=get_method; new_stream->finished_method=finished_method; new_stream->is_finished=0; new_stream->current=NULL; return new_stream; }
/** * librdf_list_unshift - add a data item to the start of a librdf_list * @list: &librdf_list object * @data: the data value * * if librdf_list_shift() is called after this, it will return the value * added here. * * Return value: non 0 on failure **/ int librdf_list_unshift(librdf_list* list, void *data) { librdf_list_node* node; /* need new node */ node=(librdf_list_node*)LIBRDF_CALLOC(librdf_list_node, 1, sizeof(librdf_list_node)); if(!node) return 1; node->data=data; /* if there is a list, connect the new node to the first node */ if(list->first) { node->next=list->first; list->first->prev=node; } /* make this node the first node always */ list->first=node; /* if there is no list at all, make this the last too */ if(!list->last) list->last=node; /* node->next = NULL implicitly */ list->length++; return 0; }
/** * librdf_iterator_add_map - Add a librdf_iterator mapping function * @iterator: the iterator * @fn: the function to operate * @free_context: the function to use to free the context (or NULL) * @map_context: the context to pass to the map function * * Adds an iterator mapping function which operates over the iterator to * select which elements are returned; it will be applied as soon as * this method is called. * * Several mapping functions can be added and they are applied in * the order given * * The mapping function should return non 0 to allow the element to be * returned. * * Return value: Non 0 on failure **/ int librdf_iterator_add_map(librdf_iterator* iterator, librdf_iterator_map_handler map_function, librdf_iterator_map_free_context_handler free_context, void *map_context) { librdf_iterator_map *map; if(!iterator->map_list) { iterator->map_list=librdf_new_list(iterator->world); if(!iterator->map_list) return 1; } map=(librdf_iterator_map*)LIBRDF_CALLOC(librdf_iterator_map, sizeof(librdf_iterator_map), 1); if(!map) return 1; map->fn=map_function; map->free_context=free_context; map->context=map_context; if(librdf_list_add(iterator->map_list, map)) { LIBRDF_FREE(librdf_iterator_map, map); return 1; } return 0; }
/** * librdf_new_iterator - Constructor - create a new librdf_iterator object * @world: redland world object * @context: context to pass to the iterator functions * @is_end: function to call to see if the iteration has ended * @get_next: function to get the next element * @finished: function to destroy the iterator context (or NULL if not needed) * * Return value: a new &librdf_iterator object or NULL on failure **/ librdf_iterator* librdf_new_iterator(librdf_world *world, void* context, int (*is_end_method)(void*), int (*next_method)(void*), void* (*get_method)(void*, int), void (*finished_method)(void*)) { librdf_iterator* new_iterator; new_iterator=(librdf_iterator*)LIBRDF_CALLOC(librdf_iterator, 1, sizeof(librdf_iterator)); if(!new_iterator) return NULL; new_iterator->world=world; new_iterator->context=context; new_iterator->is_end_method=is_end_method; new_iterator->next_method=next_method; new_iterator->get_method=get_method; new_iterator->finished_method=finished_method; new_iterator->is_finished=0; new_iterator->current=NULL; return new_iterator; }
/** * librdf_new_world: * * Create a new Redland execution environment. * * Once this constructor is called to build a #librdf_world object * several functions may be called to set some parameters such as * librdf_world_set_error(), librdf_world_set_warning(), * librdf_world_set_logger(), librdf_world_set_digest(), * librdf_world_set_feature(). * * The world object needs initializing using librdf_world_open() * whether or not the above functions are called. It will be * automatically called by all object constructors in Redland 1.0.6 * or later, but for earlier versions it MUST be called before using * any other part of Redland. * * Returns: a new #librdf_world or NULL on failure */ librdf_world* librdf_new_world(void) { librdf_world *world; #ifdef HAVE_GETTIMEOFDAY struct timeval tv; struct timezone tz; #endif world = (librdf_world*)LIBRDF_CALLOC(librdf_world, sizeof(*world), 1); if(!world) return NULL; #ifdef HAVE_GETTIMEOFDAY if(!gettimeofday(&tv, &tz)) { world->genid_base = tv.tv_sec; } else world->genid_base = 1; #else world->genid_base = 1; #endif world->genid_counter = 1; #ifdef MODULAR_LIBRDF world->ltdl_opened = !(lt_dlinit()); if (world->ltdl_opened) lt_dlsetsearchpath(REDLAND_MODULE_PATH); else LIBRDF_DEBUG1("lt_dlinit() failed\n"); #endif return world; }
/** * librdf_new_storage_from_storage - Copy constructor - create a new librdf_storage object from an existing one * @old_storage: the existing storage &librdf_storage to use * * Should create a new storage in the same context as the existing one * as appropriate for the storage. For example, in a RDBMS storage * it would be a new database, or in on disk it would be a new * set of files. This will mean automatically generating * a new identifier for the storage, maybe based on the existing * storage identifier. * * Return value: a new &librdf_storage object or NULL on failure */ librdf_storage* librdf_new_storage_from_storage(librdf_storage* old_storage) { librdf_storage* new_storage; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(old_storage, librdf_storage, NULL); if(!old_storage->factory->clone) { LIBRDF_ERROR2(old_storage->world, "clone method not implemented for storage factory %s", old_storage->factory->name); return NULL; } new_storage=(librdf_storage*)LIBRDF_CALLOC(librdf_storage, 1, sizeof(librdf_storage)); if(!new_storage) return NULL; new_storage->context=(char*)LIBRDF_CALLOC(librdf_storage_context, 1, old_storage->factory->context_length); if(!new_storage->context) { librdf_free_storage(new_storage); return NULL; } new_storage->world=old_storage->world; /* do this now so librdf_free_storage won't call new factory on * partially copied storage */ new_storage->factory=old_storage->factory; /* clone is assumed to do leave the new storage in the same state * after an init() method on an existing storage - i.e ready to * use but closed. */ if(old_storage->factory->clone(new_storage, old_storage)) { librdf_free_storage(new_storage); return NULL; } new_storage->usage=1; return new_storage; }
/** * librdf_avltree_get_iterator_start: * @list: #librdf_avltree object * * Get an (in-order) iterator for the start of a range, or the entire tree * (if range is NULL). If range specifies a range (i.e. the tree comparison * function will 'match' (return 0 for) range and /several/ nodes), the * iterator will be placed at the leftmost child matching range, and * librdf_avltree_iterator_next will iterate over all nodes * (and only nodes) that match range. * * Return value: a new #librdf_iterator object or NULL on failure **/ librdf_iterator* librdf_avltree_get_iterator_start(librdf_world* world, librdf_avltree* tree, void* range, librdf_avltree_data_free_function range_free_fn) { librdf_avltree_iterator_context* context; librdf_iterator* iterator; context = (librdf_avltree_iterator_context*)LIBRDF_CALLOC(librdf_avltree_iterator_context, 1, sizeof(*context)); if(!context) return NULL; context->tree = tree; context->range = range; context->range_free_fn = range_free_fn; if(range != NULL) { /* find the topmost match (range is contained entirely in tree rooted here) */ context->current = librdf_avltree_search_internal(tree, tree->root, range); } else { context->current=tree->root; } context->root = context->current; /* go down to find start of range (or tree) */ if(context->current) { while(1) { librdf_avltree_node* pred; context->current = librdf_avltree_node_leftmost(tree, context->current, range); /* right until we find a match */ pred = librdf_avltree_node_search_right(tree, context->current->left, range); if(pred && tree->compare_fn(range, pred->data) == 0) context->current = pred; else break; } } iterator=librdf_new_iterator(world, (void*)context, librdf_avltree_iterator_is_end, librdf_avltree_iterator_next_method, librdf_avltree_iterator_get_method, librdf_avltree_iterator_finished); if(!iterator) { librdf_avltree_iterator_finished(context); } return iterator; }
/** * librdf_new_storage_from_factory - Constructor - create a new librdf_storage object * @world: redland world object * @factory: the factory to use to construct the storage * @name: name to use for storage * @options: &librdf_hash of options to initialise storage * * If the options are present, they become owned by the storage * and should no longer be used. * * Return value: a new &librdf_storage object or NULL on failure */ librdf_storage* librdf_new_storage_from_factory (librdf_world *world, librdf_storage_factory* factory, char *name, librdf_hash* options) { librdf_storage* storage; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(factory, librdf_storage_factory, NULL); if(!factory) { librdf_free_hash(options); return NULL; } storage=(librdf_storage*)LIBRDF_CALLOC(librdf_storage, 1, sizeof(librdf_storage)); if(!storage) { librdf_free_hash(options); return NULL; } storage->world=world; storage->context=(char*)LIBRDF_CALLOC(librdf_storage_context, 1, factory->context_length); if(!storage->context) { librdf_free_hash(options); librdf_free_storage(storage); return NULL; } storage->factory=factory; if(factory->init(storage, name, options)) { librdf_free_storage(storage); return NULL; } storage->usage=1; return storage; }
/** * librdf_storage_tstore_find_statements: * @storage: the storage * @statement: the statement to match * * . * * Return a stream of statements matching the given statement (or * all statements if NULL). Parts (subject, predicate, object) of the * statement can be empty in which case any statement part will match that. * Uses #librdf_statement_match to do the matching. * * Return value: a #librdf_stream or NULL on failure **/ static librdf_stream* librdf_storage_tstore_find_statements(librdf_storage* storage, librdf_statement* statement) { librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance; librdf_storage_tstore_find_stream_context* scontext; librdf_stream* stream; rs_triple* triple; rs_obj_type type; statement=librdf_new_statement_from_statement(statement); if(!statement) return NULL; scontext=(librdf_storage_tstore_find_stream_context*)LIBRDF_CALLOC(librdf_storage_tstore_find_stream_context, 1, sizeof(librdf_storage_tstore_find_stream_context)); if(!scontext) return NULL; scontext->storage=storage; librdf_storage_add_reference(scontext->storage); triple=librdf_storage_tstore_statement_as_rs_triple(statement); scontext->search_triple=triple; if(triple->object) type=(triple->literal ? ObjLiteral: ObjURI); else type=ObjAny; scontext->result=rs_find_triples(context->rdfsql, triple->subject, triple->predicate, triple->object, type, 0, context->model); if(!scontext->result) /* empty */ scontext->triple=NULL; else scontext->triple=rs_next_triple(scontext->result); stream=librdf_new_stream(storage->world, (void*)scontext, &librdf_storage_tstore_find_end_of_stream, &librdf_storage_tstore_find_next_statement, &librdf_storage_tstore_find_get_statement, &librdf_storage_tstore_find_finished); if(!stream) { librdf_storage_tstore_find_finished((void*)scontext); return NULL; } return stream; }
/** * librdf_new_list - Constructor - create a new librdf_list * @world: redland world object * * Return value: a new &librdf_list or NULL on failure **/ librdf_list* librdf_new_list(librdf_world *world) { librdf_list* new_list; new_list=(librdf_list*)LIBRDF_CALLOC(librdf_list, 1, sizeof(librdf_list)); if(!new_list) return NULL; new_list->world=world; return new_list; }
/* functions implementing storage api */ static int librdf_storage_trees_init(librdf_storage* storage, const char *name, librdf_hash* options) { const int index_spo_option = librdf_hash_get_as_boolean(options, "index-spo") > 0; const int index_sop_option = librdf_hash_get_as_boolean(options, "index-sop") > 0; const int index_ops_option = librdf_hash_get_as_boolean(options, "index-ops") > 0; const int index_pso_option = librdf_hash_get_as_boolean(options, "index-pso") > 0; librdf_storage_trees_instance* context=(librdf_storage_trees_instance*)LIBRDF_CALLOC( librdf_storage_trees_instance, 1, sizeof(librdf_storage_trees_instance)); if(!context) { if(options) librdf_free_hash(options); return 1; } librdf_storage_set_instance(storage, context); #ifdef RDF_STORAGE_TREES_WITH_CONTEXTS /* Support contexts if option given */ if (librdf_hash_get_as_boolean(options, "contexts") > 0) { context->contexts=librdf_new_avltree(librdf_storage_trees_graph_compare, librdf_storage_trees_graph_free); } else { context->contexts=NULL; } #endif /* No indexing options given, index all by default */ if (!index_spo_option && !index_sop_option && !index_ops_option && !index_pso_option) { context->index_sop=1; context->index_ops=1; context->index_pso=1; } else { /* spo is always indexed, option just exists so user can * specifically /only/ index spo */ context->index_sop=index_sop_option; context->index_ops=index_ops_option; context->index_pso=index_pso_option; } context->graph = librdf_storage_trees_graph_new(storage, NULL); /* no more options, might as well free them now */ if(options) librdf_free_hash(options); return 0; }
/** * librdf_new_statement: * @world: redland world object * * Constructor - create a new empty #librdf_statement. * * Return value: a new #librdf_statement or NULL on failure **/ librdf_statement* librdf_new_statement(librdf_world *world) { librdf_statement* new_statement; librdf_world_open(world); new_statement=(librdf_statement*)LIBRDF_CALLOC(librdf_statement, 1, sizeof(librdf_statement)); if(!new_statement) return NULL; new_statement->world=world; return new_statement; }
/** * librdf_list_get_iterator - get an iterator for the list * @list: &librdf_list object * * Return value: a new &librdf_iterator object or NULL on failure **/ librdf_iterator* librdf_list_get_iterator(librdf_list* list) { librdf_list_iterator_context* context; context=(librdf_list_iterator_context*)LIBRDF_CALLOC(librdf_list_iterator_context, 1, sizeof(librdf_list_iterator_context)); if(!context) return NULL; context->list=list; context->current=list->first; return librdf_new_iterator(list->world, (void*)context, librdf_list_iterator_is_end, librdf_list_iterator_next_method, librdf_list_iterator_get_method, librdf_list_iterator_finished); }
/** * librdf_new_empty_stream: * @world: redland world object * * Constructor - create a new #librdf_stream with no content. * * Return value: a new #librdf_stream object or NULL on failure **/ librdf_stream* librdf_new_empty_stream(librdf_world *world) { librdf_stream* new_stream; librdf_world_open(world); new_stream=(librdf_stream*)LIBRDF_CALLOC(librdf_stream, 1, sizeof(librdf_stream)); if(!new_stream) return NULL; new_stream->world=world; /* This ensures end, next, get_object, get_context factory methods * never get called and the methods always return finished. */ new_stream->is_finished=1; return new_stream; }
/** * librdf_stream_add_map: * @stream: the stream * @map_function: the function to perform the mapping * @free_context: the function to use to free the context (or NULL) * @map_context: the context to pass to the map function * * Add a librdf_stream mapping function. * * Adds an stream mapping function which operates over the stream to * select which elements are returned; it will be applied as soon as * this method is called. * * Several mapping functions can be added and they are applied in * the order given. * * The mapping function should return the statement to return, or NULL * to remove it from the stream. * * Return value: Non 0 on failure **/ int librdf_stream_add_map(librdf_stream* stream, librdf_stream_map_handler map_function, librdf_stream_map_free_context_handler free_context, void *map_context) { librdf_stream_map *map; if(!stream->map_list) { stream->map_list=librdf_new_list(stream->world); if(!stream->map_list) { if(free_context && map_context) (*free_context)(map_context); return 1; } } map=(librdf_stream_map*)LIBRDF_CALLOC(librdf_stream_map, sizeof(librdf_stream_map), 1); if(!map) { if(free_context && map_context) (*free_context)(map_context); return 1; } map->fn=map_function; map->free_context=free_context; map->context=map_context; if(librdf_list_add(stream->map_list, map)) { LIBRDF_FREE(librdf_stream_map, map); if(free_context && map_context) (*free_context)(map_context); return 1; } return 0; }
/** * librdf_new_stream_from_node_iterator: * @iterator: #librdf_iterator of #librdf_node objects * @statement: #librdf_statement prototype with one NULL node space * @field: node part of statement * * Constructor - create a new #librdf_stream from an iterator of nodes. * * Creates a new #librdf_stream using the passed in #librdf_iterator * which generates a series of #librdf_node objects. The resulting * nodes are then inserted into the given statement and returned. * The field attribute indicates which statement node is being generated. * * Return value: a new #librdf_stream object or NULL on failure **/ librdf_stream* librdf_new_stream_from_node_iterator(librdf_iterator* iterator, librdf_statement* statement, librdf_statement_part field) { librdf_stream_from_node_iterator_stream_context *scontext; librdf_stream *stream; scontext=(librdf_stream_from_node_iterator_stream_context*)LIBRDF_CALLOC(librdf_stream_from_node_iterator_stream_context, 1, sizeof(librdf_stream_from_node_iterator_stream_context)); if(!scontext) return NULL; /* copy the prototype statement */ statement=librdf_new_statement_from_statement(statement); if(!statement) { LIBRDF_FREE(librdf_stream_from_node_iterator_stream_context, scontext); return NULL; } scontext->iterator=iterator; scontext->current=statement; scontext->field=field; stream=librdf_new_stream(iterator->world, (void*)scontext, &librdf_stream_from_node_iterator_end_of_stream, &librdf_stream_from_node_iterator_next_statement, &librdf_stream_from_node_iterator_get_statement, &librdf_stream_from_node_iterator_finished); if(!stream) { librdf_stream_from_node_iterator_finished((void*)scontext); return NULL; } return stream; }
/** * librdf_new_uri2: * @world: redland world object * @uri_string: URI in string form * @length: length of string * * Constructor - create a new #librdf_uri object from a counted URI string. * * A new URI is constructed from a copy of the string. If the string * is a NULL pointer or 0 length or empty (first byte is 0) then the * result is NULL. * * Return value: a new #librdf_uri object or NULL on failure **/ librdf_uri* librdf_new_uri2(librdf_world *world, const unsigned char *uri_string, size_t length) { #ifdef LIBRDF_USE_RAPTOR_URI return raptor_new_uri_from_counted_string(world->raptor_world_ptr, uri_string, length); #else librdf_uri* new_uri; unsigned char *new_string; librdf_hash_datum key, value; /* on stack - not allocated */ librdf_hash_datum *old_value; /* just to be safe */ memset(&key, 0, sizeof(key)); memset(&value, 0, sizeof(value)); librdf_world_open(world); if(!uri_string || !length || !*uri_string) return NULL; #ifdef WITH_THREADS pthread_mutex_lock(world->mutex); #endif key.data = (char*)uri_string; key.size = length; /* if existing URI found in hash, return it */ if((old_value = librdf_hash_get_one(world->uris_hash, &key))) { new_uri = *(librdf_uri**)old_value->data; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("Found existing URI %s in hash with current usage %d\n", uri_string, new_uri->usage); #endif librdf_free_hash_datum(old_value); new_uri->usage++; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 if(new_uri->usage > new_uri->max_usage) new_uri->max_usage = new_uri->usage; #endif goto unlock; } /* otherwise create a new one */ #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Creating new URI %s in hash\n", uri_string); #endif new_uri = (librdf_uri*)LIBRDF_CALLOC(librdf_uri, 1, sizeof(librdf_uri)); if(!new_uri) goto unlock; new_uri->world = world; new_uri->string_length = length; new_string = (unsigned char*)LIBRDF_MALLOC(cstring, length+1); if(!new_string) { LIBRDF_FREE(librdf_uri, new_uri); new_uri = NULL; goto unlock; } strcpy((char*)new_string, (const char*)uri_string); new_uri->string = new_string; new_uri->usage = 1; #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 new_uri->max_usage = 1; #endif value.data = &new_uri; value.size = sizeof(librdf_uri*); /* store in hash: URI-string => (librdf_uri*) */ if(librdf_hash_put(world->uris_hash, &key, &value)) { LIBRDF_FREE(cstring, new_string); LIBRDF_FREE(librdf_uri, new_uri); new_uri = NULL; } unlock: #ifdef WITH_THREADS pthread_mutex_unlock(world->mutex); #endif return new_uri; #endif /* !LIBRDF_USE_RAPTOR_URI */ }
/* * librdf_storage_node_stream_to_node_create - Create a stream for get sources, targets or arcs methods using find_statements method * @storage: the storage object to use * @node1: the first node to encode in the key * @node2: the second node to encode in the key * @want: the field required from the statement * * Return value: a new &librdf_iterator or NULL on failure **/ static librdf_iterator* librdf_storage_node_stream_to_node_create(librdf_storage* storage, librdf_node *node1, librdf_node *node2, librdf_statement_part want) { librdf_statement *partial_statement; librdf_stream *stream; librdf_storage_stream_to_node_iterator_context* context; librdf_iterator *iterator; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node1, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node2, librdf_node, NULL); partial_statement=librdf_new_statement(storage->world); if(!partial_statement) return NULL; context=(librdf_storage_stream_to_node_iterator_context*)LIBRDF_CALLOC(librdf_storage_stream_to_node_iterator_context, 1, sizeof(librdf_storage_stream_to_node_iterator_context)); if(!context) { librdf_free_statement(partial_statement); return NULL; } switch(want) { case LIBRDF_STATEMENT_SUBJECT: librdf_statement_set_predicate(partial_statement, node1); librdf_statement_set_object(partial_statement, node2); break; case LIBRDF_STATEMENT_PREDICATE: librdf_statement_set_subject(partial_statement, node1); librdf_statement_set_object(partial_statement, node2); break; case LIBRDF_STATEMENT_OBJECT: librdf_statement_set_subject(partial_statement, node1); librdf_statement_set_predicate(partial_statement, node2); break; default: librdf_free_statement(partial_statement); LIBRDF_ERROR2(storage->world, "Illegal statement part %d seen\n", want); return NULL; } stream=storage->factory->find_statements(storage, partial_statement); if(!stream) { librdf_storage_stream_to_node_iterator_finished(context); return NULL; } /* initialise context */ context->partial_statement=partial_statement; context->stream=stream; context->want=want; context->storage=storage; librdf_storage_add_reference(context->storage); iterator=librdf_new_iterator(storage->world, (void*)context, librdf_storage_stream_to_node_iterator_is_end, librdf_storage_stream_to_node_iterator_next_method, librdf_storage_stream_to_node_iterator_get_method, librdf_storage_stream_to_node_iterator_finished); if(!iterator) librdf_storage_stream_to_node_iterator_finished(context); return iterator; }
/** * librdf_new_sql_config: * @world: librdf_world * @storage_name: SQL storage name * @layout: SQL schema variant * @config_dir: directory for configuration files * @predicate_uri_strings: configuration predicate URIs to look for * * Constructor - Make a new SQL configuration for a layout from a file * * Uses SQL storage name @storage_name and with database schema * @layout to give a configuration that will contain an array of * string values in the #librdf_sql_config field values array. * * Return value: configuration or NULL on failure **/ librdf_sql_config* librdf_new_sql_config(librdf_world* world, const char* storage_name, const char* layout, const char* config_dir, const char** predicate_uri_strings) { raptor_parser* rdf_parser=NULL; unsigned char *uri_string=NULL; raptor_uri *base_uri; raptor_uri *uri; librdf_sql_config* config; size_t len; int i; librdf_world_open(world); config=(librdf_sql_config*)LIBRDF_MALLOC(librdf_sql_config, sizeof(librdf_sql_config)); len=strlen(config_dir) + 1 + strlen(storage_name) + 4 + 1; if(layout) len+= strlen(layout) + 1; config->filename=(char*)LIBRDF_MALLOC(cstring, len); if(layout) sprintf(config->filename, "%s/%s-%s.ttl", config_dir, storage_name, layout); else sprintf(config->filename, "%s/%s.ttl", config_dir, storage_name); config->predicate_uri_strings=predicate_uri_strings; for(i=0; config->predicate_uri_strings[i]; i++) ; config->predicates_count=i; config->values=(char**)LIBRDF_CALLOC(cstring, sizeof(char*), config->predicates_count); LIBRDF_DEBUG4("Attempting to open %s layout %s storage config file %s\n", storage_name, (layout ? layout: "(default)"), config->filename); if(access((const char*)config->filename, R_OK)) { librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "Failed to open configuration file %s for storage %s layout %s - %s", config->filename, storage_name, (layout ? layout: "(default)"), strerror(errno)); librdf_free_sql_config(config); return NULL; } uri_string=raptor_uri_filename_to_uri_string(config->filename); uri=raptor_new_uri(uri_string); base_uri=raptor_uri_copy(uri); rdf_parser=raptor_new_parser("turtle"); raptor_set_statement_handler(rdf_parser, config, librdf_sql_config_store_triple); raptor_parse_file(rdf_parser, uri, base_uri); raptor_free_parser(rdf_parser); raptor_free_uri(base_uri); raptor_free_memory(uri_string); raptor_free_uri(uri); /* Check all values are given */ for(i=0; i < config->predicates_count; i++) { if(!config->values[i]) { librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL, "Configuration %s missing for storage %s", config->predicate_uri_strings[i], storage_name); librdf_free_sql_config(config); return NULL; } } return config; }
/** * librdf_serializer_register_factory: * @world: redland world object * @name: the name of the serializer * @label: the label of the serializer (optional) * @mime_type: MIME type of the syntax (optional) * @uri_string: URI of the syntax (optional) * @factory: function to be called to register the factor parameters * * Register a serializer factory . * **/ REDLAND_EXTERN_C void librdf_serializer_register_factory(librdf_world *world, const char *name, const char *label, const char *mime_type, const unsigned char *uri_string, void (*factory) (librdf_serializer_factory*)) { librdf_serializer_factory *serializer; librdf_world_open(world); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Received registration for serializer %s\n", name); #endif if(!world->serializers) { world->serializers = raptor_new_sequence((raptor_data_free_handler)librdf_free_serializer_factory, NULL); if(!world->serializers) goto oom; } serializer=(librdf_serializer_factory*)LIBRDF_CALLOC(librdf_serializer_factory, 1, sizeof(librdf_serializer_factory)); if(!serializer) goto oom; serializer->name=(char*)LIBRDF_MALLOC(cstring, strlen(name)+1); if(!serializer->name) goto oom_tidy; strcpy(serializer->name, name); if(label) { serializer->label=(char*)LIBRDF_MALLOC(cstring, strlen(label)+1); if(!serializer->label) goto oom_tidy; strcpy(serializer->label, label); } /* register mime type if any */ if(mime_type) { serializer->mime_type=(char*)LIBRDF_MALLOC(cstring, strlen(mime_type)+1); if(!serializer->mime_type) goto oom_tidy; strcpy(serializer->mime_type, mime_type); } /* register URI if any */ if(uri_string) { serializer->type_uri=librdf_new_uri(world, uri_string); if(!serializer->type_uri) goto oom_tidy; } if(raptor_sequence_push(world->serializers, serializer)) goto oom; /* Call the serializer registration function on the new object */ (*factory)(serializer); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("%s has context size %d\n", name, serializer->context_length); #endif return; oom_tidy: librdf_free_serializer_factory(serializer); oom: LIBRDF_FATAL1(world, LIBRDF_FROM_SERIALIZER, "Out of memory"); }
/* functions implementing storage api */ static int librdf_storage_file_init(librdf_storage* storage, const char *name, librdf_hash* options) { char *name_copy; char *contexts; int rc = 1; int is_uri = !strcmp(storage->factory->name, "uri"); const char *format_name = (is_uri ? "guess" : "rdfxml"); librdf_storage_file_instance* context; context = (librdf_storage_file_instance*)LIBRDF_CALLOC(librdf_storage_file_instance, 1, sizeof(librdf_storage_file_instance)); if(!context) goto done; librdf_storage_set_instance(storage, context); /* Cannot save contexts in a file; pass everything else on */ contexts = librdf_hash_get_del(options, "contexts"); if(contexts) LIBRDF_FREE(cstring, contexts); context->format_name = librdf_hash_get_del(options, "format"); if(context->format_name) { /* for 'file' and 'uri' storage, check this is a valid parser * for 'file' storage, also check this is a valid serializer */ if(!librdf_parser_check_name(storage->world, context->format_name) || (!is_uri && !librdf_serializer_check_name(storage->world, context->format_name))) { librdf_log(storage->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_STORAGE, NULL, "Ignoring storage %s format option '%s' - using default format '%s'", storage->factory->name, context->format_name, format_name); LIBRDF_FREE(cstring, context->format_name); context->format_name = NULL; } if(context->format_name) format_name = context->format_name; } if(is_uri) context->uri = librdf_new_uri(storage->world, (const unsigned char*)name); else { context->name_len = strlen(name); name_copy = (char*)LIBRDF_MALLOC(cstring, context->name_len+1); if(!name_copy) goto done; strcpy(name_copy,name); context->name = name_copy; context->uri = librdf_new_uri_from_filename(storage->world, context->name); } context->storage = librdf_new_storage_with_options(storage->world, NULL, NULL, options); if(!context->storage) goto done; context->model = librdf_new_model(storage->world, context->storage, NULL); if(!context->model) goto done; if(is_uri || !access((const char*)context->name, F_OK)) { librdf_parser *parser; parser = librdf_new_parser(storage->world, format_name, NULL, NULL); if(!parser) { rc = 1; goto done; } librdf_parser_parse_into_model(parser, context->uri, NULL, context->model); librdf_free_parser(parser); } context->changed = 0; rc = 0; done: /* no more options, might as well free them now */ if(options) librdf_free_hash(options); return rc; }
static librdf_stream* librdf_storage_trees_serialise_range(librdf_storage* storage, librdf_statement* range) { librdf_storage_trees_instance* context=(librdf_storage_trees_instance*)storage->instance; librdf_storage_trees_serialise_stream_context* scontext; librdf_stream* stream; int filter = 0; scontext=(librdf_storage_trees_serialise_stream_context*)LIBRDF_CALLOC(librdf_storage_trees_serialise_stream_context, 1, sizeof(librdf_storage_trees_serialise_stream_context)); if(!scontext) return NULL; scontext->iterator = NULL; /* ?s ?p ?o */ if (!range || (!range->subject && !range->predicate && !range->object)) { scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->spo_tree, NULL, NULL); if (range) { librdf_free_statement(range); range=NULL; } /* s ?p o */ } else if (range->subject && !range->predicate && range->object) { if (context->index_sop) scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->sop_tree, range, librdf_storage_trees_avl_free); else filter=1; /* s _ _ */ } else if (range->subject) { scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->spo_tree, range, librdf_storage_trees_avl_free); /* ?s _ o */ } else if (range->object) { if (context->index_ops) scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->ops_tree, range, librdf_storage_trees_avl_free); else filter=1; /* ?s p ?o */ } else { /* range->predicate != NULL */ if (context->index_pso) scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->pso_tree, range, librdf_storage_trees_avl_free); else filter=1; } /* If filter is set, we're missing the required index. * Iterate over the entire model and filter the stream. * (With a fully indexed store, this will never happen) */ if (filter) { scontext->iterator=librdf_avltree_get_iterator_start(storage->world, context->graph->spo_tree, range, librdf_storage_trees_avl_free); } #ifdef RDF_STORAGE_TREES_WITH_CONTEXTS scontext->context_node=NULL; #endif if(!scontext->iterator) { LIBRDF_FREE(librdf_storage_trees_serialise_stream_context, scontext); return librdf_new_empty_stream(storage->world); } scontext->storage=storage; librdf_storage_add_reference(scontext->storage); stream=librdf_new_stream(storage->world, (void*)scontext, &librdf_storage_trees_serialise_end_of_stream, &librdf_storage_trees_serialise_next_statement, &librdf_storage_trees_serialise_get_statement, &librdf_storage_trees_serialise_finished); if(!stream) { librdf_storage_trees_serialise_finished((void*)scontext); return NULL; } if(filter) { if(librdf_stream_add_map(stream, &librdf_stream_statement_find_map, NULL, (void*)range)) { /* error - stream_add_map failed */ librdf_free_stream(stream); stream=NULL; } } return stream; }