1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rdf_storage_tstore.c - RDF Storage using 3store
4  *
5  * Copyright (C) 2003-2008, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2003-2004, 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>
38 #endif
39 #include <sys/types.h>
40 
41 #include <redland.h>
42 
43 #include <rdfsql/rdfsql.h>
44 
45 typedef struct
46 {
47   /* Tstore args for connecting */
48   const char *host;
49   const char *db;
50   const char *user;
51   const char *password;
52   const char *model;
53 
54   RDFSQL* rdfsql;
55 
56 } librdf_storage_tstore_instance;
57 
58 
59 /* prototypes for local functions */
60 static int librdf_storage_tstore_init(librdf_storage* storage, const char *name, librdf_hash* options);
61 static int librdf_storage_tstore_open(librdf_storage* storage, librdf_model* model);
62 static int librdf_storage_tstore_close(librdf_storage* storage);
63 static int librdf_storage_tstore_size(librdf_storage* storage);
64 static int librdf_storage_tstore_add_statement(librdf_storage* storage, librdf_statement* statement);
65 static int librdf_storage_tstore_remove_statement(librdf_storage* storage, librdf_statement* statement);
66 static int librdf_storage_tstore_contains_statement(librdf_storage* storage, librdf_statement* statement);
67 static librdf_stream* librdf_storage_tstore_serialise(librdf_storage* storage);
68 static librdf_stream* librdf_storage_tstore_find_statements(librdf_storage* storage, librdf_statement* statement);
69 
70 /* serialising implementing functions */
71 static int librdf_storage_tstore_serialise_end_of_stream(void* context);
72 static int librdf_storage_tstore_serialise_next_statement(void* context);
73 static void* librdf_storage_tstore_serialise_get_statement(void* context, int flags);
74 static void librdf_storage_tstore_serialise_finished(void* context);
75 
76 /* find implementing functions */
77 static int librdf_storage_tstore_find_end_of_stream(void* context);
78 static int librdf_storage_tstore_find_next_statement(void* context);
79 static void* librdf_storage_tstore_find_get_statement(void* context, int flags);
80 static void librdf_storage_tstore_find_finished(void* context);
81 
82 
83 /* context functions */
84 static int librdf_storage_tstore_context_add_statement(librdf_storage* storage, librdf_node* context_node, librdf_statement* statement);
85 static int librdf_storage_tstore_context_remove_statement(librdf_storage* storage, librdf_node* context_node, librdf_statement* statement);
86 static librdf_stream* librdf_storage_tstore_context_serialise(librdf_storage* storage, librdf_node* context_node);
87 
88 /* context list statement stream methods */
89 #if 0
90 static int librdf_storage_tstore_context_serialise_end_of_stream(void* context);
91 static int librdf_storage_tstore_context_serialise_next_statement(void* context);
92 static void* librdf_storage_tstore_context_serialise_get_statement(void* context, int flags);
93 static void librdf_storage_tstore_context_serialise_finished(void* context);
94 #endif
95 
96 static librdf_statement* librdf_storage_tstore_statement_from_rs_triple(librdf_world* world, rs_triple *triple);
97 static rs_triple* librdf_storage_tstore_statement_as_rs_triple(librdf_statement *statement);
98 
99 static void librdf_storage_tstore_register_factory(librdf_storage_factory *factory);
100 #ifdef MODULAR_LIBRDF
101 void librdf_storage_module_register_factory(librdf_world *world);
102 #endif
103 
104 
105 /* functions implementing storage api */
106 static int
librdf_storage_tstore_init(librdf_storage * storage,const char * name,librdf_hash * options)107 librdf_storage_tstore_init(librdf_storage* storage, const char *name,
108                            librdf_hash* options)
109 {
110   librdf_storage_tstore_instance* context;
111 
112   context = LIBRDF_CALLOC(librdf_storage_tstore_instance*, 1, sizeof(*context));
113   if(!context) {
114     if(options)
115       librdf_free_hash(options);
116     return 1;
117   }
118 
119   librdf_storage_set_instance(storage, context);
120 
121   context->host=librdf_hash_get_del(options, "host");
122   context->db=librdf_hash_get_del(options, "database");
123   context->user=librdf_hash_get_del(options, "user");
124   context->password=librdf_hash_get_del(options, "password");
125   context->model=librdf_hash_get_del(options, "model");
126 
127   /* no more options, might as well free them now */
128   if(options)
129     librdf_free_hash(options);
130 
131   return 0;
132 }
133 
134 
135 static void
librdf_storage_tstore_terminate(librdf_storage * storage)136 librdf_storage_tstore_terminate(librdf_storage* storage)
137 {
138   librdf_storage_tstore_instance *context;
139 
140   context =(librdf_storage_tstore_instance*)storage->instance;
141   if(context == NULL)
142     return;
143 
144   LIBRDF_FREE(librdf_storage_tstore_instance*, context);
145 }
146 
147 
148 
149 static int
librdf_storage_tstore_open(librdf_storage * storage,librdf_model * model)150 librdf_storage_tstore_open(librdf_storage* storage, librdf_model* model)
151 {
152   librdf_storage_tstore_instance *context;
153 
154   context = (librdf_storage_tstore_instance*)storage->instance;
155 
156   if(context->host)
157     context->rdfsql=rs_connect_remote(context->host,
158                                       context->db, context->user,
159                                       context->password, context->model);
160   else
161     context->rdfsql=rs_connect(context->db, context->user,
162                                context->password, context->model);
163   if(!context->rdfsql)
164     return 1;
165 
166   return 0;
167 }
168 
169 
170 /**
171  * librdf_storage_tstore_close:
172  * @storage: the storage
173  *
174  * .
175  *
176  * Close the storage list storage, and free all content since there is no
177  * persistance.
178  *
179  * Return value: non 0 on failure
180  **/
181 static int
librdf_storage_tstore_close(librdf_storage * storage)182 librdf_storage_tstore_close(librdf_storage* storage)
183 {
184   /* librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance; */
185 
186   return 0;
187 }
188 
189 
190 static int
librdf_storage_tstore_size(librdf_storage * storage)191 librdf_storage_tstore_size(librdf_storage* storage)
192 {
193   return -1;
194 }
195 
196 
197 static int
librdf_storage_tstore_add_statement(librdf_storage * storage,librdf_statement * statement)198 librdf_storage_tstore_add_statement(librdf_storage* storage, librdf_statement* statement)
199 {
200   /* FIXME - cannot check for adding duplicate statements */
201 
202   return librdf_storage_tstore_context_add_statement(storage, NULL, statement);
203 }
204 
205 
206 
207 static int
librdf_storage_tstore_remove_statement(librdf_storage * storage,librdf_statement * statement)208 librdf_storage_tstore_remove_statement(librdf_storage* storage, librdf_statement* statement)
209 {
210   return librdf_storage_tstore_context_remove_statement(storage, NULL, statement);
211 }
212 
213 
214 static int
librdf_storage_tstore_contains_statement(librdf_storage * storage,librdf_statement * statement)215 librdf_storage_tstore_contains_statement(librdf_storage* storage, librdf_statement* statement)
216 {
217   /*librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance; */
218   /* FIXME */
219   return 0;
220 }
221 
222 
223 static librdf_statement*
librdf_storage_tstore_statement_from_rs_triple(librdf_world * world,rs_triple * triple)224 librdf_storage_tstore_statement_from_rs_triple(librdf_world* world,
225                                                rs_triple *triple)
226 {
227   librdf_node *subject_node;
228   librdf_node *predicate_node;
229   librdf_node *object_node;
230 
231   if(triple->subject) {
232     if(!strncmp(triple->subject, "_:",2))
233       subject_node=librdf_new_node_from_blank_identifier(world,
234                                                          (const unsigned char *)triple->subject+2);
235     else
236       subject_node=librdf_new_node_from_uri_string(world,
237                                                    (const unsigned char *)triple->subject);
238 
239     if(!subject_node)
240       return NULL;
241 
242   } else
243     subject_node=NULL;
244 
245   if(triple->predicate) {
246     predicate_node=librdf_new_node_from_uri_string(world,
247                                                    (const unsigned char *)triple->predicate);
248 
249     if(!predicate_node) {
250       librdf_free_node(subject_node);
251       return NULL;
252     }
253   } else
254     predicate_node=NULL;
255 
256   if(triple->object) {
257     if(triple->literal)
258       object_node=librdf_new_node_from_typed_literal(world,
259                                                      (const unsigned char *)triple->object,
260                                                      NULL, NULL);
261     else if(!strncmp(triple->object, ":", 2))
262       object_node=librdf_new_node_from_blank_identifier(world,
263                                                         (const unsigned char *)triple->object+2);
264     else
265       object_node=librdf_new_node_from_uri_string(world,
266                                                   (const unsigned char *)triple->object);
267 
268     if(!object_node) {
269       librdf_free_node(subject_node);
270       librdf_free_node(predicate_node);
271       return NULL;
272     }
273   } else
274     object_node=NULL;
275 
276   return librdf_new_statement_from_nodes(world, subject_node, predicate_node, object_node);
277 }
278 
279 
280 /* FIXME returns an alloced triple pointing to shared strings */
281 static rs_triple*
librdf_storage_tstore_statement_as_rs_triple(librdf_statement * statement)282 librdf_storage_tstore_statement_as_rs_triple(librdf_statement *statement)
283 {
284   librdf_node *subject_node=statement->subject;
285   librdf_node *predicate_node=statement->predicate;
286   librdf_node *object_node=statement->object;
287   rs_triple* triple = LIBRDF_MALLOC(rs_triple, sizeof(*triple));
288 
289   if(subject_node) {
290     if(librdf_node_is_blank(subject_node))
291       triple->subject=(char*)librdf_node_get_blank_identifier(subject_node);
292     else
293       triple->subject=(char*)librdf_uri_as_string(librdf_node_get_uri(subject_node));
294   } else
295     triple->subject=NULL;
296 
297   if(predicate_node)
298     triple->predicate=(char*)librdf_uri_as_string(librdf_node_get_uri(predicate_node));
299   else
300     triple->predicate=NULL;
301 
302   /* Assumptions - FIXME */
303   triple->literal = 0;
304   if(object_node) {
305     if(librdf_node_is_literal(object_node)) {
306       triple->object=(char*)librdf_node_get_literal_value(object_node);
307       triple->literal = 1;
308     } else if(librdf_node_is_blank(object_node)) {
309       triple->object=(char*)librdf_node_get_blank_identifier(object_node);
310     } else {
311       triple->object=(char*)librdf_uri_as_string(librdf_node_get_uri(object_node));
312     }
313   } else
314     triple->object=NULL;
315 
316   return triple;
317 }
318 
319 
320 typedef struct {
321   librdf_storage* storage;
322   rs_result *result;
323   rs_triple *triple;
324 } librdf_storage_tstore_serialise_stream_context;
325 
326 
327 static librdf_stream*
librdf_storage_tstore_serialise(librdf_storage * storage)328 librdf_storage_tstore_serialise(librdf_storage* storage)
329 {
330   librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance;
331   librdf_storage_tstore_serialise_stream_context* scontext;
332   librdf_stream* stream;
333 
334   scontext = LIBRDF_CALLOC(librdf_storage_tstore_serialise_stream_context*, 1, sizeof(*scontext));
335   if(!scontext)
336     return NULL;
337 
338   scontext->storage=storage;
339   librdf_storage_add_reference(scontext->storage);
340 
341   scontext->result=rs_find_all_resources(context->rdfsql, 0, context->model);
342   if(!scontext->result)
343     /* empty */
344     scontext->triple=NULL;
345   else
346     scontext->triple=rs_next_triple(scontext->result);
347 
348   stream=librdf_new_stream(storage->world,
349                            (void*)scontext,
350                            &librdf_storage_tstore_serialise_end_of_stream,
351                            &librdf_storage_tstore_serialise_next_statement,
352                            &librdf_storage_tstore_serialise_get_statement,
353                            &librdf_storage_tstore_serialise_finished);
354   if(!stream) {
355     librdf_storage_tstore_serialise_finished((void*)scontext);
356     return NULL;
357   }
358 
359   return stream;
360 }
361 
362 
363 static int
librdf_storage_tstore_serialise_end_of_stream(void * context)364 librdf_storage_tstore_serialise_end_of_stream(void* context)
365 {
366   librdf_storage_tstore_serialise_stream_context* scontext=(librdf_storage_tstore_serialise_stream_context*)context;
367 
368   return scontext->triple == NULL;
369 
370 }
371 
372 static int
librdf_storage_tstore_serialise_next_statement(void * context)373 librdf_storage_tstore_serialise_next_statement(void* context)
374 {
375   librdf_storage_tstore_serialise_stream_context* scontext=(librdf_storage_tstore_serialise_stream_context*)context;
376 
377   if(!scontext->triple)
378     return 1;
379 
380   scontext->triple=rs_next_triple(scontext->result);
381 
382   return scontext->triple == NULL;
383 }
384 
385 
386 static void*
librdf_storage_tstore_serialise_get_statement(void * context,int flags)387 librdf_storage_tstore_serialise_get_statement(void* context, int flags)
388 {
389   librdf_storage_tstore_serialise_stream_context* scontext=(librdf_storage_tstore_serialise_stream_context*)context;
390 
391   switch(flags) {
392     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
393       {
394         librdf_statement* statement=librdf_storage_tstore_statement_from_rs_triple(scontext->storage->world, scontext->triple);
395         return statement;
396       }
397     case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
398       return NULL;
399     default:
400       librdf_log(scontext->storage->world,
401                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
402                  "Unknown iterator method flag %d", flags);
403       return NULL;
404   }
405 }
406 
407 
408 static void
librdf_storage_tstore_serialise_finished(void * context)409 librdf_storage_tstore_serialise_finished(void* context)
410 {
411   librdf_storage_tstore_serialise_stream_context* scontext=(librdf_storage_tstore_serialise_stream_context*)context;
412 
413   if(scontext->triple) {
414     /* The docs say about rs_find_triples:[[
415      *   NB Once rs_find_triples has been called, all the triples
416      *   /must/ be fetched with rs_next_triple(), even if they are
417      *   not required.
418      * ]]
419      * but let's assume it applies to rs_find_all_resources
420      */
421     while(rs_next_triple(scontext->result))
422       ;
423   }
424 
425   if(scontext->result)
426     rs_free_result(scontext->result);
427 
428   if(scontext->storage)
429     librdf_storage_remove_reference(scontext->storage);
430 
431   LIBRDF_FREE(librdf_storage_tstore_serialise_stream_context*, scontext);
432 }
433 
434 
435 typedef struct {
436   librdf_storage* storage;
437   rs_result *result;
438   rs_triple *triple;
439   rs_triple *search_triple;
440 } librdf_storage_tstore_find_stream_context;
441 
442 
443 /**
444  * librdf_storage_tstore_find_statements:
445  * @storage: the storage
446  * @statement: the statement to match
447  *
448  * .
449  *
450  * Return a stream of statements matching the given statement (or
451  * all statements if NULL).  Parts (subject, predicate, object) of the
452  * statement can be empty in which case any statement part will match that.
453  * Uses #librdf_statement_match to do the matching.
454  *
455  * Return value: a #librdf_stream or NULL on failure
456  **/
457 static librdf_stream*
librdf_storage_tstore_find_statements(librdf_storage * storage,librdf_statement * statement)458 librdf_storage_tstore_find_statements(librdf_storage* storage, librdf_statement* statement)
459 {
460   librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance;
461   librdf_storage_tstore_find_stream_context* scontext;
462   librdf_stream* stream;
463   rs_triple* triple;
464   rs_obj_type type;
465 
466   statement=librdf_new_statement_from_statement(statement);
467   if(!statement)
468     return NULL;
469 
470   scontext = LIBRDF_CALLOC(librdf_storage_tstore_find_stream_context*, 1,
471                            sizeof(*scontext));
472   if(!scontext)
473     return NULL;
474 
475   scontext->storage=storage;
476   librdf_storage_add_reference(scontext->storage);
477 
478   triple=librdf_storage_tstore_statement_as_rs_triple(statement);
479   scontext->search_triple=triple;
480 
481   if(triple->object)
482     type=(triple->literal ? ObjLiteral: ObjURI);
483   else
484     type=ObjAny;
485 
486   scontext->result=rs_find_triples(context->rdfsql,
487                                    triple->subject,
488                                    triple->predicate,
489                                    triple->object,
490                                    type,
491                                    0,
492                                    context->model);
493   if(!scontext->result)
494     /* empty */
495     scontext->triple=NULL;
496   else
497     scontext->triple=rs_next_triple(scontext->result);
498 
499   stream=librdf_new_stream(storage->world,
500                            (void*)scontext,
501                            &librdf_storage_tstore_find_end_of_stream,
502                            &librdf_storage_tstore_find_next_statement,
503                            &librdf_storage_tstore_find_get_statement,
504                            &librdf_storage_tstore_find_finished);
505   if(!stream) {
506     librdf_storage_tstore_find_finished((void*)scontext);
507     return NULL;
508   }
509 
510   return stream;
511 
512 }
513 
514 
515 static int
librdf_storage_tstore_find_end_of_stream(void * context)516 librdf_storage_tstore_find_end_of_stream(void* context)
517 {
518   librdf_storage_tstore_find_stream_context* scontext=(librdf_storage_tstore_find_stream_context*)context;
519 
520   return scontext->triple == NULL;
521 
522 }
523 
524 static int
librdf_storage_tstore_find_next_statement(void * context)525 librdf_storage_tstore_find_next_statement(void* context)
526 {
527   librdf_storage_tstore_find_stream_context* scontext=(librdf_storage_tstore_find_stream_context*)context;
528 
529   if(!scontext->triple)
530     return 1;
531 
532   scontext->triple=rs_next_triple(scontext->result);
533 
534   return scontext->triple == NULL;
535 }
536 
537 
538 static void*
librdf_storage_tstore_find_get_statement(void * context,int flags)539 librdf_storage_tstore_find_get_statement(void* context, int flags)
540 {
541   librdf_storage_tstore_find_stream_context* scontext=(librdf_storage_tstore_find_stream_context*)context;
542 
543   switch(flags) {
544     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
545       {
546         librdf_statement* statement=librdf_storage_tstore_statement_from_rs_triple(scontext->storage->world, scontext->triple);
547         return statement;
548       }
549     case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
550       return NULL;
551     default:
552       librdf_log(scontext->storage->world,
553                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
554                  "Unknown iterator method flag %d", flags);
555       return NULL;
556   }
557 }
558 
559 
560 static void
librdf_storage_tstore_find_finished(void * context)561 librdf_storage_tstore_find_finished(void* context)
562 {
563   librdf_storage_tstore_find_stream_context* scontext=(librdf_storage_tstore_find_stream_context*)context;
564 
565   if(scontext->triple) {
566     /* The docs say about rs_find_triples:[[
567      *   NB Once rs_find_triples has been called, all the triples
568      *   /must/ be fetched with rs_next_triple(), even if they are
569      *   not required.
570      * ]]
571      */
572     while(rs_next_triple(scontext->result))
573       ;
574   }
575 
576   if(scontext->result)
577     rs_free_result(scontext->result);
578 
579 
580   /* FIXME: as alloced in librdf_storage_tstore_statement_as_rs_triple */
581   if(scontext->search_triple)
582     LIBRDF_FREE(rs_triple*, scontext->search_triple);
583 
584   if(scontext->storage)
585     librdf_storage_remove_reference(scontext->storage);
586 
587   LIBRDF_FREE(librdf_storage_tstore_find_stream_context*, scontext);
588 }
589 
590 /**
591  * librdf_storage_tstore_context_add_statement:
592  * @storage: #librdf_storage object
593  * @context_node: #librdf_node object
594  * @statement: #librdf_statement statement to add
595  *
596  * Add a statement to a storage context.
597  *
598  * Return value: non 0 on failure
599  **/
600 static int
librdf_storage_tstore_context_add_statement(librdf_storage * storage,librdf_node * context_node,librdf_statement * statement)601 librdf_storage_tstore_context_add_statement(librdf_storage* storage,
602                                             librdf_node* context_node,
603                                             librdf_statement* statement)
604 {
605   librdf_storage_tstore_instance* context;
606   librdf_node *subject_node=statement->subject;
607   librdf_node *predicate_node=statement->predicate;
608   librdf_node *object_node=statement->object;
609   char *subject;
610   char *predicate;
611   char *object;
612   rs_obj_type type;
613 
614   context = (librdf_storage_tstore_instance*)storage->instance;
615 
616   if(librdf_node_is_blank(subject_node)) {
617     subject=(char*)librdf_node_get_blank_identifier(subject_node);
618   } else
619     subject=(char*)librdf_uri_as_string(librdf_node_get_uri(subject_node));
620 
621 
622   predicate=(char*)librdf_uri_as_string(librdf_node_get_uri(predicate_node));
623 
624   /* Assumptions - FIXME */
625   if(librdf_node_is_literal(object_node)) {
626     object=(char*)librdf_node_get_literal_value(object_node);
627     type = ObjLiteral;
628   } else if(librdf_node_is_blank(object_node)) {
629     object=(char*)librdf_node_get_blank_identifier(object_node);
630     type = ObjURI;
631   } else {
632     object=(char*)librdf_uri_as_string(librdf_node_get_uri(object_node));
633     type = ObjURI;
634   }
635 
636 
637   if(rs_assert_triple(context->rdfsql, subject, predicate, object, type))
638     return 1;
639 
640   return 0;
641 }
642 
643 
644 /**
645  * librdf_storage_tstore_context_remove_statement:
646  * @storage: #librdf_storage object
647  * @context_node: #librdf_node object
648  * @statement: #librdf_statement statement to remove
649  *
650  * Remove a statement from a storage context.
651  *
652  * Return value: non 0 on failure
653  **/
654 static int
librdf_storage_tstore_context_remove_statement(librdf_storage * storage,librdf_node * context_node,librdf_statement * statement)655 librdf_storage_tstore_context_remove_statement(librdf_storage* storage,
656                                              librdf_node* context_node,
657                                              librdf_statement* statement)
658 {
659   /* librdf_storage_tstore_instance* context=(librdf_storage_tstore_instance*)storage->instance; */
660 
661   /* FIXME */
662 
663   return 0;
664 }
665 
666 
667 typedef struct {
668   librdf_iterator* iterator;
669   librdf_hash_datum *key;
670   librdf_hash_datum *value;
671   librdf_statement current; /* static, shared statement */
672 } librdf_storage_tstore_context_serialise_stream_context;
673 
674 
675 /**
676  * librdf_storage_tstore_context_serialise:
677  * @storage: #librdf_storage object
678  * @context_node: #librdf_node object
679  *
680  * List all statements in a storage context.
681  *
682  * Return value: #librdf_stream of statements or NULL on failure or context is empty
683  **/
684 static librdf_stream*
librdf_storage_tstore_context_serialise(librdf_storage * storage,librdf_node * context_node)685 librdf_storage_tstore_context_serialise(librdf_storage* storage,
686                                       librdf_node* context_node)
687 {
688   return NULL;
689 }
690 
691 
692 #if 0
693 static int
694 librdf_storage_tstore_context_serialise_end_of_stream(void* context)
695 {
696   /* librdf_storage_tstore_context_serialise_stream_context* scontext=(librdf_storage_tstore_context_serialise_stream_context*)context; */
697 
698   return 1;
699 }
700 
701 
702 static int
703 librdf_storage_tstore_context_serialise_next_statement(void* context)
704 {
705   /* librdf_storage_tstore_context_serialise_stream_context* scontext=(librdf_storage_tstore_context_serialise_stream_context*)context; */
706 
707   return 1;
708 }
709 
710 
711 static void*
712 librdf_storage_tstore_context_serialise_get_statement(void* context, int flags)
713 {
714   /* librdf_storage_tstore_context_serialise_stream_context* scontext=(librdf_storage_tstore_context_serialise_stream_context*)context; */
715 
716   return NULL;
717 }
718 
719 
720 static void
721 librdf_storage_tstore_context_serialise_finished(void* context)
722 {
723   librdf_storage_tstore_context_serialise_stream_context* scontext;
724 
725   scontext = (librdf_storage_tstore_context_serialise_stream_context*)context;
726 
727   LIBRDF_FREE(librdf_storage_tstore_context_serialise_stream_context*, scontext);
728 }
729 #endif
730 
731 
732 /** Local entry point for dynamically loaded storage module */
733 static void
librdf_storage_register_factory(librdf_storage_factory * factory)734 librdf_storage_register_factory(librdf_storage_factory *factory)
735 {
736   assert(factory->name    == "tstore");
737 
738   factory->version            = LIBRDF_STORAGE_INTERFACE_VERSION;
739   factory->init               = librdf_storage_tstore_init;
740   factory->terminate          = librdf_storage_tstore_terminate;
741   factory->open               = librdf_storage_tstore_open;
742   factory->close              = librdf_storage_tstore_close;
743   factory->size               = librdf_storage_tstore_size;
744   factory->add_statement      = librdf_storage_tstore_add_statement;
745   factory->remove_statement   = librdf_storage_tstore_remove_statement;
746   factory->contains_statement = librdf_storage_tstore_contains_statement;
747   factory->serialise          = librdf_storage_tstore_serialise;
748   factory->find_statements    = librdf_storage_tstore_find_statements;
749   factory->context_add_statement    = librdf_storage_tstore_context_add_statement;
750   factory->context_remove_statement = librdf_storage_tstore_context_remove_statement;
751   factory->context_serialise        = librdf_storage_tstore_context_serialise;
752 }
753 
754 #ifdef MODULAR_LIBRDF
755 
756 /** Entry point for dynamically loaded storage module */
757 static void
librdf_storage_module_register_factory(librdf_world * world)758 librdf_storage_module_register_factory(librdf_world *world)
759 {
760   librdf_storage_register_factory(world, "tstore", "AKT triplestore",
761                                   &librdf_storage_tstore_register_factory);
762 }
763 
764 #else
765 
766 /*
767  * librdf_init_storage_tstore:
768  * @world: world object
769  *
770  * INTERNAL - Initialise the built-in storage_tstore module.
771  */
772 void
librdf_init_storage_tstore(librdf_world * world)773 librdf_init_storage_tstore(librdf_world *world)
774 {
775   librdf_storage_register_factory(world, "tstore", "AKT triplestore",
776                                   &librdf_storage_tstore_register_factory);
777 }
778 
779 #endif
780 
781