/* -*- Mode: c; c-basic-offset: 2 -*- * * rdf_model.c - RDF Graph (Model) interface * * Copyright (C) 2000-2008, David Beckett http://www.dajobe.org/ * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/ * * This package is Free Software and part of Redland http://librdf.org/ * * It is licensed under the following three licenses as alternatives: * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version * 2. GNU General Public License (GPL) V2 or any newer version * 3. Apache License, V2.0 or any newer version * * You may not use this file except in compliance with at least one of * the above three licenses. * * See LICENSE.html or LICENSE.txt at the top of this package for the * complete terms and further detail along with the license texts for * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. * * */ #ifdef HAVE_CONFIG_H #include #endif #ifdef WIN32 #include #endif #include #include #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif #include #ifndef STANDALONE /** * librdf_init_model: * @world: redland world object * * INTERNAL - Initialise the model module. * **/ void librdf_init_model(librdf_world *world) { /* Always have model storage - must always be the default model */ librdf_init_model_storage(world); } /** * librdf_finish_model: * @world: redland world object * * INTERNAL - Terminate the model module. * **/ void librdf_finish_model(librdf_world *world) { if(world->models) { raptor_free_sequence(world->models); world->models=NULL; } } /* * librdf_model_supports_contexts - helper function to determine if this model supports contexts **/ static REDLAND_INLINE int librdf_model_supports_contexts(librdf_model* model) { return model->supports_contexts; } /* class methods */ static void librdf_free_model_factory(librdf_model_factory* factory) { if(factory->name) LIBRDF_FREE(librdf_model_factory, factory->name); if(factory->label) LIBRDF_FREE(librdf_model_factory, factory->label); LIBRDF_FREE(librdf_model_factory, factory); } /** * librdf_model_register_factory: * @world: redland world object * @name: the model factory name * @label: the storage factory label * @factory: pointer to function to call to register the factory * * Register a model factory. * **/ void librdf_model_register_factory(librdf_world *world, const char *name, const char *label, void (*factory) (librdf_model_factory*)) { librdf_model_factory *model; int i; librdf_world_open(world); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG2("Received registration for model %s\n", name); #endif if(!world->models) { world->models=raptor_new_sequence((raptor_sequence_free_handler *)librdf_free_model_factory, NULL); if(!world->models) goto oom; } for(i=0; (model=(librdf_model_factory*)raptor_sequence_get_at(world->models, i)); i++) { if(!strcmp(model->name, name)) { librdf_log(world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_MODEL, NULL, "model %s already registered", model->name); return; } } model=(librdf_model_factory*)LIBRDF_CALLOC(librdf_model_factory, 1, sizeof(librdf_model_factory)); if(!model) goto oom; model->name=(char*)LIBRDF_MALLOC(cstring, strlen(name)+1); if(!model->name) goto oom_tidy; strcpy(model->name, name); model->label=(char*)LIBRDF_MALLOC(cstring, strlen(label)+1); if(!model->label) goto oom_tidy; strcpy(model->label, label); if(raptor_sequence_push(world->models, model)) goto oom; /* Call the model registration function on the new object */ (*factory)(model); #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1 LIBRDF_DEBUG3("%s has context size %d\n", name, model->context_length); #endif return; oom_tidy: librdf_free_model_factory(model); oom: LIBRDF_FATAL1(world, LIBRDF_FROM_MODEL, "Out of memory"); } /** * librdf_get_model_factory: * @world: redland world object * @name: the factory name or NULL for the default factory * * Get a model factory by name. * * Return value: the factory object or NULL if there is no such factory **/ librdf_model_factory* librdf_get_model_factory(librdf_world* world, const char *name) { librdf_model_factory *factory; librdf_world_open(world); /* return 1st model if no particular one wanted - why? */ if(!name) { factory=(librdf_model_factory *)raptor_sequence_get_at(world->models, 0); if(!factory) { LIBRDF_DEBUG1("No (default) models registered\n"); return NULL; } } else { int i; for(i=0; (factory=(librdf_model_factory*)raptor_sequence_get_at(world->models, i)); i++) { if(!strcmp(factory->name, name)) break; } /* else FACTORY name not found */ if(!factory) { LIBRDF_DEBUG2("No model with name %s found\n", name); return NULL; } } return factory; } /** * librdf_model_enumerate: * @world: redland world object * @counter: index into the list of models * @name: pointer to store the name of the model (or NULL) * @label: pointer to store syntax readable label (or NULL) * * Get information on models. * * Return value: non 0 on failure of if counter is out of range **/ int librdf_model_enumerate(librdf_world* world, const unsigned int counter, const char **name, const char **label) { librdf_model_factory *factory; librdf_world_open(world); factory=(librdf_model_factory*)raptor_sequence_get_at(world->models, counter); if(!factory) return 1; if(name) *name=factory->name; if(label) *label=factory->label; return 0; } /** * librdf_new_model: * @world: redland world object * @storage: #librdf_storage to use * @options_string: options to initialise model * * Constructor - create a new storage #librdf_model object. * * The options are encoded as described in librdf_hash_from_string() * and can be NULL if none are required. * * Return value: a new #librdf_model object or NULL on failure */ librdf_model* librdf_new_model (librdf_world *world, librdf_storage *storage, const char *options_string) { librdf_hash* options_hash; librdf_model *model; librdf_world_open(world); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL); if(!storage) return NULL; options_hash=librdf_new_hash(world, NULL); if(!options_hash) return NULL; if(librdf_hash_from_string(options_hash, options_string)) { librdf_free_hash(options_hash); return NULL; } model=librdf_new_model_with_options(world, storage, options_hash); librdf_free_hash(options_hash); return model; } /** * librdf_new_model_with_options: * @world: redland world object * @storage: #librdf_storage storage to use * @options: #librdf_hash of options to use * * Constructor - Create a new #librdf_model with storage. * * Options are presently not used. * * Return value: a new #librdf_model object or NULL on failure **/ librdf_model* librdf_new_model_with_options(librdf_world *world, librdf_storage *storage, librdf_hash* options) { librdf_model *model; librdf_uri *uri; librdf_world_open(world); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL); if(!storage) return NULL; model=(librdf_model*)LIBRDF_CALLOC(librdf_model, 1, sizeof(librdf_model)); if(!model) return NULL; model->world=world; model->factory=librdf_get_model_factory(world, "storage"); if(!model->factory) { LIBRDF_FREE(librdf_model, model); return NULL; } model->context=LIBRDF_CALLOC(data, 1, model->factory->context_length); if(!model->context || model->factory->create(model, storage, options)) { if(model->context) LIBRDF_FREE(data, model->context); LIBRDF_FREE(librdf_model, model); return NULL; } uri=librdf_new_uri(world, (const unsigned char*)LIBRDF_MODEL_FEATURE_CONTEXTS); if(uri) { librdf_node *node=librdf_model_get_feature(model, uri); if(node) { model->supports_contexts=atoi((const char*)librdf_node_get_literal_value(node)); librdf_free_node(node); } librdf_free_uri(uri); } model->usage=1; return model; } /** * librdf_new_model_from_model: * @model: the existing #librdf_model * * Copy constructor - create a new librdf_model from an existing one. * * Creates a new model as a copy of the existing model in the same * storage context. * * Return value: a new #librdf_model or NULL on failure **/ librdf_model* librdf_new_model_from_model(librdf_model* model) { librdf_model *new_model; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); new_model=model->factory->clone(model); if(new_model) { new_model->supports_contexts=model->supports_contexts; new_model->usage=1; } return new_model; } /** * librdf_free_model: * @model: #librdf_model model to destroy * * Destructor - Destroy a #librdf_model object. * **/ void librdf_free_model(librdf_model *model) { librdf_iterator* iterator; librdf_model* m; LIBRDF_ASSERT_OBJECT_POINTER_RETURN(model, librdf_model); if(--model->usage) return; if(model->sub_models) { iterator=librdf_list_get_iterator(model->sub_models); if(iterator) { while(!librdf_iterator_end(iterator)) { m=(librdf_model*)librdf_iterator_get_object(iterator); if(m) librdf_free_model(m); librdf_iterator_next(iterator); } librdf_free_iterator(iterator); } librdf_free_list(model->sub_models); } else { model->factory->destroy(model); } LIBRDF_FREE(data, model->context); LIBRDF_FREE(librdf_model, model); } void librdf_model_add_reference(librdf_model *model) { model->usage++; } void librdf_model_remove_reference(librdf_model *model) { model->usage--; } /* methods */ /** * librdf_model_size: * @model: #librdf_model object * * Get the number of statements in the model. * * WARNING: Not all underlying stores can return the size of the graph * In which case the return value will be negative. * * Return value: the number of statements or <0 if not possible **/ int librdf_model_size(librdf_model* model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, -1); return model->factory->size(model); } /** * librdf_model_add_statement: * @model: model object * @statement: statement object * * Add a statement to the model. * * The passed-in statement is copied when added to the model, not * shared with the model. It must be a complete statement - all * of subject, predicate, object parts must be present. * * Only statements that are legal RDF can be added: URI or blank subject, * URI predicate and URI or blank or literal object (i.e. anything). * * If the statement already exists in the model, it is not added. * Duplicate statements can be added when used with Redland Contexts * such as with #librdf_model_context_add_statement * * Return value: non 0 on failure **/ int librdf_model_add_statement(librdf_model* model, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1); if(!librdf_statement_is_complete(statement)) return 1; return model->factory->add_statement(model, statement); } /** * librdf_model_add_statements: * @model: model object * @statement_stream: stream of statements to use * * Add a stream of statements to the model. * * If any of the statements are illegal RDF statements they will * be skipped and not added. See #librdf_model_add_statement for the detail. * * If any of the statements already exists in the store, they are not * added unless Redland contexts are being used. See also * #librdf_model_context_add_statements * * Return value: non 0 on failure **/ int librdf_model_add_statements(librdf_model* model, librdf_stream* statement_stream) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement_stream, librdf_statement, 1); return model->factory->add_statements(model, statement_stream); } /** * librdf_model_add: * @model: model object * @subject: #librdf_node of subject * @predicate: #librdf_node of predicate * @object: #librdf_node of object (literal or resource) * * Create and add a new statement about a resource to the model. * * After this method, the #librdf_node objects become owned by the model. * All of subject, predicate and object must be non-NULL. * * Return value: non 0 on failure **/ int librdf_model_add(librdf_model* model, librdf_node* subject, librdf_node* predicate, librdf_node* object) { librdf_statement *statement; int result; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(object, librdf_node, 1); if(!subject || (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject))) return 1; if(!predicate || !librdf_node_is_resource(predicate)) return 1; if(!object) return 1; statement=librdf_new_statement(model->world); if(!statement) return 1; librdf_statement_set_subject(statement, subject); librdf_statement_set_predicate(statement, predicate); librdf_statement_set_object(statement, object); result=librdf_model_add_statement(model, statement); librdf_free_statement(statement); return result; } /** * librdf_model_add_typed_literal_statement: * @model: model object * @subject: #librdf_node of subject * @predicate: #librdf_node of predicate * @literal: string literal content * @xml_language: language of literal * @datatype_uri: datatype #librdf_uri * * Create and add a new statement about a typed literal to the model. * * After this method, the #librdf_node subject and predicate become * owned by the model. * * The language can be set to NULL if not used. * All of subject, predicate and literal must be non-NULL. * * Return value: non 0 on failure **/ int librdf_model_add_typed_literal_statement(librdf_model* model, librdf_node* subject, librdf_node* predicate, const unsigned char* literal, const char *xml_language, librdf_uri *datatype_uri) { librdf_node* object; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(literal, string, 1); if(!subject || (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject))) return 1; if(!predicate || !librdf_node_is_resource(predicate)) return 1; if(!literal) return 1; object=librdf_new_node_from_typed_literal(model->world, literal, xml_language, datatype_uri); if(!object) return 1; return librdf_model_add(model, subject, predicate, object); } /** * librdf_model_add_string_literal_statement: * @model: model object * @subject: #librdf_node of subject * @predicate: #librdf_node of predicate * @literal: string literal conten * @xml_language: language of literal * @is_wf_xml: literal is XML * * Create and add a new statement about a literal to the model. * * The language can be set to NULL if not used. * All of subject, predicate and literal must be non-NULL. * * 0.9.12: xml_space argument deleted * * Return value: non 0 on failure **/ int librdf_model_add_string_literal_statement(librdf_model* model, librdf_node* subject, librdf_node* predicate, const unsigned char* literal, const char *xml_language, int is_wf_xml) { librdf_node* object; int result; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(literal, string, 1); if(!subject || (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject))) return 1; if(!predicate || !librdf_node_is_resource(predicate)) return 1; if(!literal) return 1; object=librdf_new_node_from_literal(model->world, literal, xml_language, is_wf_xml); if(!object) return 1; result=librdf_model_add(model, subject, predicate, object); if(result) librdf_free_node(object); return result; } /** * librdf_model_remove_statement: * @model: the model object * @statement: the statement * * Remove a known statement from the model. * * It must be a complete statement - all of subject, predicate, object * parts must be present and a legal RDF triple. * * Return value: non 0 on failure **/ int librdf_model_remove_statement(librdf_model* model, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1); if(!librdf_statement_is_complete(statement)) return 1; return model->factory->remove_statement(model, statement); } /** * librdf_model_contains_statement: * @model: the model object * @statement: the statement * * Check for a statement in the model. * * It must be a complete statement - all of subject, predicate, * object parts must be present and a legal RDF triple. Use * librdf_model_find_statements to search for partial statement * matches. * * WARNING: librdf_model_contains_statement may not work correctly * with stores using contexts. In this case, a search using * librdf_model_find_statements for a non-empty list will * return the correct result. * * Return value: non 0 if the model contains the statement (>0 if the statement is illegal) **/ int librdf_model_contains_statement(librdf_model* model, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 0); if(!librdf_statement_is_complete(statement)) return 1; return model->factory->contains_statement(model, statement); } /** * librdf_model_as_stream: * @model: the model object * * List the model contents as a stream of statements. * * Return value: a #librdf_stream or NULL on failure **/ librdf_stream* librdf_model_as_stream(librdf_model* model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); return model->factory->serialise(model); } /** * librdf_model_serialise: * @model: the model object * * Serialise the entire model as a stream (DEPRECATED). * * DEPRECATED to reduce confusion with the librdf_serializer class. * Please use librdf_model_as_stream. * * Return value: a #librdf_stream or NULL on failure **/ librdf_stream* librdf_model_serialise(librdf_model* model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); return model->factory->serialise(model); } /** * librdf_model_find_statements: * @model: the model object * @statement: the partial statement to match * * Find matching statements in the model. * * The partial statement is a statement where the subject, predicate * and/or object can take the value NULL which indicates a match with * any value in the model * * Return value: a #librdf_stream of statements (can be empty) or NULL * on failure. **/ librdf_stream* librdf_model_find_statements(librdf_model* model, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL); return model->factory->find_statements(model, statement); } /** * librdf_model_get_sources: * @model: #librdf_model object * @arc: #librdf_node arc * @target: #librdf_node target * * Return the sources (subjects) of arc in an RDF graph given arc (predicate) and target (object). * * Searches the model for arcs matching the given arc and target * and returns a list of the source #librdf_node objects as an iterator * * Return value: #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure **/ librdf_iterator* librdf_model_get_sources(librdf_model *model, librdf_node *arc, librdf_node *target) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL); return model->factory->get_sources(model, arc, target); } /** * librdf_model_get_arcs: * @model: #librdf_model object * @source: #librdf_node source * @target: #librdf_node target * * Return the arcs (predicates) of an arc in an RDF graph given source (subject) and target (object). * * Searches the model for arcs matching the given source and target * and returns a list of the arc #librdf_node objects as an iterator * * Return value: #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure **/ librdf_iterator* librdf_model_get_arcs(librdf_model *model, librdf_node *source, librdf_node *target) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL); return model->factory->get_arcs(model, source, target); } /** * librdf_model_get_targets: * @model: #librdf_model object * @source: #librdf_node source * @arc: #librdf_node arc * * Return the targets (objects) of an arc in an RDF graph given source (subject) and arc (predicate). * * Searches the model for targets matching the given source and arc * and returns a list of the source #librdf_node objects as an iterator * * Return value: #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure **/ librdf_iterator* librdf_model_get_targets(librdf_model *model, librdf_node *source, librdf_node *arc) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL); return model->factory->get_targets(model, source, arc); } /** * librdf_model_get_source: * @model: #librdf_model object * @arc: #librdf_node arc * @target: #librdf_node target * * Return one source (subject) of arc in an RDF graph given arc (predicate) and target (object). * * Searches the model for arcs matching the given arc and target * and returns one #librdf_node object * * Return value: a new #librdf_node object or NULL on failure **/ librdf_node* librdf_model_get_source(librdf_model *model, librdf_node *arc, librdf_node *target) { librdf_iterator *iterator; librdf_node *node; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL); iterator=librdf_model_get_sources(model, arc, target); if(!iterator) return NULL; node=(librdf_node*)librdf_iterator_get_object(iterator); if(node) node=librdf_new_node_from_node(node); librdf_free_iterator(iterator); return node; } /** * librdf_model_get_arc: * @model: #librdf_model object * @source: #librdf_node source * @target: #librdf_node target * * Return one arc (predicate) of an arc in an RDF graph given source (subject) and target (object). * * Searches the model for arcs matching the given source and target * and returns one #librdf_node object * * Return value: a new #librdf_node object or NULL on failure **/ librdf_node* librdf_model_get_arc(librdf_model *model, librdf_node *source, librdf_node *target) { librdf_iterator *iterator; librdf_node *node; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL); iterator=librdf_model_get_arcs(model, source, target); if(!iterator) return NULL; node=(librdf_node*)librdf_iterator_get_object(iterator); if(node) node=librdf_new_node_from_node(node); librdf_free_iterator(iterator); return node; } /** * librdf_model_get_target: * @model: #librdf_model object * @source: #librdf_node source * @arc: #librdf_node arc * * Return one target (object) of an arc in an RDF graph given source (subject) and arc (predicate). * * Searches the model for targets matching the given source and arc * and returns one #librdf_node object * * Return value: a new #librdf_node object or NULL on failure **/ librdf_node* librdf_model_get_target(librdf_model *model, librdf_node *source, librdf_node *arc) { librdf_iterator *iterator; librdf_node *node; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL); iterator=librdf_model_get_targets(model, source, arc); if(!iterator) return NULL; node=(librdf_node*)librdf_iterator_get_object(iterator); if(node) node=librdf_new_node_from_node(node); librdf_free_iterator(iterator); return node; } /** * librdf_model_add_submodel: * @model: the model object * @sub_model: the sub model to add * * Add a sub-model to the model. * * FIXME: Not tested * * Return value: non 0 on failure **/ int librdf_model_add_submodel(librdf_model* model, librdf_model* sub_model) { librdf_list *l=model->sub_models; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(sub_model, librdf_model, 1); if(!l) { l=librdf_new_list(model->world); if(!l) return 1; model->sub_models=l; } if(librdf_list_add(l, sub_model)) return 1; return 0; } /** * librdf_model_remove_submodel: * @model: the model object * @sub_model: the sub model to remove * * Remove a sub-model from the model. * * FIXME: Not tested * * Return value: non 0 on failure **/ int librdf_model_remove_submodel(librdf_model* model, librdf_model* sub_model) { librdf_list *l=model->sub_models; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(sub_model, librdf_model, 1); if(!l) return 1; if(!librdf_list_remove(l, sub_model)) return 1; return 0; } /** * librdf_model_get_arcs_in: * @model: #librdf_model object * @node: #librdf_node resource node * * Return the properties pointing to the given resource. * * Return value: #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure **/ librdf_iterator* librdf_model_get_arcs_in(librdf_model *model, librdf_node *node) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL); return model->factory->get_arcs_in(model, node); } /** * librdf_model_get_arcs_out: * @model: #librdf_model object * @node: #librdf_node resource node * * Return the properties pointing from the given resource. * * Return value: #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure **/ librdf_iterator* librdf_model_get_arcs_out(librdf_model *model, librdf_node *node) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL); return model->factory->get_arcs_out(model, node); } /** * librdf_model_has_arc_in: * @model: #librdf_model object * @node: #librdf_node resource node * @property: #librdf_node property node * * Check if a node has a given property pointing to it. * * Return value: non 0 if arc property does point to the resource node **/ int librdf_model_has_arc_in(librdf_model *model, librdf_node *node, librdf_node *property) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0); return model->factory->has_arc_in(model, node, property); } /** * librdf_model_has_arc_out: * @model: #librdf_model object * @node: #librdf_node resource node * @property: #librdf_node property node * * Check if a node has a given property pointing from it. * * Return value: non 0 if arc property does point from the resource node **/ int librdf_model_has_arc_out(librdf_model *model, librdf_node *node, librdf_node *property) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0); return model->factory->has_arc_out(model, node, property); } /** * librdf_model_print: * @model: the model object * @fh: the FILE stream to print to * * Print the model. * * This method is for debugging and the format of the output should * not be relied on. **/ void librdf_model_print(librdf_model *model, FILE *fh) { librdf_stream* stream; LIBRDF_ASSERT_OBJECT_POINTER_RETURN(model, librdf_model); LIBRDF_ASSERT_OBJECT_POINTER_RETURN(fh, FILE*); stream=librdf_model_as_stream(model); if(!stream) return; fputs("[[\n", fh); librdf_stream_print(stream, fh); fputs("]]\n", fh); librdf_free_stream(stream); } /** * librdf_model_context_add_statement: * @model: #librdf_model object * @context: #librdf_node context * @statement: #librdf_statement statement object * * Add a statement to a model with a context. * * It must be a complete statement - all * of subject, predicate, object parts must be present. * * If @context is NULL, this is equivalent to librdf_model_add_statement * * Return value: Non 0 on failure **/ int librdf_model_context_add_statement(librdf_model* model, librdf_node* context, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1); if(!librdf_statement_is_complete(statement)) return 1; if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return 1; } return model->factory->context_add_statement(model, context, statement); } /** * librdf_model_context_add_statements: * @model: #librdf_model object * @context: #librdf_node context * @stream: #librdf_stream stream object * * Add statements to a model with a context. * * If @context is NULL, this is equivalent to librdf_model_add_statements * * Return value: Non 0 on failure **/ int librdf_model_context_add_statements(librdf_model* model, librdf_node* context, librdf_stream* stream) { int status=0; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1); if(!stream) return 1; if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return 1; } if(model->factory->context_add_statements) return model->factory->context_add_statements(model, context, stream); while(!librdf_stream_end(stream)) { librdf_statement* statement=librdf_stream_get_object(stream); if(!statement) break; status=librdf_model_context_add_statement(model, context, statement); if(status) break; librdf_stream_next(stream); } return status; } /** * librdf_model_context_remove_statement: * @model: #librdf_model object * @context: #librdf_node context * @statement: #librdf_statement statement * * Remove a statement from a model in a context. * * It must be a complete statement - all of subject, predicate, object * parts must be present. * * If @context is NULL, this is equivalent to librdf_model_remove_statement * * Return value: Non 0 on failure **/ int librdf_model_context_remove_statement(librdf_model* model, librdf_node* context, librdf_statement* statement) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1); if(!librdf_statement_is_complete(statement)) return 1; if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return 1; } return model->factory->context_remove_statement(model, context, statement); } /** * librdf_model_context_remove_statements: * @model: #librdf_model object * @context: #librdf_node context * * Remove statements from a model with the given context. * * Return value: Non 0 on failure **/ int librdf_model_context_remove_statements(librdf_model* model, librdf_node* context) { librdf_stream *stream; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, 1); if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return 1; } if(model->factory->context_remove_statements) return model->factory->context_remove_statements(model, context); stream=librdf_model_context_as_stream(model, context); if(!stream) return 1; while(!librdf_stream_end(stream)) { librdf_statement *statement=librdf_stream_get_object(stream); if(!statement) break; librdf_model_context_remove_statement(model, context, statement); librdf_stream_next(stream); } librdf_free_stream(stream); return 0; } /** * librdf_model_context_as_stream: * @model: #librdf_model object * @context: #librdf_node context * * List all statements in a model context. * * Return value: #librdf_stream of statements or NULL on failure **/ librdf_stream* librdf_model_context_as_stream(librdf_model* model, librdf_node* context) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, NULL); if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return NULL; } return model->factory->context_serialize(model, context); } /** * librdf_model_context_serialize: * @model: #librdf_model object * @context: #librdf_node context * * List all statements in a model context. * * DEPRECATED to reduce confusion with the librdf_serializer class. * Please use librdf_model_context_as_stream. * * Return value: #librdf_stream of statements or NULL on failure **/ librdf_stream* librdf_model_context_serialize(librdf_model* model, librdf_node* context) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, NULL); if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return NULL; } return model->factory->context_serialize(model, context); } /** * librdf_model_query_execute: * @model: #librdf_model object * @query: #librdf_query object * * Execute a query against the model. * * Run the given query against the model and return a #librdf_stream of * matching #librdf_statement objects * * Return value: #librdf_query_results or NULL on failure **/ librdf_query_results* librdf_model_query_execute(librdf_model* model, librdf_query* query) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, librdf_query, NULL); return model->factory->query_execute(model, query); } /** * librdf_model_sync: * @model: #librdf_model object * * Synchronise the model to the model implementation. * * Return value: non-0 on failure **/ int librdf_model_sync(librdf_model* model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1); if(model->factory->sync) return model->factory->sync(model); return 0; } /** * librdf_model_get_storage: * @model: #librdf_model object * * Return the storage of this model. * * Note: this can only return one storage, so model implementations * that have multiple #librdf_storage internally may chose not to * implement this. * * Return value: #librdf_storage or NULL if this has no store **/ librdf_storage* librdf_model_get_storage(librdf_model *model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); if(model->factory->get_storage) return model->factory->get_storage(model); else return NULL; } /** * librdf_model_find_statements_in_context: * @model: #librdf_model object * @statement: #librdf_statement partial statement to find * @context_node: context #librdf_node (or NULL) * * Search the model for matching statements in a given context. * * Searches the model for a (partial) statement as described in * librdf_statement_match() in the given context and returns a * #librdf_stream of matching #librdf_statement objects. If * context is NULL, this is equivalent to librdf_model_find_statements. * * Return value: #librdf_stream of matching statements (may be empty) or NULL on failure **/ librdf_stream* librdf_model_find_statements_in_context(librdf_model* model, librdf_statement* statement, librdf_node* context_node) { librdf_stream *stream; LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL); if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return NULL; } if(model->factory->find_statements_in_context) return model->factory->find_statements_in_context(model, statement, context_node); statement=librdf_new_statement_from_statement(statement); if(!statement) return NULL; stream=librdf_model_context_as_stream(model, context_node); if(!stream) { librdf_free_statement(statement); return librdf_new_empty_stream(model->world); } librdf_stream_add_map(stream, &librdf_stream_statement_find_map, (librdf_stream_map_free_context_handler)&librdf_free_statement, (void*)statement); return stream; } /** * librdf_model_get_contexts: * @model: #librdf_model object * * Return the list of contexts in the graph. * * Returns an iterator of #librdf_node context nodes for each * context in the graph. * * Return value: #librdf_iterator of context nodes or NULL on failure or if contexts are not supported **/ librdf_iterator* librdf_model_get_contexts(librdf_model* model) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); if(!librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return NULL; } if(model->factory->get_contexts) return model->factory->get_contexts(model); else return NULL; } /** * librdf_model_get_feature: * @model: #librdf_model object * @feature: #librdf_uri feature property * * Get the value of a graph feature . * * Return value: new #librdf_node feature value or NULL if no such feature * exists or the value is empty. **/ librdf_node* librdf_model_get_feature(librdf_model* model, librdf_uri* feature) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, NULL); if(model->factory->get_feature) return model->factory->get_feature(model, feature); return NULL; } /** * librdf_model_set_feature: * @model: #librdf_model object * @feature: #librdf_uri feature property * @value: #librdf_node feature property value * * Set the value of a graph feature. * * Return value: non 0 on failure (negative if no such feature) **/ int librdf_model_set_feature(librdf_model* model, librdf_uri* feature, librdf_node* value) { LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, -1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, -1); LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, librdf_node, -1); if(model->factory->set_feature) return model->factory->set_feature(model, feature, value); return -1; } /** * librdf_model_find_statements_with_options: * @model: #librdf_model object * @statement: #librdf_statement partial statement to find * @context_node: #librdf_node context node or NULL. * @options: #librdf_hash of matching options or NULL * * Search the model for matching statements with match options. * * Searches the model for a (partial) statement as described in * librdf_statement_match() and returns a #librdf_stream of * matching #librdf_statement objects. * * If options is given then the match is made according to * the given options. If options is NULL, this is equivalent * to librdf_model_find_statements_in_context. * * Return value: #librdf_stream of matching statements (may be empty) or NULL on failure **/ librdf_stream* librdf_model_find_statements_with_options(librdf_model* model, librdf_statement* statement, librdf_node* context_node, librdf_hash* options) { if(context_node && !librdf_model_supports_contexts(model)) { librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL, "Model does not support contexts"); return NULL; } if(model->factory->find_statements_with_options) return model->factory->find_statements_with_options(model, statement, context_node, options); else return librdf_model_find_statements_in_context(model, statement, context_node); } /** * librdf_model_load: * @model: #librdf_model object * @uri: the URI to read the content * @name: the name of the parser (or NULL) * @mime_type: the MIME type of the syntax (NULL if not used) * @type_uri: URI identifying the syntax (NULL if not used) * * Load content from a URI into the model. * * If the name field is NULL, the library will try to guess * the parser to use from the uri, mime_type and type_uri fields. * This is done via the raptor_guess_parser_name function. * * Return value: non 0 on failure **/ int librdf_model_load(librdf_model* model, librdf_uri *uri, const char *name, const char *mime_type, librdf_uri *type_uri) { int rc=0; librdf_parser* parser; if(name && !*name) name=NULL; if(mime_type && !*mime_type) mime_type=NULL; if(!name) name=raptor_guess_parser_name((raptor_uri*)type_uri, mime_type, NULL, 0, librdf_uri_as_string(uri)); parser=librdf_new_parser(model->world, name, NULL, NULL); if(!parser) return 1; rc=librdf_parser_parse_into_model(parser, uri, NULL, model); librdf_free_parser(parser); return rc; } /** * librdf_model_to_counted_string: * @model: #librdf_model object * @uri: base URI to use in serializing (or NULL if not used) * @name: the name of the serializer (or NULL for default) * @mime_type: the MIME type of the syntax (NULL if not used) * @type_uri: URI identifying the syntax (NULL if not used) * @string_length_p: pointer to location to store string length (or NULL) * * Write serialized model to a string. * * If the name field is NULL, the default serializer will be used. * * Note: the returned string must be freed by the caller. * * Return value: new string or NULL on failure **/ unsigned char* librdf_model_to_counted_string(librdf_model* model, librdf_uri *uri, const char *name, const char *mime_type, librdf_uri *type_uri, size_t* string_length_p) { unsigned char *string=NULL; librdf_serializer* serializer; if(name && !*name) name=NULL; if(mime_type && !*mime_type) mime_type=NULL; serializer=librdf_new_serializer(model->world, name, mime_type, type_uri); if(!serializer) return NULL; string=librdf_serializer_serialize_model_to_counted_string(serializer, uri, model, string_length_p); librdf_free_serializer(serializer); return string; } /** * librdf_model_to_string: * @model: #librdf_model object * @uri: base URI to use in serializing (or NULL if not used) * @name: the name of the serializer (or NULL for default) * @mime_type: the MIME type of the syntax (NULL if not used) * @type_uri: URI identifying the syntax (NULL if not used) * * Write serialized model to a string. * * If the name field is NULL, the default serializer will be used. * * Note: the returned string must be freed by the caller. * * Return value: new string or NULL on failure **/ unsigned char* librdf_model_to_string(librdf_model* model, librdf_uri *uri, const char *name, const char *mime_type, librdf_uri *type_uri) { return librdf_model_to_counted_string(model, uri, name, mime_type, type_uri, NULL); } /** * librdf_model_contains_context: * @model: the model object * @context: the contest * * Check for a context in the model. * * Return value: non 0 if the model contains the context node **/ int librdf_model_contains_context(librdf_model* model, librdf_node* context) { librdf_stream* stream; int result; stream=librdf_model_context_as_stream(model, context); if(!stream) return 0; result=!librdf_stream_end(stream); librdf_free_stream(stream); return result; } /** * librdf_model_transaction_start: * @model: the model object * * Start a transaction * * Return value: non-0 on failure **/ int librdf_model_transaction_start(librdf_model* model) { if(model->factory->transaction_start) return model->factory->transaction_start(model); else return 1; } /** * librdf_model_transaction_start_with_handle: * @model: the model object * @handle: the transaction object * * Start a transaction using an existing external transaction object. * * Return value: non-0 on failure **/ int librdf_model_transaction_start_with_handle(librdf_model* model, void* handle) { if(model->factory->transaction_start_with_handle) return model->factory->transaction_start_with_handle(model, handle); else return 1; } /** * librdf_model_transaction_commit: * @model: the model object * * Commit a transaction. * * Return value: non-0 on failure **/ int librdf_model_transaction_commit(librdf_model* model) { if(model->factory->transaction_commit) return model->factory->transaction_commit(model); else return 1; } /** * librdf_model_transaction_rollback: * @model: the model object * * Rollback a transaction. * * Return value: non-0 on failure **/ int librdf_model_transaction_rollback(librdf_model* model) { if(model->factory->transaction_rollback) return model->factory->transaction_rollback(model); else return 1; } /** * librdf_model_transaction_get_handle: * @model: the model object * * Get the current transaction handle. * * Return value: non-0 on failure **/ void* librdf_model_transaction_get_handle(librdf_model* model) { if(model->factory->transaction_get_handle) return model->factory->transaction_get_handle(model); else return NULL; } #endif /* TEST CODE */ #ifdef STANDALONE /* one more prototype */ int main(int argc, char *argv[]); #define EX1_CONTENT \ "\n" \ "\n" \ " \n" \ " Dave Beckett's Home Page\n" \ " Dave Beckett\n" \ " The generic home page of Dave Beckett.\n" \ " \n" \ "" #define EX2_CONTENT \ "\n" \ "\n" \ " \n" \ " Dave Beckett's Home Page\n" \ " Dave Beckett\n" \ " I do development-based research on RDF, metadata and web searching.\n" \ " Copyright © 2002 Dave Beckett\n" \ " \n" \ "" int test_model_cloning(char const *program, librdf_world *); int main(int argc, char *argv[]) { librdf_storage* storage; librdf_model* model; librdf_statement *statement; librdf_parser* parser; librdf_stream* stream; const char *parser_name="rdfxml"; #define URI_STRING_COUNT 2 const unsigned char *file_uri_strings[URI_STRING_COUNT]={(const unsigned char*)"http://example.org/test1.rdf", (const unsigned char*)"http://example.org/test2.rdf"}; const unsigned char *file_content[URI_STRING_COUNT]={(const unsigned char*)EX1_CONTENT, (const unsigned char*)EX2_CONTENT}; librdf_uri* uris[URI_STRING_COUNT]; librdf_node* nodes[URI_STRING_COUNT]; int i; const char *program=librdf_basename((const char*)argv[0]); /* initialise dependent modules - all of them! */ librdf_world *world=librdf_new_world(); librdf_iterator *iterator, *second_iterator; librdf_node *n1, *n2; int count; int expected_count; #define EXPECTED_BAD_STRING_LENGTH 317 librdf_uri* base_uri; unsigned char *string; size_t string_length=0; int remove_count=0; int status=0; const char* storage_type; const char* storage_name; const char* storage_options; librdf_world_open(world); /* Test model cloning first */ if(test_model_cloning(program, world)) return(1); /* Get storage configuration */ storage_type=getenv("REDLAND_TEST_STORAGE_TYPE"); storage_name=getenv("REDLAND_TEST_STORAGE_NAME"); storage_options=getenv("REDLAND_TEST_STORAGE_OPTIONS"); if(!(storage_type && storage_name && storage_options)) { /* default is to test in memory */ storage_type="memory"; storage_name=NULL; storage_options="write='yes',new='yes',contexts='yes'"; } fprintf(stderr, "%s: Creating new %s storage\n", program, storage_type); storage=librdf_new_storage(world, storage_type, storage_name, storage_options); if(!storage) { fprintf(stderr, "%s: Failed to create new %s storage name %s with options %s\n", program, storage_type, storage_name, storage_options); return(1); } fprintf(stderr, "%s: Creating model\n", program); model=librdf_new_model(world, storage, NULL); if(!model) { fprintf(stderr, "%s: Failed to create new model\n", program); return(1); } statement=librdf_new_statement(world); /* after this, nodes become owned by model */ librdf_statement_set_subject(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://www.dajobe.org/")); librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator")); if(!librdf_model_add_statement(model, statement)) { fprintf(stderr, "%s: librdf_model_add_statement unexpectedly succeeded adding a partial statement\n", program); return(1); } librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Dave Beckett", NULL, 0)); librdf_model_add_statement(model, statement); librdf_free_statement(statement); /* make it illegal */ statement=librdf_new_statement(world); librdf_statement_set_subject(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Bad Subject", NULL, 0)); librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/pred")); librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Good Object", NULL, 0)); if(!librdf_model_add_statement(model, statement)) { fprintf(stderr, "%s: librdf_model_add_statement unexpectedly succeeded adding an illegal triple\n", program); return(1); } librdf_free_statement(statement); fprintf(stderr, "%s: Printing model\n", program); librdf_model_print(model, stderr); parser=librdf_new_parser(world, parser_name, NULL, NULL); if(!parser) { fprintf(stderr, "%s: Failed to create new parser type %s\n", program, parser_name); exit(1); } for (i=0; i