1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rdf_model.c - RDF Graph (Model) interface
4  *
5  * Copyright (C) 2000-2008, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/
7  *
8  * This package is Free Software and part of Redland http://librdf.org/
9  *
10  * It is licensed under the following three licenses as alternatives:
11  *   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12  *   2. GNU General Public License (GPL) V2 or any newer version
13  *   3. Apache License, V2.0 or any newer version
14  *
15  * You may not use this file except in compliance with at least one of
16  * the above three licenses.
17  *
18  * See LICENSE.html or LICENSE.txt at the top of this package for the
19  * complete terms and further detail along with the license texts for
20  * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21  *
22  *
23  */
24 
25 
26 #ifdef HAVE_CONFIG_H
27 #include <rdf_config.h>
28 #endif
29 
30 #ifdef WIN32
31 #include <win32_rdf_config.h>
32 #endif
33 
34 #include <stdio.h>
35 #include <string.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h> /* for exit()  */
38 #endif
39 
40 #include <redland.h>
41 
42 #ifndef STANDALONE
43 
44 /**
45  * librdf_init_model:
46  * @world: redland world object
47  *
48  * INTERNAL - Initialise the model module.
49  *
50  **/
51 void
librdf_init_model(librdf_world * world)52 librdf_init_model(librdf_world *world)
53 {
54   /* Always have model storage - must always be the default model */
55   librdf_init_model_storage(world);
56 }
57 
58 
59 /**
60  * librdf_finish_model:
61  * @world: redland world object
62  *
63  * INTERNAL - Terminate the model module.
64  *
65  **/
66 void
librdf_finish_model(librdf_world * world)67 librdf_finish_model(librdf_world *world)
68 {
69   if(world->models) {
70     raptor_free_sequence(world->models);
71     world->models=NULL;
72   }
73 }
74 
75 
76 /**
77  * librdf_model_supports_contexts:
78  * @model: the model object
79  *
80  * Check if this model supports contexts
81  *
82  * Return value: non-0 if contexts are supported
83  **/
84 int
librdf_model_supports_contexts(librdf_model * model)85 librdf_model_supports_contexts(librdf_model* model)
86 {
87   return model->supports_contexts;
88 }
89 
90 
91 
92 /* class methods */
93 
94 static void
librdf_free_model_factory(librdf_model_factory * factory)95 librdf_free_model_factory(librdf_model_factory* factory)
96 {
97   if(factory->name)
98     LIBRDF_FREE(librdf_model_factory, factory->name);
99   if(factory->label)
100     LIBRDF_FREE(librdf_model_factory, factory->label);
101   LIBRDF_FREE(librdf_model_factory, factory);
102 }
103 
104 
105 /**
106  * librdf_model_register_factory:
107  * @world: redland world object
108  * @name: the model factory name
109  * @label: the storage factory label
110  * @factory: pointer to function to call to register the factory
111  *
112  * Register a model factory.
113  *
114  **/
115 REDLAND_EXTERN_C
116 void
librdf_model_register_factory(librdf_world * world,const char * name,const char * label,void (* factory)(librdf_model_factory *))117 librdf_model_register_factory(librdf_world *world,
118                               const char *name, const char *label,
119                               void (*factory) (librdf_model_factory*))
120 {
121   librdf_model_factory *model;
122   int i;
123 
124   librdf_world_open(world);
125 
126 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
127   LIBRDF_DEBUG2("Received registration for model %s\n", name);
128 #endif
129 
130   if(!world->models) {
131     world->models = raptor_new_sequence((raptor_data_free_handler)librdf_free_model_factory, NULL);
132 
133     if(!world->models)
134       goto oom;
135   }
136 
137   for(i=0;
138       (model=(librdf_model_factory*)raptor_sequence_get_at(world->models, i));
139       i++) {
140     if(!strcmp(model->name, name)) {
141       librdf_log(world,
142                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_MODEL, NULL,
143                  "model %s already registered", model->name);
144       return;
145     }
146   }
147 
148   model = LIBRDF_CALLOC(librdf_model_factory*, 1, sizeof(*model));
149   if(!model)
150     goto oom;
151 
152   model->name = LIBRDF_MALLOC(char*, strlen(name) + 1);
153   if(!model->name)
154     goto oom_tidy;
155   strcpy(model->name, name);
156 
157   model->label = LIBRDF_MALLOC(char*, strlen(label) + 1);
158   if(!model->label)
159     goto oom_tidy;
160   strcpy(model->label, label);
161 
162   if(raptor_sequence_push(world->models, model))
163     goto oom;
164 
165   /* Call the model registration function on the new object */
166   (*factory)(model);
167 
168 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
169   LIBRDF_DEBUG3("%s has context size %d\n", name, model->context_length);
170 #endif
171 
172   return;
173 
174   oom_tidy:
175   librdf_free_model_factory(model);
176   oom:
177   LIBRDF_FATAL1(world, LIBRDF_FROM_MODEL, "Out of memory");
178 }
179 
180 
181 /**
182  * librdf_get_model_factory:
183  * @world: redland world object
184  * @name: the factory name or NULL for the default factory
185  *
186  * Get a model factory by name.
187  *
188  * Return value: the factory object or NULL if there is no such factory
189  **/
190 librdf_model_factory*
librdf_get_model_factory(librdf_world * world,const char * name)191 librdf_get_model_factory(librdf_world* world, const char *name)
192 {
193   librdf_model_factory *factory;
194 
195   librdf_world_open(world);
196 
197   /* return 1st model if no particular one wanted - why? */
198   if(!name) {
199     factory=(librdf_model_factory *)raptor_sequence_get_at(world->models, 0);
200     if(!factory) {
201       LIBRDF_DEBUG1("No (default) models registered\n");
202       return NULL;
203     }
204   } else {
205     int i;
206 
207     for(i=0;
208         (factory=(librdf_model_factory*)raptor_sequence_get_at(world->models, i));
209         i++) {
210       if(!strcmp(factory->name, name))
211         break;
212     }
213     /* else FACTORY name not found */
214     if(!factory) {
215       LIBRDF_DEBUG2("No model with name %s found\n", name);
216       return NULL;
217     }
218   }
219 
220   return factory;
221 }
222 
223 
224 /**
225  * librdf_model_enumerate:
226  * @world: redland world object
227  * @counter: index into the list of models
228  * @name: pointer to store the name of the model (or NULL)
229  * @label: pointer to store syntax readable label (or NULL)
230  *
231  * Get information on models.
232  *
233  * Return value: non 0 on failure of if counter is out of range
234  **/
235 int
librdf_model_enumerate(librdf_world * world,const unsigned int counter,const char ** name,const char ** label)236 librdf_model_enumerate(librdf_world* world,
237                        const unsigned int counter,
238                        const char **name, const char **label)
239 {
240   librdf_model_factory *factory;
241   int ioffset = LIBRDF_GOOD_CAST(int, counter);
242 
243   librdf_world_open(world);
244 
245   factory = (librdf_model_factory*)raptor_sequence_get_at(world->models,
246                                                           ioffset);
247   if(!factory)
248     return 1;
249 
250   if(name)
251     *name = factory->name;
252 
253   if(label)
254     *label = factory->label;
255 
256   return 0;
257 }
258 
259 
260 /**
261  * librdf_new_model:
262  * @world: redland world object
263  * @storage: #librdf_storage to use
264  * @options_string: options to initialise model
265  *
266  * Constructor - create a new storage #librdf_model object.
267  *
268  * The options are encoded as described in librdf_hash_from_string()
269  * and can be NULL if none are required.
270  *
271  * Return value: a new #librdf_model object or NULL on failure
272  */
273 librdf_model*
librdf_new_model(librdf_world * world,librdf_storage * storage,const char * options_string)274 librdf_new_model (librdf_world *world,
275                   librdf_storage *storage, const char *options_string) {
276   librdf_hash* options_hash;
277   librdf_model *model;
278 
279   librdf_world_open(world);
280 
281   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
282 
283   if(!storage)
284     return NULL;
285 
286   options_hash=librdf_new_hash(world, NULL);
287   if(!options_hash)
288     return NULL;
289 
290   if(librdf_hash_from_string(options_hash, options_string)) {
291     librdf_free_hash(options_hash);
292     return NULL;
293   }
294 
295   model=librdf_new_model_with_options(world, storage, options_hash);
296   librdf_free_hash(options_hash);
297   return model;
298 }
299 
300 
301 /**
302  * librdf_new_model_with_options:
303  * @world: redland world object
304  * @storage: #librdf_storage storage to use
305  * @options: #librdf_hash of options to use
306  *
307  * Constructor - Create a new #librdf_model with storage.
308  *
309  * Options are presently not used.
310  *
311  * Return value: a new #librdf_model object or NULL on failure
312  **/
313 librdf_model*
librdf_new_model_with_options(librdf_world * world,librdf_storage * storage,librdf_hash * options)314 librdf_new_model_with_options(librdf_world *world,
315                               librdf_storage *storage, librdf_hash* options)
316 {
317   librdf_model *model;
318   librdf_uri *uri;
319 
320   librdf_world_open(world);
321 
322   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
323 
324   if(!storage)
325     return NULL;
326 
327   model = LIBRDF_CALLOC(librdf_model*, 1, sizeof(*model));
328   if(!model)
329     return NULL;
330 
331   model->world=world;
332 
333   model->factory=librdf_get_model_factory(world, "storage");
334   if(!model->factory) {
335     LIBRDF_FREE(librdf_model, model);
336     return NULL;
337   }
338 
339   model->context = LIBRDF_CALLOC(void*, 1, model->factory->context_length);
340 
341   if(!model->context || model->factory->create(model, storage, options)) {
342     if(model->context)
343       LIBRDF_FREE(data, model->context);
344     LIBRDF_FREE(librdf_model, model);
345     return NULL;
346   }
347 
348   uri=librdf_new_uri(world, (const unsigned char*)LIBRDF_MODEL_FEATURE_CONTEXTS);
349   if(uri) {
350     librdf_node *node=librdf_model_get_feature(model, uri);
351     if(node) {
352       model->supports_contexts=atoi((const char*)librdf_node_get_literal_value(node));
353       librdf_free_node(node);
354     }
355     librdf_free_uri(uri);
356   }
357 
358   model->usage=1;
359 
360   return model;
361 }
362 
363 
364 /**
365  * librdf_new_model_from_model:
366  * @model: the existing #librdf_model
367  *
368  * Copy constructor - create a new librdf_model from an existing one.
369  *
370  * Creates a new model as a copy of the existing model in the same
371  * storage context.
372  *
373  * Return value: a new #librdf_model or NULL on failure
374  **/
375 librdf_model*
librdf_new_model_from_model(librdf_model * model)376 librdf_new_model_from_model(librdf_model* model)
377 {
378   librdf_model *new_model;
379 
380   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
381 
382   new_model=model->factory->clone(model);
383   if(new_model) {
384     new_model->supports_contexts=model->supports_contexts;
385     new_model->usage=1;
386   }
387   return new_model;
388 }
389 
390 
391 /**
392  * librdf_free_model:
393  * @model: #librdf_model model to destroy
394  *
395  * Destructor - Destroy a #librdf_model object.
396  *
397  **/
398 void
librdf_free_model(librdf_model * model)399 librdf_free_model(librdf_model *model)
400 {
401   librdf_iterator* iterator;
402   librdf_model* m;
403 
404   if(!model)
405     return;
406 
407   LIBRDF_ASSERT_OBJECT_POINTER_RETURN(model, librdf_model);
408 
409   if(--model->usage)
410     return;
411 
412   if(model->sub_models) {
413     iterator=librdf_list_get_iterator(model->sub_models);
414     if(iterator) {
415       while(!librdf_iterator_end(iterator)) {
416         m=(librdf_model*)librdf_iterator_get_object(iterator);
417         if(m)
418           librdf_free_model(m);
419         librdf_iterator_next(iterator);
420       }
421       librdf_free_iterator(iterator);
422     }
423     librdf_free_list(model->sub_models);
424   } else {
425     model->factory->destroy(model);
426   }
427   LIBRDF_FREE(data, model->context);
428 
429   LIBRDF_FREE(librdf_model, model);
430 }
431 
432 
433 void
librdf_model_add_reference(librdf_model * model)434 librdf_model_add_reference(librdf_model *model)
435 {
436   model->usage++;
437 }
438 
439 void
librdf_model_remove_reference(librdf_model * model)440 librdf_model_remove_reference(librdf_model *model)
441 {
442   model->usage--;
443 }
444 
445 
446 /* methods */
447 
448 /**
449  * librdf_model_size:
450  * @model: #librdf_model object
451  *
452  * Get the number of statements in the model.
453  *
454  * WARNING: Not all underlying stores can return the size of the graph
455  * In which case the return value will be negative.
456  *
457  * Return value: the number of statements or <0 if not possible
458  **/
459 int
librdf_model_size(librdf_model * model)460 librdf_model_size(librdf_model* model)
461 {
462   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, -1);
463 
464   return model->factory->size(model);
465 }
466 
467 
468 /**
469  * librdf_model_add_statement:
470  * @model: model object
471  * @statement: statement object
472  *
473  * Add a statement to the model.
474  *
475  * The passed-in statement is copied when added to the model, not
476  * shared with the model.  It must be a complete statement - all
477  * of subject, predicate, object parts must be present.
478  *
479  * Only statements that are legal RDF can be added: URI or blank subject,
480  * URI predicate and URI or blank or literal object (i.e. anything).
481  *
482  * If the statement already exists in the model, it is not added.
483  * Duplicate statements can be added when used with Redland Contexts
484  * such as with #librdf_model_context_add_statement
485  *
486  * Return value: non 0 on failure
487  **/
488 int
librdf_model_add_statement(librdf_model * model,librdf_statement * statement)489 librdf_model_add_statement(librdf_model* model, librdf_statement* statement)
490 {
491   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
492   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
493 
494   if(!librdf_statement_is_complete(statement))
495     return 1;
496 
497   return model->factory->add_statement(model, statement);
498 }
499 
500 
501 /**
502  * librdf_model_add_statements:
503  * @model: model object
504  * @statement_stream: stream of statements to use
505  *
506  * Add a stream of statements to the model.
507  *
508  * If any of the statements are illegal RDF statements they will
509  * be skipped and not added.  See #librdf_model_add_statement for the detail.
510  *
511  * If any of the statements already exists in the store, they are not
512  * added unless Redland contexts are being used.  See also
513  * #librdf_model_context_add_statements
514  *
515  * Return value: non 0 on failure
516  **/
517 int
librdf_model_add_statements(librdf_model * model,librdf_stream * statement_stream)518 librdf_model_add_statements(librdf_model* model, librdf_stream* statement_stream)
519 {
520   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
521   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement_stream, librdf_statement, 1);
522 
523   return model->factory->add_statements(model, statement_stream);
524 }
525 
526 
527 /**
528  * librdf_model_add:
529  * @model: model object
530  * @subject: #librdf_node of subject
531  * @predicate: #librdf_node of predicate
532  * @object: #librdf_node of object (literal or resource)
533  *
534  * Create and add a new statement about a resource to the model.
535  *
536  * After this method, the #librdf_node objects become owned by the model.
537  * All of subject, predicate and object must be non-NULL.
538  *
539  * Return value: non 0 on failure
540  **/
541 int
librdf_model_add(librdf_model * model,librdf_node * subject,librdf_node * predicate,librdf_node * object)542 librdf_model_add(librdf_model* model, librdf_node* subject,
543 		 librdf_node* predicate, librdf_node* object)
544 {
545   librdf_statement *statement;
546   int result;
547 
548   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
549   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1);
550   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1);
551   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(object, librdf_node, 1);
552 
553   if(!subject ||
554      (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject)))
555     return 1;
556 
557   if(!predicate || !librdf_node_is_resource(predicate))
558      return 1;
559 
560   if(!object)
561     return 1;
562 
563   statement=librdf_new_statement(model->world);
564   if(!statement)
565     return 1;
566 
567   librdf_statement_set_subject(statement, subject);
568   librdf_statement_set_predicate(statement, predicate);
569   librdf_statement_set_object(statement, object);
570 
571   result=librdf_model_add_statement(model, statement);
572   librdf_free_statement(statement);
573 
574   return result;
575 }
576 
577 
578 /**
579  * librdf_model_add_typed_literal_statement:
580  * @model: model object
581  * @subject: #librdf_node of subject
582  * @predicate: #librdf_node of predicate
583  * @literal: string literal content
584  * @xml_language: language of literal
585  * @datatype_uri: datatype #librdf_uri
586  *
587  * Create and add a new statement about a typed literal to the model.
588  *
589  * After this method, the #librdf_node subject and predicate become
590  * owned by the model.
591  *
592  * The language can be set to NULL if not used.
593  * All of subject, predicate and literal must be non-NULL.
594  *
595  * Return value: non 0 on failure
596  **/
597 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)598 librdf_model_add_typed_literal_statement(librdf_model* model,
599                                          librdf_node* subject,
600                                          librdf_node* predicate,
601                                          const unsigned char* literal,
602                                          const char *xml_language,
603                                          librdf_uri *datatype_uri)
604 {
605   librdf_node* object;
606 
607   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
608   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1);
609   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1);
610   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(literal, string, 1);
611 
612   if(!subject ||
613      (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject)))
614     return 1;
615 
616   if(!predicate || !librdf_node_is_resource(predicate))
617      return 1;
618 
619   if(!literal)
620     return 1;
621 
622   object=librdf_new_node_from_typed_literal(model->world,
623                                             literal, xml_language,
624                                             datatype_uri);
625   if(!object)
626     return 1;
627 
628   return librdf_model_add(model, subject, predicate, object);
629 }
630 
631 
632 /**
633  * librdf_model_add_string_literal_statement:
634  * @model: model object
635  * @subject: #librdf_node of subject
636  * @predicate: #librdf_node of predicate
637  * @literal: string literal conten
638  * @xml_language: language of literal
639  * @is_wf_xml: literal is XML
640  *
641  * Create and add a new statement about a literal to the model.
642  *
643  * The language can be set to NULL if not used.
644  * All of subject, predicate and literal must be non-NULL.
645  *
646  * 0.9.12: xml_space argument deleted
647  *
648  * Return value: non 0 on failure
649  **/
650 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)651 librdf_model_add_string_literal_statement(librdf_model* model,
652                                           librdf_node* subject,
653                                           librdf_node* predicate,
654                                           const unsigned char* literal,
655                                           const char *xml_language,
656                                           int is_wf_xml)
657 {
658   librdf_node* object;
659   int result;
660 
661   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
662   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(subject, librdf_node, 1);
663   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(predicate, librdf_node, 1);
664   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(literal, string, 1);
665 
666   if(!subject ||
667      (!librdf_node_is_resource(subject) && !librdf_node_is_blank(subject)))
668     return 1;
669 
670   if(!predicate || !librdf_node_is_resource(predicate))
671      return 1;
672 
673   if(!literal)
674     return 1;
675 
676   object=librdf_new_node_from_literal(model->world,
677                                       literal, xml_language,
678                                       is_wf_xml);
679   if(!object)
680     return 1;
681 
682   result=librdf_model_add(model, subject, predicate, object);
683   if(result)
684     librdf_free_node(object);
685 
686   return result;
687 }
688 
689 
690 /**
691  * librdf_model_remove_statement:
692  * @model: the model object
693  * @statement: the statement
694  *
695  * Remove a known statement from the model.
696  *
697  * It must be a complete statement - all of subject, predicate, object
698  * parts must be present and a legal RDF triple.
699  *
700  * Return value: non 0 on failure
701  **/
702 int
librdf_model_remove_statement(librdf_model * model,librdf_statement * statement)703 librdf_model_remove_statement(librdf_model* model, librdf_statement* statement)
704 {
705   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
706   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
707 
708   if(!librdf_statement_is_complete(statement))
709     return 1;
710 
711   return model->factory->remove_statement(model, statement);
712 }
713 
714 
715 /**
716  * librdf_model_contains_statement:
717  * @model: the model object
718  * @statement: the statement
719  *
720  * Check for a statement in the model.
721  *
722  * It must be a complete statement - all of subject, predicate,
723  * object parts must be present and a legal RDF triple.  Use
724  * librdf_model_find_statements to search for partial statement
725  * matches.
726  *
727  * WARNING: librdf_model_contains_statement may not work correctly
728  * with stores using contexts.  In this case, a search using
729  * librdf_model_find_statements for a non-empty list will
730  * return the correct result.
731  *
732  * Return value: non 0 if the model contains the statement (>0 if the statement is illegal)
733  **/
734 int
librdf_model_contains_statement(librdf_model * model,librdf_statement * statement)735 librdf_model_contains_statement(librdf_model* model, librdf_statement* statement)
736 {
737   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0);
738   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
739 
740   if(!librdf_statement_is_complete(statement))
741     return 1;
742 
743   return model->factory->contains_statement(model, statement) ? -1 : 0;
744 }
745 
746 
747 /**
748  * librdf_model_as_stream:
749  * @model: the model object
750  *
751  * List the model contents as a stream of statements.
752  *
753  * Return value: a #librdf_stream or NULL on failure
754  **/
755 librdf_stream*
librdf_model_as_stream(librdf_model * model)756 librdf_model_as_stream(librdf_model* model)
757 {
758   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
759 
760   return model->factory->serialise(model);
761 }
762 
763 
764 #ifndef REDLAND_DISABLE_DEPRECATED
765 /**
766  * librdf_model_serialise:
767  * @model: the model object
768  *
769  * Serialise the entire model as a stream (DEPRECATED).
770  *
771  * DEPRECATED to reduce confusion with the librdf_serializer class.
772  * Please use librdf_model_as_stream.
773  *
774  * Return value: a #librdf_stream or NULL on failure
775  **/
776 librdf_stream*
librdf_model_serialise(librdf_model * model)777 librdf_model_serialise(librdf_model* model)
778 {
779   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
780 
781   return model->factory->serialise(model);
782 }
783 #endif
784 
785 
786 /**
787  * librdf_model_find_statements:
788  * @model: the model object
789  * @statement: the partial statement to match
790  *
791  * Find matching statements in the model.
792  *
793  * The partial statement is a statement where the subject, predicate
794  * and/or object can take the value NULL which indicates a match with
795  * any value in the model
796  *
797  * Return value: a #librdf_stream of statements (can be empty) or NULL
798  * on failure.
799  **/
800 librdf_stream*
librdf_model_find_statements(librdf_model * model,librdf_statement * statement)801 librdf_model_find_statements(librdf_model* model,
802                              librdf_statement* statement)
803 {
804   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
805   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL);
806 
807   return model->factory->find_statements(model, statement);
808 }
809 
810 
811 /**
812  * librdf_model_get_sources:
813  * @model: #librdf_model object
814  * @arc: #librdf_node arc
815  * @target: #librdf_node target
816  *
817  * Return the sources (subjects) of arc in an RDF graph given arc (predicate) and target (object).
818  *
819  * Searches the model for arcs matching the given arc and target
820  * and returns a list of the source #librdf_node objects as an iterator
821  *
822  * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
823  **/
824 librdf_iterator*
librdf_model_get_sources(librdf_model * model,librdf_node * arc,librdf_node * target)825 librdf_model_get_sources(librdf_model *model,
826                          librdf_node *arc, librdf_node *target)
827 {
828   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
829   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
830   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
831 
832   return model->factory->get_sources(model, arc, target);
833 }
834 
835 
836 /**
837  * librdf_model_get_arcs:
838  * @model: #librdf_model object
839  * @source: #librdf_node source
840  * @target: #librdf_node target
841  *
842  * Return the arcs (predicates) of an arc in an RDF graph given source (subject) and target (object).
843  *
844  * Searches the model for arcs matching the given source and target
845  * and returns a list of the arc #librdf_node objects as an iterator
846  *
847  * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
848  **/
849 librdf_iterator*
librdf_model_get_arcs(librdf_model * model,librdf_node * source,librdf_node * target)850 librdf_model_get_arcs(librdf_model *model,
851                       librdf_node *source, librdf_node *target)
852 {
853   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
854   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
855   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
856 
857   return model->factory->get_arcs(model, source, target);
858 }
859 
860 
861 /**
862  * librdf_model_get_targets:
863  * @model: #librdf_model object
864  * @source: #librdf_node source
865  * @arc: #librdf_node arc
866  *
867  * Return the targets (objects) of an arc in an RDF graph given source (subject) and arc (predicate).
868  *
869  * Searches the model for targets matching the given source and arc
870  * and returns a list of the source #librdf_node objects as an iterator
871  *
872  * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
873  **/
874 librdf_iterator*
librdf_model_get_targets(librdf_model * model,librdf_node * source,librdf_node * arc)875 librdf_model_get_targets(librdf_model *model,
876                          librdf_node *source, librdf_node *arc)
877 {
878   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
879   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
880   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
881 
882   return model->factory->get_targets(model, source, arc);
883 }
884 
885 
886 /**
887  * librdf_model_get_source:
888  * @model: #librdf_model object
889  * @arc: #librdf_node arc
890  * @target: #librdf_node target
891  *
892  * Return one source (subject) of arc in an RDF graph given arc (predicate) and target (object).
893  *
894  * Searches the model for arcs matching the given arc and target
895  * and returns one #librdf_node object
896  *
897  * Return value:  a new #librdf_node object or NULL on failure
898  **/
899 librdf_node*
librdf_model_get_source(librdf_model * model,librdf_node * arc,librdf_node * target)900 librdf_model_get_source(librdf_model *model,
901                         librdf_node *arc, librdf_node *target)
902 {
903   librdf_iterator *iterator;
904   librdf_node *node;
905 
906   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
907   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
908   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
909 
910   iterator=librdf_model_get_sources(model, arc, target);
911   if(!iterator)
912     return NULL;
913 
914   node=(librdf_node*)librdf_iterator_get_object(iterator);
915   if(node)
916     node=librdf_new_node_from_node(node);
917   librdf_free_iterator(iterator);
918   return node;
919 }
920 
921 
922 /**
923  * librdf_model_get_arc:
924  * @model: #librdf_model object
925  * @source: #librdf_node source
926  * @target: #librdf_node target
927  *
928  * Return one arc (predicate) of an arc in an RDF graph given source (subject) and target (object).
929  *
930  * Searches the model for arcs matching the given source and target
931  * and returns one #librdf_node object
932  *
933  * Return value:  a new #librdf_node object or NULL on failure
934  **/
935 librdf_node*
librdf_model_get_arc(librdf_model * model,librdf_node * source,librdf_node * target)936 librdf_model_get_arc(librdf_model *model,
937                      librdf_node *source, librdf_node *target)
938 {
939   librdf_iterator *iterator;
940   librdf_node *node;
941 
942   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
943   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
944   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
945 
946   iterator=librdf_model_get_arcs(model, source, target);
947   if(!iterator)
948     return NULL;
949 
950   node=(librdf_node*)librdf_iterator_get_object(iterator);
951   if(node)
952     node=librdf_new_node_from_node(node);
953   librdf_free_iterator(iterator);
954   return node;
955 }
956 
957 
958 /**
959  * librdf_model_get_target:
960  * @model: #librdf_model object
961  * @source: #librdf_node source
962  * @arc: #librdf_node arc
963  *
964  * Return one target (object) of an arc in an RDF graph given source (subject) and arc (predicate).
965  *
966  * Searches the model for targets matching the given source and arc
967  * and returns one #librdf_node object
968  *
969  * Return value:  a new #librdf_node object or NULL on failure
970  **/
971 librdf_node*
librdf_model_get_target(librdf_model * model,librdf_node * source,librdf_node * arc)972 librdf_model_get_target(librdf_model *model,
973                         librdf_node *source, librdf_node *arc)
974 {
975   librdf_iterator *iterator;
976   librdf_node *node;
977 
978   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
979   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
980   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
981 
982   iterator=librdf_model_get_targets(model, source, arc);
983   if(!iterator)
984     return NULL;
985 
986   node=(librdf_node*)librdf_iterator_get_object(iterator);
987   if(node)
988     node=librdf_new_node_from_node(node);
989   librdf_free_iterator(iterator);
990   return node;
991 }
992 
993 
994 /**
995  * librdf_model_add_submodel:
996  * @model: the model object
997  * @sub_model: the sub model to add
998  *
999  * Add a sub-model to the model.
1000  *
1001  * FIXME: Not tested
1002  *
1003  * Return value: non 0 on failure
1004  **/
1005 int
librdf_model_add_submodel(librdf_model * model,librdf_model * sub_model)1006 librdf_model_add_submodel(librdf_model* model, librdf_model* sub_model)
1007 {
1008   librdf_list *l=model->sub_models;
1009 
1010   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1011   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(sub_model, librdf_model, 1);
1012 
1013   if(!l) {
1014     l=librdf_new_list(model->world);
1015     if(!l)
1016       return 1;
1017     model->sub_models=l;
1018   }
1019 
1020   if(librdf_list_add(l, sub_model))
1021     return 1;
1022 
1023   return 0;
1024 }
1025 
1026 
1027 
1028 /**
1029  * librdf_model_remove_submodel:
1030  * @model: the model object
1031  * @sub_model: the sub model to remove
1032  *
1033  * Remove a sub-model from the model.
1034  *
1035  * FIXME: Not tested
1036  *
1037  * Return value: non 0 on failure
1038  **/
1039 int
librdf_model_remove_submodel(librdf_model * model,librdf_model * sub_model)1040 librdf_model_remove_submodel(librdf_model* model, librdf_model* sub_model)
1041 {
1042   librdf_list *l=model->sub_models;
1043 
1044   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1045   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(sub_model, librdf_model, 1);
1046 
1047   if(!l)
1048     return 1;
1049   if(!librdf_list_remove(l, sub_model))
1050     return 1;
1051 
1052   return 0;
1053 }
1054 
1055 
1056 
1057 /**
1058  * librdf_model_get_arcs_in:
1059  * @model: #librdf_model object
1060  * @node: #librdf_node resource node
1061  *
1062  * Return the properties pointing to the given resource.
1063  *
1064  * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
1065  **/
1066 librdf_iterator*
librdf_model_get_arcs_in(librdf_model * model,librdf_node * node)1067 librdf_model_get_arcs_in(librdf_model *model, librdf_node *node)
1068 {
1069   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1070   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
1071 
1072   return model->factory->get_arcs_in(model, node);
1073 }
1074 
1075 
1076 /**
1077  * librdf_model_get_arcs_out:
1078  * @model: #librdf_model object
1079  * @node: #librdf_node resource node
1080  *
1081  * Return the properties pointing from the given resource.
1082  *
1083  * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
1084  **/
1085 librdf_iterator*
librdf_model_get_arcs_out(librdf_model * model,librdf_node * node)1086 librdf_model_get_arcs_out(librdf_model *model, librdf_node *node)
1087 {
1088   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1089   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
1090 
1091   return model->factory->get_arcs_out(model, node);
1092 }
1093 
1094 
1095 /**
1096  * librdf_model_has_arc_in:
1097  * @model: #librdf_model object
1098  * @node: #librdf_node resource node
1099  * @property: #librdf_node property node
1100  *
1101  * Check if a node has a given property pointing to it.
1102  *
1103  * Return value: non 0 if arc property does point to the resource node
1104  **/
1105 int
librdf_model_has_arc_in(librdf_model * model,librdf_node * node,librdf_node * property)1106 librdf_model_has_arc_in(librdf_model *model, librdf_node *node,
1107                         librdf_node *property)
1108 {
1109   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0);
1110   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
1111   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0);
1112 
1113   return model->factory->has_arc_in(model, node, property);
1114 }
1115 
1116 
1117 /**
1118  * librdf_model_has_arc_out:
1119  * @model: #librdf_model object
1120  * @node: #librdf_node resource node
1121  * @property: #librdf_node property node
1122  *
1123  * Check if a node has a given property pointing from it.
1124  *
1125  * Return value: non 0 if arc property does point from the resource node
1126  **/
1127 int
librdf_model_has_arc_out(librdf_model * model,librdf_node * node,librdf_node * property)1128 librdf_model_has_arc_out(librdf_model *model, librdf_node *node,
1129                          librdf_node *property)
1130 {
1131   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 0);
1132   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
1133   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0);
1134 
1135   return model->factory->has_arc_out(model, node, property);
1136 }
1137 
1138 
1139 
1140 
1141 #ifndef REDLAND_DISABLE_DEPRECATED
1142 /**
1143  * librdf_model_print:
1144  * @model: the model object
1145  * @fh: the FILE stream to print to
1146  *
1147  * Print the model.
1148  *
1149  * This method is for debugging and the format of the output should
1150  * not be relied on.
1151  *
1152  * @Deprecated: Use librdf_model_write() to write to #raptor_iostream
1153  * which can be made to write to a string.  Use a #librdf_serializer
1154  * to write proper syntax formats.
1155  *
1156  **/
1157 void
librdf_model_print(librdf_model * model,FILE * fh)1158 librdf_model_print(librdf_model *model, FILE *fh)
1159 {
1160   raptor_iostream *iostr;
1161 
1162   LIBRDF_ASSERT_OBJECT_POINTER_RETURN(model, librdf_model);
1163   LIBRDF_ASSERT_OBJECT_POINTER_RETURN(fh, FILE*);
1164 
1165   iostr = raptor_new_iostream_to_file_handle(model->world->raptor_world_ptr, fh);
1166   if(!iostr)
1167     return;
1168 
1169   librdf_model_write(model, iostr);
1170 
1171   raptor_free_iostream(iostr);
1172 }
1173 #endif
1174 
1175 
1176 /**
1177  * librdf_model_write:
1178  * @model: the model object
1179  * @iostr: the iostream to write to
1180  *
1181  * Write a model to an iostream in a debug format.
1182  *
1183  * This method is for debugging and the format of the output should
1184  * not be relied on.  In particular, when contexts are used the
1185  * result may be 4 nodes.
1186  *
1187  * Return value: non-0 on failure
1188  **/
1189 int
librdf_model_write(librdf_model * model,raptor_iostream * iostr)1190 librdf_model_write(librdf_model *model, raptor_iostream* iostr)
1191 {
1192   int rc = 1;
1193   librdf_stream* stream;
1194 
1195   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1196   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(iostr, raptor_iostream, 1);
1197 
1198   stream = librdf_model_as_stream(model);
1199   if(!stream)
1200     goto tidy;
1201 
1202   if(raptor_iostream_counted_string_write("[[\n", 3, iostr))
1203     goto tidy;
1204   if(librdf_stream_write(stream, iostr))
1205     goto tidy;
1206   if(raptor_iostream_counted_string_write("]]\n", 3, iostr))
1207     goto tidy;
1208 
1209   /* success */
1210   rc = 0;
1211 
1212   tidy:
1213   if(stream)
1214     librdf_free_stream(stream);
1215 
1216   return rc;
1217 }
1218 
1219 
1220 /**
1221  * librdf_model_context_add_statement:
1222  * @model: #librdf_model object
1223  * @context: #librdf_node context
1224  * @statement: #librdf_statement statement object
1225  *
1226  * Add a statement to a model with a context.
1227  *
1228  * It must be a complete statement - all
1229  * of subject, predicate, object parts must be present.
1230  *
1231  * If @context is NULL, this is equivalent to librdf_model_add_statement
1232  *
1233  * Return value: Non 0 on failure
1234  **/
1235 int
librdf_model_context_add_statement(librdf_model * model,librdf_node * context,librdf_statement * statement)1236 librdf_model_context_add_statement(librdf_model* model,
1237                                    librdf_node* context,
1238                                    librdf_statement* statement)
1239 {
1240   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1241   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
1242 
1243   if(!librdf_statement_is_complete(statement))
1244     return 1;
1245 
1246   if(!librdf_model_supports_contexts(model)) {
1247     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1248                "Model does not support contexts");
1249     return 1;
1250   }
1251 
1252   return model->factory->context_add_statement(model, context, statement);
1253 }
1254 
1255 
1256 
1257 /**
1258  * librdf_model_context_add_statements:
1259  * @model: #librdf_model object
1260  * @context: #librdf_node context
1261  * @stream: #librdf_stream stream object
1262  *
1263  * Add statements to a model with a context.
1264  *
1265  * If @context is NULL, this is equivalent to librdf_model_add_statements
1266  *
1267  * Return value: Non 0 on failure
1268  **/
1269 int
librdf_model_context_add_statements(librdf_model * model,librdf_node * context,librdf_stream * stream)1270 librdf_model_context_add_statements(librdf_model* model,
1271                                     librdf_node* context,
1272                                     librdf_stream* stream)
1273 {
1274   int status=0;
1275 
1276   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1277   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1);
1278 
1279   if(!stream)
1280     return 1;
1281 
1282   if(!librdf_model_supports_contexts(model)) {
1283     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1284                "Model does not support contexts");
1285     return 1;
1286   }
1287 
1288   if(model->factory->context_add_statements)
1289     return model->factory->context_add_statements(model, context, stream);
1290 
1291   while(!librdf_stream_end(stream)) {
1292     librdf_statement* statement=librdf_stream_get_object(stream);
1293     if(!statement)
1294       break;
1295     status=librdf_model_context_add_statement(model, context, statement);
1296     if(status)
1297       break;
1298     librdf_stream_next(stream);
1299   }
1300 
1301   return status;
1302 }
1303 
1304 
1305 
1306 /**
1307  * librdf_model_context_remove_statement:
1308  * @model: #librdf_model object
1309  * @context: #librdf_node context
1310  * @statement: #librdf_statement statement
1311  *
1312  * Remove a statement from a model in a context.
1313  *
1314  * It must be a complete statement - all of subject, predicate, object
1315  * parts must be present.
1316  *
1317  * If @context is NULL, this is equivalent to librdf_model_remove_statement
1318  *
1319  * Return value: Non 0 on failure
1320  **/
1321 int
librdf_model_context_remove_statement(librdf_model * model,librdf_node * context,librdf_statement * statement)1322 librdf_model_context_remove_statement(librdf_model* model,
1323                                       librdf_node* context,
1324                                       librdf_statement* statement)
1325 {
1326   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1327   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
1328 
1329   if(!librdf_statement_is_complete(statement))
1330     return 1;
1331 
1332   if(!librdf_model_supports_contexts(model)) {
1333     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1334                "Model does not support contexts");
1335     return 1;
1336   }
1337 
1338   return model->factory->context_remove_statement(model, context, statement);
1339 }
1340 
1341 
1342 /**
1343  * librdf_model_context_remove_statements:
1344  * @model: #librdf_model object
1345  * @context: #librdf_node context
1346  *
1347  * Remove statements from a model with the given context.
1348  *
1349  * Return value: Non 0 on failure
1350  **/
1351 int
librdf_model_context_remove_statements(librdf_model * model,librdf_node * context)1352 librdf_model_context_remove_statements(librdf_model* model,
1353                                        librdf_node* context)
1354 {
1355   librdf_stream *stream;
1356 
1357   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1358   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, 1);
1359 
1360   if(!librdf_model_supports_contexts(model)) {
1361     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1362                "Model does not support contexts");
1363     return 1;
1364   }
1365 
1366   if(model->factory->context_remove_statements)
1367     return model->factory->context_remove_statements(model, context);
1368 
1369   stream=librdf_model_context_as_stream(model, context);
1370   if(!stream)
1371     return 1;
1372 
1373   while(!librdf_stream_end(stream)) {
1374     librdf_statement *statement=librdf_stream_get_object(stream);
1375     if(!statement)
1376       break;
1377     librdf_model_context_remove_statement(model, context, statement);
1378     librdf_stream_next(stream);
1379   }
1380   librdf_free_stream(stream);
1381   return 0;
1382 }
1383 
1384 
1385 /**
1386  * librdf_model_context_as_stream:
1387  * @model: #librdf_model object
1388  * @context: #librdf_node context
1389  *
1390  * List all statements in a model context.
1391  *
1392  * Return value: #librdf_stream of statements or NULL on failure
1393  **/
1394 librdf_stream*
librdf_model_context_as_stream(librdf_model * model,librdf_node * context)1395 librdf_model_context_as_stream(librdf_model* model, librdf_node* context)
1396 {
1397   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1398   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, NULL);
1399 
1400   if(!librdf_model_supports_contexts(model)) {
1401     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1402                "Model does not support contexts");
1403     return NULL;
1404   }
1405 
1406   return model->factory->context_serialize(model, context);
1407 }
1408 
1409 
1410 #ifndef REDLAND_DISABLE_DEPRECATED
1411 /**
1412  * librdf_model_context_serialize:
1413  * @model: #librdf_model object
1414  * @context: #librdf_node context
1415  *
1416  * List all statements in a model context.
1417  *
1418  * DEPRECATED to reduce confusion with the librdf_serializer class.
1419  * Please use librdf_model_context_as_stream.
1420  *
1421  * Return value: #librdf_stream of statements or NULL on failure
1422  **/
1423 librdf_stream*
librdf_model_context_serialize(librdf_model * model,librdf_node * context)1424 librdf_model_context_serialize(librdf_model* model, librdf_node* context)
1425 {
1426   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1427   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_node, NULL);
1428 
1429   if(!librdf_model_supports_contexts(model)) {
1430     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1431                "Model does not support contexts");
1432     return NULL;
1433   }
1434 
1435   return model->factory->context_serialize(model, context);
1436 }
1437 #endif
1438 
1439 
1440 /**
1441  * librdf_model_query_execute:
1442  * @model: #librdf_model object
1443  * @query: #librdf_query object
1444  *
1445  * Execute a query against the model.
1446  *
1447  * Run the given query against the model and return a #librdf_stream of
1448  * matching #librdf_statement objects
1449  *
1450  * Return value: #librdf_query_results or NULL on failure
1451  **/
1452 librdf_query_results*
librdf_model_query_execute(librdf_model * model,librdf_query * query)1453 librdf_model_query_execute(librdf_model* model, librdf_query* query)
1454 {
1455   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1456   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, librdf_query, NULL);
1457 
1458   return model->factory->query_execute(model, query);
1459 }
1460 
1461 
1462 /**
1463  * librdf_model_sync:
1464  * @model: #librdf_model object
1465  *
1466  * Synchronise the model to the model implementation.
1467  *
1468  * Return value: non-0 on failure
1469  **/
1470 int
librdf_model_sync(librdf_model * model)1471 librdf_model_sync(librdf_model* model)
1472 {
1473   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, 1);
1474 
1475   if(model->factory->sync)
1476     return model->factory->sync(model);
1477 
1478   return 0;
1479 }
1480 
1481 
1482 /**
1483  * librdf_model_get_storage:
1484  * @model: #librdf_model object
1485  *
1486  * Return the storage of this model.
1487  *
1488  * Note: this can only return one storage, so model implementations
1489  * that have multiple #librdf_storage internally may chose not to
1490  * implement this.
1491  *
1492  * Return value:  #librdf_storage or NULL if this has no store
1493  **/
1494 librdf_storage*
librdf_model_get_storage(librdf_model * model)1495 librdf_model_get_storage(librdf_model *model)
1496 {
1497   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1498 
1499   if(model->factory->get_storage)
1500     return model->factory->get_storage(model);
1501   else
1502     return NULL;
1503 }
1504 
1505 
1506 /**
1507  * librdf_model_find_statements_in_context:
1508  * @model: #librdf_model object
1509  * @statement: #librdf_statement partial statement to find
1510  * @context_node: context #librdf_node (or NULL)
1511  *
1512  * Search the model for matching statements in a given context.
1513  *
1514  * Searches the model for a (partial) statement as described in
1515  * librdf_statement_match() in the given context and returns a
1516  * #librdf_stream of matching #librdf_statement objects.  If
1517  * context is NULL, this is equivalent to librdf_model_find_statements.
1518  *
1519  * Return value: #librdf_stream of matching statements (may be empty) or NULL on failure
1520  **/
1521 librdf_stream*
librdf_model_find_statements_in_context(librdf_model * model,librdf_statement * statement,librdf_node * context_node)1522 librdf_model_find_statements_in_context(librdf_model* model, librdf_statement* statement, librdf_node* context_node)
1523 {
1524   librdf_stream *stream;
1525 
1526   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1527   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL);
1528 
1529   if(!librdf_model_supports_contexts(model)) {
1530     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1531                "Model does not support contexts");
1532     return NULL;
1533   }
1534 
1535   if(model->factory->find_statements_in_context)
1536     return model->factory->find_statements_in_context(model, statement, context_node);
1537 
1538   statement=librdf_new_statement_from_statement(statement);
1539   if(!statement)
1540     return NULL;
1541 
1542   stream=librdf_model_context_as_stream(model, context_node);
1543   if(!stream) {
1544     librdf_free_statement(statement);
1545     return librdf_new_empty_stream(model->world);
1546   }
1547 
1548   librdf_stream_add_map(stream,
1549                         &librdf_stream_statement_find_map,
1550                         (librdf_stream_map_free_context_handler)&librdf_free_statement, (void*)statement);
1551 
1552   return stream;
1553 }
1554 
1555 
1556 /**
1557  * librdf_model_get_contexts:
1558  * @model: #librdf_model object
1559  *
1560  * Return the list of contexts in the graph.
1561  *
1562  * Returns an iterator of #librdf_node context nodes for each
1563  * context in the graph.
1564  *
1565  * Return value: #librdf_iterator of context nodes or NULL on failure or if contexts are not supported
1566  **/
1567 librdf_iterator*
librdf_model_get_contexts(librdf_model * model)1568 librdf_model_get_contexts(librdf_model* model)
1569 {
1570   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1571 
1572   if(!librdf_model_supports_contexts(model)) {
1573     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1574                "Model does not support contexts");
1575     return NULL;
1576   }
1577 
1578   if(model->factory->get_contexts)
1579     return model->factory->get_contexts(model);
1580   else
1581     return NULL;
1582 }
1583 
1584 
1585 /**
1586  * librdf_model_get_feature:
1587  * @model: #librdf_model object
1588  * @feature: #librdf_uri feature property
1589  *
1590  * Get the value of a graph feature .
1591  *
1592  * Return value: new #librdf_node feature value or NULL if no such feature
1593  * exists or the value is empty.
1594  **/
1595 librdf_node*
librdf_model_get_feature(librdf_model * model,librdf_uri * feature)1596 librdf_model_get_feature(librdf_model* model, librdf_uri* feature)
1597 {
1598   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, NULL);
1599   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, NULL);
1600 
1601   if(model->factory->get_feature)
1602     return model->factory->get_feature(model, feature);
1603   return NULL;
1604 }
1605 
1606 
1607 /**
1608  * librdf_model_set_feature:
1609  * @model: #librdf_model object
1610  * @feature: #librdf_uri feature property
1611  * @value: #librdf_node feature property value
1612  *
1613  * Set the value of a graph feature.
1614  *
1615  * Return value: non 0 on failure (negative if no such feature)
1616  **/
1617 int
librdf_model_set_feature(librdf_model * model,librdf_uri * feature,librdf_node * value)1618 librdf_model_set_feature(librdf_model* model, librdf_uri* feature,
1619                          librdf_node* value)
1620 {
1621   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(model, librdf_model, -1);
1622   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, -1);
1623   LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, librdf_node, -1);
1624 
1625   if(model->factory->set_feature)
1626     return model->factory->set_feature(model, feature, value);
1627   return -1;
1628 }
1629 
1630 
1631 /**
1632  * librdf_model_find_statements_with_options:
1633  * @model: #librdf_model object
1634  * @statement: #librdf_statement partial statement to find
1635  * @context_node: #librdf_node context node or NULL.
1636  * @options: #librdf_hash of matching options or NULL
1637  *
1638  * Search the model for matching statements with match options.
1639  *
1640  * Searches the model for a (partial) statement as described in
1641  * librdf_statement_match() and returns a #librdf_stream of
1642  * matching #librdf_statement objects.
1643  *
1644  * If options is given then the match is made according to
1645  * the given options.  If options is NULL, this is equivalent
1646  * to librdf_model_find_statements_in_context.
1647  *
1648  * Return value:  #librdf_stream of matching statements (may be empty) or NULL on failure
1649  **/
1650 librdf_stream*
librdf_model_find_statements_with_options(librdf_model * model,librdf_statement * statement,librdf_node * context_node,librdf_hash * options)1651 librdf_model_find_statements_with_options(librdf_model* model,
1652                                           librdf_statement* statement,
1653                                           librdf_node* context_node,
1654                                           librdf_hash* options)
1655 {
1656   if(context_node && !librdf_model_supports_contexts(model)) {
1657     librdf_log(model->world, 0, LIBRDF_LOG_WARN, LIBRDF_FROM_MODEL, NULL,
1658                "Model does not support contexts");
1659     return NULL;
1660   }
1661 
1662   if(model->factory->find_statements_with_options)
1663     return model->factory->find_statements_with_options(model, statement, context_node, options);
1664   else
1665     return librdf_model_find_statements_in_context(model, statement, context_node);
1666 }
1667 
1668 
1669 /**
1670  * librdf_model_load:
1671  * @model: #librdf_model object
1672  * @uri: the URI to read the content
1673  * @name: the name of the parser (or NULL)
1674  * @mime_type: the MIME type of the syntax (NULL if not used)
1675  * @type_uri: URI identifying the syntax (NULL if not used)
1676  *
1677  * Load content from a URI into the model.
1678  *
1679  * If the name field is NULL, the library will try to guess
1680  * the parser to use from the uri, mime_type and type_uri fields.
1681  * This is done via the raptor_guess_parser_name function.
1682  *
1683  * Return value: non 0 on failure
1684  **/
1685 int
librdf_model_load(librdf_model * model,librdf_uri * uri,const char * name,const char * mime_type,librdf_uri * type_uri)1686 librdf_model_load(librdf_model* model, librdf_uri *uri,
1687                   const char *name, const char *mime_type,
1688                   librdf_uri *type_uri)
1689 {
1690   int rc=0;
1691   librdf_parser* parser;
1692 
1693   if(name && !*name)
1694     name=NULL;
1695   if(mime_type && !*mime_type)
1696     mime_type=NULL;
1697 
1698   if(!name)
1699     name = raptor_world_guess_parser_name(model->world->raptor_world_ptr,
1700                                           (raptor_uri*)type_uri, mime_type,
1701                                           NULL, 0, librdf_uri_as_string(uri));
1702 
1703   parser=librdf_new_parser(model->world, name, NULL, NULL);
1704   if(!parser)
1705     return 1;
1706 
1707   rc=librdf_parser_parse_into_model(parser, uri, NULL, model);
1708   librdf_free_parser(parser);
1709   return rc;
1710 }
1711 
1712 
1713 /**
1714  * librdf_model_to_counted_string:
1715  * @model: #librdf_model object
1716  * @uri: base URI to use in serializing (or NULL if not used)
1717  * @name: the name of the serializer (or NULL for default)
1718  * @mime_type: the MIME type of the syntax (NULL if not used)
1719  * @type_uri: URI identifying the syntax (NULL if not used)
1720  * @string_length_p: pointer to location to store string length (or NULL)
1721  *
1722  * Write serialized model to a string.
1723  *
1724  * If the name field is NULL, the default serializer will be used.
1725  *
1726  * Note: the returned string must be freed by the caller using librdf_free_memory().
1727  *
1728  * Return value: new string or NULL on failure
1729  **/
1730 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)1731 librdf_model_to_counted_string(librdf_model* model, librdf_uri *uri,
1732                                const char *name, const char *mime_type,
1733                                librdf_uri *type_uri, size_t* string_length_p)
1734 {
1735   unsigned char *string=NULL;
1736   librdf_serializer* serializer;
1737 
1738   if(name && !*name)
1739     name=NULL;
1740   if(mime_type && !*mime_type)
1741     mime_type=NULL;
1742 
1743   serializer=librdf_new_serializer(model->world, name, mime_type, type_uri);
1744   if(!serializer)
1745     return NULL;
1746 
1747   string=librdf_serializer_serialize_model_to_counted_string(serializer,
1748                                                              uri, model,
1749                                                              string_length_p);
1750   librdf_free_serializer(serializer);
1751   return string;
1752 }
1753 
1754 
1755 /**
1756  * librdf_model_to_string:
1757  * @model: #librdf_model object
1758  * @uri: base URI to use in serializing (or NULL if not used)
1759  * @name: the name of the serializer (or NULL for default)
1760  * @mime_type: the MIME type of the syntax (NULL if not used)
1761  * @type_uri: URI identifying the syntax (NULL if not used)
1762  *
1763  * Write serialized model to a string.
1764  *
1765  * If the name field is NULL, the default serializer will be used.
1766  *
1767  * Note: the returned string must be freed by the caller.
1768  *
1769  * Return value: new string or NULL on failure
1770  **/
1771 unsigned char*
librdf_model_to_string(librdf_model * model,librdf_uri * uri,const char * name,const char * mime_type,librdf_uri * type_uri)1772 librdf_model_to_string(librdf_model* model, librdf_uri *uri,
1773                        const char *name, const char *mime_type,
1774                        librdf_uri *type_uri) {
1775   return librdf_model_to_counted_string(model, uri,
1776                                         name, mime_type, type_uri,
1777                                         NULL);
1778 }
1779 
1780 
1781 /**
1782  * librdf_model_contains_context:
1783  * @model: the model object
1784  * @context: the contest
1785  *
1786  * Check for a context in the model.
1787  *
1788  * Return value: non 0 if the model contains the context node
1789  **/
1790 int
librdf_model_contains_context(librdf_model * model,librdf_node * context)1791 librdf_model_contains_context(librdf_model* model, librdf_node* context) {
1792   librdf_stream* stream;
1793   int result;
1794 
1795   stream=librdf_model_context_as_stream(model, context);
1796   if(!stream)
1797     return 0;
1798 
1799   result=!librdf_stream_end(stream);
1800   librdf_free_stream(stream);
1801 
1802   return result;
1803 }
1804 
1805 
1806 /**
1807  * librdf_model_transaction_start:
1808  * @model: the model object
1809  *
1810  * Start a transaction
1811  *
1812  * Return value: non-0 on failure
1813  **/
1814 int
librdf_model_transaction_start(librdf_model * model)1815 librdf_model_transaction_start(librdf_model* model)
1816 {
1817   if(model->factory->transaction_start)
1818     return model->factory->transaction_start(model);
1819   else
1820     return 1;
1821 }
1822 
1823 
1824 /**
1825  * librdf_model_transaction_start_with_handle:
1826  * @model: the model object
1827  * @handle: the transaction object
1828  *
1829  * Start a transaction using an existing external transaction object.
1830  *
1831  * Return value: non-0 on failure
1832  **/
1833 int
librdf_model_transaction_start_with_handle(librdf_model * model,void * handle)1834 librdf_model_transaction_start_with_handle(librdf_model* model, void* handle)
1835 {
1836   if(model->factory->transaction_start_with_handle)
1837     return model->factory->transaction_start_with_handle(model, handle);
1838   else
1839     return 1;
1840 }
1841 
1842 
1843 /**
1844  * librdf_model_transaction_commit:
1845  * @model: the model object
1846  *
1847  * Commit a transaction.
1848  *
1849  * Return value: non-0 on failure
1850  **/
1851 int
librdf_model_transaction_commit(librdf_model * model)1852 librdf_model_transaction_commit(librdf_model* model)
1853 {
1854   if(model->factory->transaction_commit)
1855     return model->factory->transaction_commit(model);
1856   else
1857     return 1;
1858 }
1859 
1860 
1861 /**
1862  * librdf_model_transaction_rollback:
1863  * @model: the model object
1864  *
1865  * Rollback a transaction.
1866  *
1867  * Return value: non-0 on failure
1868  **/
1869 int
librdf_model_transaction_rollback(librdf_model * model)1870 librdf_model_transaction_rollback(librdf_model* model)
1871 {
1872   if(model->factory->transaction_rollback)
1873     return model->factory->transaction_rollback(model);
1874   else
1875     return 1;
1876 }
1877 
1878 
1879 /**
1880  * librdf_model_transaction_get_handle:
1881  * @model: the model object
1882  *
1883  * Get the current transaction handle.
1884  *
1885  * Return value: non-0 on failure
1886  **/
1887 void*
librdf_model_transaction_get_handle(librdf_model * model)1888 librdf_model_transaction_get_handle(librdf_model* model)
1889 {
1890   if(model->factory->transaction_get_handle)
1891     return model->factory->transaction_get_handle(model);
1892   else
1893     return NULL;
1894 }
1895 
1896 #endif
1897 
1898 
1899 /* TEST CODE */
1900 
1901 
1902 #ifdef STANDALONE
1903 
1904 /* one more prototype */
1905 int main(int argc, char *argv[]);
1906 
1907 #define EX1_CONTENT \
1908 "<?xml version=\"1.0\"?>\n" \
1909 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" \
1910 "         xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n" \
1911 "  <rdf:Description rdf:about=\"http://purl.org/net/dajobe/\">\n" \
1912 "    <dc:title>Dave Beckett's Home Page</dc:title>\n" \
1913 "    <dc:creator>Dave Beckett</dc:creator>\n" \
1914 "    <dc:description>The generic home page of Dave Beckett.</dc:description>\n" \
1915 "  </rdf:Description>\n" \
1916 "</rdf:RDF>"
1917 
1918 #define EX2_CONTENT \
1919 "<?xml version=\"1.0\"?>\n" \
1920 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" \
1921 "         xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n" \
1922 "  <rdf:Description rdf:about=\"http://purl.org/net/dajobe/\">\n" \
1923 "    <dc:title>Dave Beckett's Home Page</dc:title>\n" \
1924 "    <dc:creator>Dave Beckett</dc:creator>\n" \
1925 "    <dc:description>I do development-based research on RDF, metadata and web searching.</dc:description>\n" \
1926 "    <dc:rights>Copyright &#169; 2002 Dave Beckett</dc:rights>\n" \
1927 "  </rdf:Description>\n" \
1928 "</rdf:RDF>"
1929 
1930 int test_model_cloning(char const *program, librdf_world *);
1931 int test_model(librdf_world *world, const char *program,
1932     const char *storage_type, const char *storage_name, const char* storage_options);
1933 
1934 int
main(int argc,char * argv[])1935 main(int argc, char *argv[])
1936 {
1937   const char *program=librdf_basename((const char*)argv[0]);
1938   /* initialise dependent modules - all of them! */
1939   librdf_world *world=librdf_new_world();
1940   const char* storage_type;
1941   const char* storage_name;
1942   const char* storage_options;
1943   int i;
1944   int status=0;
1945 
1946   librdf_world_open(world);
1947 
1948   /* Test model cloning first */
1949   if(test_model_cloning(program, world)) {
1950     status = 1;
1951     goto tidy;
1952   }
1953 
1954   /* Get storage configuration */
1955   storage_type=getenv("REDLAND_TEST_STORAGE_TYPE");
1956   storage_name=getenv("REDLAND_TEST_STORAGE_NAME");
1957   storage_options=getenv("REDLAND_TEST_STORAGE_OPTIONS");
1958   if(!(storage_type && storage_name && storage_options)) {
1959     /* test all storages */
1960     const char* const storages[] = {
1961       "memory", NULL, "write='yes',new='yes',contexts='yes'",
1962 #ifdef STORAGE_HASHES
1963 #ifdef HAVE_BDB_HASH
1964       "hashes", "test", "hash-type='bdb',dir='.',write='yes',new='yes',contexts='yes'",
1965 #else
1966       "hashes", "test", "hash-type='memory',write='yes',new='yes',contexts='yes'",
1967 #endif
1968 #endif
1969 #ifdef STORAGE_TREES
1970       "trees", "test", "contexts='yes'",
1971 #endif
1972 #ifdef STORAGE_FILE
1973       "file", "test.rdf", NULL,
1974 #endif
1975 #ifdef STORAGE_MYSQL
1976       "mysql", "test", "host='localhost',database='test'",
1977 #endif
1978 #ifdef STORAGE_POSTGRESQL
1979       "postgresql", "test", "host='localhost',database='test'",
1980 #endif
1981 #ifdef STORAGE_TSTORE
1982       "tstore", "test", "host='localhost',database='test'",
1983 #endif
1984 #ifdef STORAGE_SQLITE
1985       "sqlite", "test", "new='yes'",
1986 #endif
1987        NULL, NULL, NULL
1988     };
1989 
1990     for (i=0; storages[i]; i += 3) {
1991       if (test_model(world, program, storages[i], storages[i+1], storages[i+2])) {
1992         status = 1;
1993         break;
1994       }
1995     }
1996   } else {
1997     status = test_model(world, program, storage_type, storage_name, storage_options);
1998   }
1999 
2000   tidy:
2001   librdf_free_world(world);
2002 
2003   return status;
2004 }
2005 
2006 int
test_model(librdf_world * world,const char * program,const char * storage_type,const char * storage_name,const char * storage_options)2007 test_model(librdf_world *world, const char *program,
2008     const char *storage_type, const char *storage_name, const char *storage_options)
2009 {
2010   librdf_storage* storage;
2011   librdf_model* model;
2012   librdf_statement *statement;
2013   librdf_parser* parser;
2014   librdf_stream* stream;
2015   const char *parser_name="rdfxml";
2016   #define URI_STRING_COUNT 2
2017   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"};
2018   const unsigned char *file_content[URI_STRING_COUNT]={(const unsigned char*)EX1_CONTENT, (const unsigned char*)EX2_CONTENT};
2019   librdf_uri* uris[URI_STRING_COUNT];
2020   librdf_node* nodes[URI_STRING_COUNT];
2021   int i;
2022   librdf_iterator *iterator;
2023   librdf_node *n1, *n2;
2024   int count;
2025   int expected_count;
2026 #define EXPECTED_BAD_STRING_LENGTH 1139
2027   librdf_uri* base_uri;
2028   unsigned char *string;
2029   size_t string_length=0;
2030   int remove_count=0;
2031   int status=0;
2032   raptor_iostream* iostr;
2033   librdf_node* literal_node;
2034   char literal[6];
2035 
2036   iostr = raptor_new_iostream_to_file_handle(world->raptor_world_ptr, stderr);
2037 
2038   fprintf(stderr, "%s: Creating new %s storage\n", program, storage_type);
2039   storage=librdf_new_storage(world, storage_type, storage_name, storage_options);
2040   if(!storage) {
2041     fprintf(stderr, "%s: WARNING: Failed to create new %s storage name %s with options %s\n", program, storage_type, storage_name, storage_options);
2042     raptor_free_iostream(iostr);
2043     return(0);
2044   }
2045 
2046   fprintf(stderr, "%s: Creating model\n", program);
2047   model=librdf_new_model(world, storage, NULL);
2048   if(!model) {
2049     fprintf(stderr, "%s: Failed to create new model\n", program);
2050     return(1);
2051   }
2052 
2053   statement=librdf_new_statement(world);
2054   /* after this, nodes become owned by model */
2055   librdf_statement_set_subject(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://www.dajobe.org/"));
2056   librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator"));
2057 
2058   if(!librdf_model_add_statement(model, statement)) {
2059     fprintf(stderr, "%s: librdf_model_add_statement unexpectedly succeeded adding a partial statement\n", program);
2060     return(1);
2061   }
2062 
2063   librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Dave Beckett", NULL, 0));
2064 
2065   librdf_model_add_statement(model, statement);
2066   librdf_free_statement(statement);
2067 
2068   /* make it illegal */
2069   statement=librdf_new_statement(world);
2070   librdf_statement_set_subject(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Bad Subject", NULL, 0));
2071   librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/pred"));
2072   librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)"Good Object", NULL, 0));
2073 
2074   if(!librdf_model_add_statement(model, statement)) {
2075     fprintf(stderr, "%s: librdf_model_add_statement unexpectedly succeeded adding an illegal triple\n", program);
2076     return(1);
2077   }
2078   librdf_free_statement(statement);
2079 
2080   fprintf(stderr, "%s: Printing model\n", program);
2081   librdf_model_write(model, iostr);
2082 
2083 #define TEST_SIMILAR_COUNT 9
2084 
2085   /* add some similar statements */
2086   fprintf(stderr, "%s: Adding %d similar statements\n", program, TEST_SIMILAR_COUNT);
2087   for(i=0; i < TEST_SIMILAR_COUNT; i++) {
2088     char literal[6];
2089     strncpy(literal, "DaveX", 6);
2090     literal[4]='0'+i;
2091     statement=librdf_new_statement(world);
2092     librdf_statement_set_subject(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/"));
2093     librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator"));
2094     librdf_statement_set_object(statement, librdf_new_node_from_literal(world, (const unsigned char*)literal, NULL, 0));
2095 
2096     librdf_model_add_statement(model, statement);
2097     librdf_free_statement(statement);
2098   }
2099 
2100   /* targets */
2101   fprintf(stderr, "%s: iterating similar statements\n", program);
2102   n1=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/");
2103   n2=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator");
2104   iterator=librdf_model_get_targets(model, n1, n2);
2105   if(!iterator) {
2106     fprintf(stderr, "%s: librdf_model_get_targets failed\n", program);
2107     status=1;
2108   }
2109 
2110   fprintf(stderr, "%s: iterating similar statements again\n", program);
2111   for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2112     librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2113     fputs("  ", stderr);
2114     librdf_node_print(n, stderr);
2115     fputs("\n", stderr);
2116   }
2117   librdf_free_iterator(iterator);
2118 
2119   /* delete first, last, and another statement */
2120   statement=librdf_new_statement(world);
2121   librdf_statement_set_subject(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://example.org/"));
2122   librdf_statement_set_predicate(statement, librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator"));
2123 
2124   strncpy(literal, "DaveX", 6);
2125 
2126   literal[4]='0';
2127   fprintf(stderr, "%s: Removing statement with literal '%s'\n", program, literal);
2128   literal_node = librdf_new_node_from_literal(world, (const unsigned char*)literal, NULL, 0);
2129   librdf_statement_set_object(statement, literal_node);
2130   librdf_model_remove_statement(model, statement);
2131   librdf_statement_set_object(statement, NULL);
2132   librdf_free_node(literal_node);
2133 
2134   literal[4]='0' + (TEST_SIMILAR_COUNT / 2);
2135   fprintf(stderr, "%s: Removing statement with literal '%s'\n", program, literal);
2136   literal_node = librdf_new_node_from_literal(world, (const unsigned char*)literal, NULL, 0);
2137   librdf_statement_set_object(statement, literal_node);
2138   librdf_model_remove_statement(model, statement);
2139   librdf_statement_set_object(statement, NULL);
2140   librdf_free_node(literal_node);
2141 
2142   literal[4]='0' + (TEST_SIMILAR_COUNT - 1);
2143   fprintf(stderr, "%s: Removing statement with literal '%s'\n", program, literal);
2144   literal_node = librdf_new_node_from_literal(world, (const unsigned char*)literal, NULL, 0);
2145   librdf_statement_set_object(statement, literal_node);
2146   librdf_model_remove_statement(model, statement);
2147   librdf_statement_set_object(statement, NULL);
2148   librdf_free_node(literal_node);
2149 
2150   librdf_free_statement(statement);
2151 
2152   iterator=librdf_model_get_targets(model, n1, n2);
2153   fprintf(stderr, "%s: iterating similar statements again\n", program);
2154   for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2155     librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2156     fputs("  ", stderr);
2157     librdf_node_print(n, stderr);
2158     fputs("\n", stderr);
2159   }
2160   librdf_free_iterator(iterator);
2161   expected_count=TEST_SIMILAR_COUNT - 3;
2162   if(count != expected_count) {
2163     fprintf(stderr, "%s: model has %d similar statements, expected %d\n", program, count, expected_count);
2164     status=1;
2165   }
2166 
2167   librdf_free_node(n1);
2168   librdf_free_node(n2);
2169 
2170   if (!model->supports_contexts)
2171     goto done;
2172 
2173   parser=librdf_new_parser(world, parser_name, NULL, NULL);
2174   if(!parser) {
2175     fprintf(stderr, "%s: Failed to create new parser type %s\n", program,
2176             parser_name);
2177     exit(1);
2178   }
2179 
2180   for (i=0; i<URI_STRING_COUNT; i++) {
2181     uris[i]=librdf_new_uri(world, file_uri_strings[i]);
2182     nodes[i]=librdf_new_node_from_uri_string(world, file_uri_strings[i]);
2183 
2184     fprintf(stderr, "%s: Adding content from %s into statement context\n", program,
2185             librdf_uri_as_string(uris[i]));
2186     if(!(stream=librdf_parser_parse_string_as_stream(parser,
2187                                                      file_content[i], uris[i]))) {
2188       fprintf(stderr, "%s: Failed to parse RDF from %s as stream\n", program,
2189               librdf_uri_as_string(uris[i]));
2190       return(1);
2191     }
2192     librdf_model_context_add_statements(model, nodes[i], stream);
2193     librdf_free_stream(stream);
2194 
2195     fprintf(stderr, "%s: Printing model\n", program);
2196     librdf_model_write(model, iostr);
2197   }
2198 
2199 
2200   fprintf(stderr, "%s: Freeing Parser\n", program);
2201   librdf_free_parser(parser);
2202 
2203 
2204   /* sync - probably a NOP */
2205   librdf_model_sync(model);
2206 
2207 
2208   /* sources */
2209   n1=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/creator");
2210   n2=librdf_new_node_from_literal(world, (const unsigned char*)"Dave Beckett", NULL, 0);
2211 
2212   fprintf(stderr, "%s: Looking for sources of arc=", program);
2213   librdf_node_print(n1, stderr);
2214   fputs(" target=", stderr);
2215   librdf_node_print(n2, stderr);
2216   fputs("\n", stderr);
2217 
2218   iterator=librdf_model_get_sources(model, n1, n2);
2219   if(!iterator) {
2220     fprintf(stderr, "%s: librdf_model_get_sources failed\n", program);
2221     status=1;
2222   }
2223 
2224   expected_count=3;
2225   for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2226     librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2227     fputs("  ", stderr);
2228     librdf_node_print(n, stderr);
2229     fputs("\n", stderr);
2230   }
2231   librdf_free_iterator(iterator);
2232   if(count != expected_count) {
2233     fprintf(stderr, "%s: librdf_model_get_sources returned %d nodes, expected %d\n", program, count, expected_count);
2234     status=1;
2235   }
2236   librdf_free_node(n1);
2237   librdf_free_node(n2);
2238 
2239 
2240   /* targets */
2241   n1=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/net/dajobe/");
2242   n2=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/dc/elements/1.1/description");
2243 
2244   fprintf(stderr, "%s: Looking for targets of source=", program);
2245   librdf_node_print(n1, stderr);
2246   fputs(" arc=", stderr);
2247   librdf_node_print(n2, stderr);
2248   fputs("\n", stderr);
2249 
2250   iterator=librdf_model_get_targets(model, n1, n2);
2251   if(!iterator) {
2252     fprintf(stderr, "%s: librdf_model_get_targets failed\n", program);
2253     status=1;
2254   }
2255 
2256   expected_count=2;
2257   for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2258     librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2259     fputs("  ", stderr);
2260     librdf_node_print(n, stderr);
2261     fputs("\n", stderr);
2262   }
2263   librdf_free_iterator(iterator);
2264   if(count != expected_count) {
2265     fprintf(stderr, "%s: librdf_model_get_targets returned %d nodes, expected %d\n", program, count, expected_count);
2266     status=1;
2267   }
2268   librdf_free_node(n1);
2269   librdf_free_node(n2);
2270 
2271 
2272   /* arcs */
2273   n1=librdf_new_node_from_uri_string(world, (const unsigned char*)"http://purl.org/net/dajobe/");
2274   n2=librdf_new_node_from_literal(world, (const unsigned char*)"Dave Beckett", NULL, 0);
2275 
2276   fprintf(stderr, "%s: Looking for arcs of source=", program);
2277   librdf_node_print(n1, stderr);
2278   fputs(" target=", stderr);
2279   librdf_node_print(n2, stderr);
2280   fputs("\n", stderr);
2281 
2282   iterator=librdf_model_get_arcs(model, n1, n2);
2283   if(!iterator) {
2284     fprintf(stderr, "%s: librdf_model_get_arcs failed\n", program);
2285     status=1;
2286   }
2287 
2288   expected_count=2;
2289   for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2290     librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2291     fputs("  ", stderr);
2292     librdf_node_print(n, stderr);
2293     fputs("\n", stderr);
2294   }
2295   librdf_free_iterator(iterator);
2296   if(count != expected_count) {
2297     fprintf(stderr, "%s: librdf_model_get_arcs returned %d nodes, expected %d\n", program, count, expected_count);
2298     status=1;
2299   }
2300   librdf_free_node(n1);
2301   librdf_free_node(n2);
2302 
2303 
2304   fprintf(stderr, "%s: Listing contexts\n", program);
2305   iterator=librdf_model_get_contexts(model);
2306   if(!iterator) {
2307     fprintf(stderr, "%s: librdf_model_get_contexts failed (optional method)\n", program);
2308   } else {
2309     expected_count=2;
2310     for(count=0; !librdf_iterator_end(iterator); librdf_iterator_next(iterator), count++) {
2311       librdf_node* n=(librdf_node*)librdf_iterator_get_object(iterator);
2312       fputs("  ", stderr);
2313       librdf_node_print(n, stderr);
2314       fputs("\n", stderr);
2315     }
2316     librdf_free_iterator(iterator);
2317     if(count != expected_count) {
2318       fprintf(stderr, "%s: librdf_model_get_contexts returned %d context nodes, expected %d\n", program, count, expected_count);
2319       status=1;
2320     }
2321   }
2322 
2323 #define TEST_CONTEXT_URI_INDEX 0
2324 
2325   if(librdf_model_contains_context(model, nodes[TEST_CONTEXT_URI_INDEX])) {
2326     fprintf(stderr, "%s: Model contains context %s\n", program,
2327             librdf_uri_as_string(uris[TEST_CONTEXT_URI_INDEX]));
2328   } else {
2329     fprintf(stderr, "%s: librdf_model_contains_contexts failed to find context URI %s\n",
2330             program, librdf_uri_as_string(uris[TEST_CONTEXT_URI_INDEX]));
2331     status=1;
2332   }
2333 
2334 
2335   for (i=0; i<URI_STRING_COUNT; i++) {
2336     fprintf(stderr, "%s: Removing statement context %s\n", program,
2337             librdf_uri_as_string(uris[i]));
2338     librdf_model_context_remove_statements(model, nodes[i]);
2339 
2340     fprintf(stderr, "%s: Printing model\n", program);
2341     librdf_model_write(model, iostr);
2342   }
2343 
2344   fprintf(stderr, "%s: Serializing model\n", program);
2345   base_uri=librdf_new_uri(world, (const unsigned char*)"http://example.org/base#");
2346   string=librdf_model_to_counted_string(model, base_uri,
2347                                         "rdfxml",
2348                                         NULL, NULL,
2349                                         &string_length);
2350   if(string_length != EXPECTED_BAD_STRING_LENGTH) {
2351     fprintf(stderr, "%s: Serialising to RDF/XML returned string size %d, expected %d\n", program,
2352             (int)string_length, EXPECTED_BAD_STRING_LENGTH);
2353     return 1;
2354   }
2355   librdf_free_uri(base_uri);
2356   librdf_free_memory(string);
2357   fprintf(stderr, "%s: Serialized OK\n", program);
2358 
2359   fprintf(stderr, "%s: Freeing URIs and Nodes\n", program);
2360   for (i=0; i<URI_STRING_COUNT; i++) {
2361     librdf_free_uri(uris[i]);
2362     librdf_free_node(nodes[i]);
2363   }
2364 
2365 done:
2366   fprintf(stderr, "%s: Freeing model\n", program);
2367   librdf_free_model(model);
2368 
2369   fprintf(stderr, "%s: Freeing storage\n", program);
2370   librdf_free_storage(storage);
2371 
2372   raptor_free_iostream(iostr);
2373 
2374   return status;
2375 }
2376 
2377 int
test_model_cloning(char const * program,librdf_world * world)2378 test_model_cloning(char const *program, librdf_world *world)
2379 {
2380   int status = 0;
2381   librdf_storage *storage1 = NULL;
2382   librdf_storage *storage2 = NULL;
2383   librdf_storage *storage3 = NULL;
2384   librdf_model *model1 = NULL;
2385   librdf_model *model2 = NULL;
2386   librdf_model *model3 = NULL;
2387   const char* storage_type;
2388   const char* storage_name;
2389   const char* storage_options;
2390 
2391   fprintf(stderr, "%s: Testing model cloning\n", program);
2392 
2393   /* Get storage configuration */
2394   storage_type = getenv("REDLAND_TEST_CLONING_STORAGE_TYPE");
2395   storage_name = getenv("REDLAND_TEST_CLONING_STORAGE_NAME");
2396   storage_options = getenv("REDLAND_TEST_CLONING_STORAGE_OPTIONS");
2397 
2398   if(!(storage_type && storage_name && storage_options)) {
2399     /* default is to test bdb disk hashes for cloning */
2400     storage_type="hashes";
2401     storage_name="test";
2402 #ifdef HAVE_BDB_HASH
2403     storage_options = "hash-type='bdb',dir='.',write='yes',new='yes',contexts='yes'";
2404 #else
2405     storage_options = "hash-type='memory',write='yes',new='yes',contexts='yes'";
2406 #endif
2407   }
2408 
2409   fprintf(stderr, "%s: Creating new %s storage\n", program, storage_type);
2410   storage1 = librdf_new_storage(world, storage_type, storage_name, storage_options);
2411   if(!storage1) {
2412     fprintf(stderr, "%s: Failed to create new %s storage name %s with options %s\n", program, storage_type, storage_name, storage_options);
2413     return 1;
2414   }
2415 
2416   fprintf(stderr, "%s: Creating new model for cloning\n", program);
2417   model1 = librdf_new_model(world, storage1, NULL);
2418   if(!model1) {
2419     fprintf(stderr, "%s: Failed to create new model\n", program);
2420     status = 1;
2421     goto tidy;
2422   }
2423 
2424   fprintf(stderr, "%s: Cloning model\n", program);
2425   model2 = librdf_new_model_from_model(model1);
2426   if(!model2) {
2427     fprintf(stderr, "%s: Failed to clone model\n", program);
2428     status = 1;
2429     goto tidy;
2430   }
2431   storage2 = librdf_model_get_storage(model2);
2432 
2433   /* Free original model now so we can test whether the clone is self-sufficient */
2434   fprintf(stderr, "%s: Freeing original model\n", program);
2435   librdf_free_model(model1); model1 = NULL;
2436 
2437   fprintf(stderr, "%s: Cloning cloned model\n", program);
2438   model3 = librdf_new_model_from_model(model2);
2439   if(!model3) {
2440     fprintf(stderr, "%s: Failed to clone cloned model\n", program);
2441     status = 1;
2442     goto tidy;
2443   }
2444   storage3 = librdf_model_get_storage(model3);
2445 
2446   tidy:
2447   fprintf(stderr, "%s: Freeing models\n", program);
2448   if(model3)
2449     librdf_free_model(model3);
2450   if(model2)
2451     librdf_free_model(model2);
2452   if(model1)
2453     librdf_free_model(model1);
2454 
2455   fprintf(stderr, "%s: Freeing %s storages\n", program, storage_type);
2456   if(storage3)
2457     librdf_free_storage(storage3);
2458   if(storage2)
2459     librdf_free_storage(storage2);
2460   librdf_free_storage(storage1);
2461 
2462   return status;
2463 }
2464 
2465 #endif
2466 
2467