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 © 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