1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * rdf_storage_sqlite.c - RDF Storage using SQLite implementation
4  *
5  * Copyright (C) 2004-2010, David Beckett http://www.dajobe.org/
6  * Copyright (C) 2004-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>
38 #endif
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #include <sys/types.h>
43 
44 #include <sqlite3.h>
45 
46 #include <redland.h>
47 #include <rdf_storage.h>
48 
49 
50 static const char* const sqlite_synchronous_flags[4] = {
51   "off", "normal", "full", NULL
52 };
53 
54 typedef struct librdf_storage_sqlite_query librdf_storage_sqlite_query;
55 
56 struct librdf_storage_sqlite_query
57 {
58   unsigned char *query;
59   librdf_storage_sqlite_query *next;
60 };
61 
62 typedef struct
63 {
64   librdf_storage *storage;
65 
66   sqlite3 *db;
67 
68   int is_new;
69 
70   char *name;
71   size_t name_len;
72 
73   int synchronous; /* -1 (not set), 0+ index into sqlite_synchronous_flags */
74 
75   int in_stream;
76   librdf_storage_sqlite_query *in_stream_queries;
77 
78   int in_transaction;
79 } librdf_storage_sqlite_instance;
80 
81 
82 
83 /* prototypes for local functions */
84 static int librdf_storage_sqlite_init(librdf_storage* storage, const char *name, librdf_hash* options);
85 static int librdf_storage_sqlite_open(librdf_storage* storage, librdf_model* model);
86 static int librdf_storage_sqlite_close(librdf_storage* storage);
87 static int librdf_storage_sqlite_size(librdf_storage* storage);
88 static int librdf_storage_sqlite_add_statement(librdf_storage* storage, librdf_statement* statement);
89 static int librdf_storage_sqlite_add_statements(librdf_storage* storage, librdf_stream* statement_stream);
90 static int librdf_storage_sqlite_remove_statement(librdf_storage* storage, librdf_statement* statement);
91 static int librdf_storage_sqlite_contains_statement(librdf_storage* storage, librdf_statement* statement);
92 static librdf_stream* librdf_storage_sqlite_serialise(librdf_storage* storage);
93 static librdf_stream* librdf_storage_sqlite_find_statements(librdf_storage* storage, librdf_statement* statement);
94 
95 /* serialising implementing functions */
96 static int librdf_storage_sqlite_serialise_end_of_stream(void* context);
97 static int librdf_storage_sqlite_serialise_next_statement(void* context);
98 static void* librdf_storage_sqlite_serialise_get_statement(void* context, int flags);
99 static void librdf_storage_sqlite_serialise_finished(void* context);
100 
101 /* find_statements implementing functions */
102 static int librdf_storage_sqlite_find_statements_end_of_stream(void* context);
103 static int librdf_storage_sqlite_find_statements_next_statement(void* context);
104 static void* librdf_storage_sqlite_find_statements_get_statement(void* context, int flags);
105 static void librdf_storage_sqlite_find_statements_finished(void* context);
106 
107 /* context functions */
108 static int librdf_storage_sqlite_context_add_statement(librdf_storage* storage, librdf_node* context_node, librdf_statement* statement);
109 static int librdf_storage_sqlite_context_remove_statement(librdf_storage* storage, librdf_node* context_node, librdf_statement* statement);
110 static int librdf_storage_sqlite_context_contains_statement(librdf_storage* storage, librdf_node* context, librdf_statement* statement);
111 static librdf_stream* librdf_storage_sqlite_context_serialise(librdf_storage* storage, librdf_node* context_node);
112 
113 /* context sqlite statement stream methods */
114 static int librdf_storage_sqlite_context_serialise_end_of_stream(void* context);
115 static int librdf_storage_sqlite_context_serialise_next_statement(void* context);
116 static void* librdf_storage_sqlite_context_serialise_get_statement(void* context, int flags);
117 static void librdf_storage_sqlite_context_serialise_finished(void* context);
118 
119 /* helper functions for contexts */
120 
121 static librdf_iterator* librdf_storage_sqlite_get_contexts(librdf_storage* storage);
122 
123 /* get_context iterator functions */
124 static int librdf_storage_sqlite_get_contexts_is_end(void* iterator);
125 static int librdf_storage_sqlite_get_contexts_next_method(void* iterator);
126 static void* librdf_storage_sqlite_get_contexts_get_method(void* iterator, int);
127 static void librdf_storage_sqlite_get_contexts_finished(void* iterator);
128 
129 /* transactions */
130 static int librdf_storage_sqlite_transaction_start(librdf_storage *storage);
131 static int librdf_storage_sqlite_transaction_commit(librdf_storage *storage);
132 static int librdf_storage_sqlite_transaction_rollback(librdf_storage *storage);
133 
134 static void librdf_storage_sqlite_query_flush(librdf_storage *storage);
135 
136 static void librdf_storage_sqlite_register_factory(librdf_storage_factory *factory);
137 #ifdef MODULAR_LIBRDF
138 void librdf_storage_module_register_factory(librdf_world *world);
139 #endif
140 
141 
142 /* functions implementing storage api */
143 static int
librdf_storage_sqlite_init(librdf_storage * storage,const char * name,librdf_hash * options)144 librdf_storage_sqlite_init(librdf_storage* storage, const char *name,
145                            librdf_hash* options)
146 {
147   char *name_copy;
148   char* synchronous;
149   librdf_storage_sqlite_instance* context;
150 
151   if(!name) {
152     if(options)
153       librdf_free_hash(options);
154     return 1;
155   }
156 
157   context = LIBRDF_CALLOC(librdf_storage_sqlite_instance*, 1, sizeof(*context));
158   if(!context) {
159     if(options)
160       librdf_free_hash(options);
161     return 1;
162   }
163 
164   librdf_storage_set_instance(storage, context);
165 
166   context->storage = storage;
167 
168   context->name_len = strlen(name);
169   name_copy = LIBRDF_MALLOC(char*, context->name_len + 1);
170   if(!name_copy) {
171     if(options)
172       librdf_free_hash(options);
173     return 1;
174   }
175 
176   strncpy(name_copy, name, context->name_len + 1);
177   context->name = name_copy;
178 
179   if(librdf_hash_get_as_boolean(options, "new")>0)
180     context->is_new = 1; /* default is NOT NEW */
181 
182   /* Redland default is "PRAGMA synchronous normal" */
183   context->synchronous = 1;
184 
185   if((synchronous = librdf_hash_get(options, "synchronous"))) {
186     int i;
187 
188     for(i = 0; sqlite_synchronous_flags[i]; i++) {
189       if(!strcmp(synchronous, sqlite_synchronous_flags[i])) {
190         context->synchronous = i;
191         break;
192       }
193     }
194 
195     LIBRDF_FREE(char*, synchronous);
196 
197   }
198 
199 
200   /* no more options, might as well free them now */
201   if(options)
202     librdf_free_hash(options);
203 
204   return 0;
205 }
206 
207 
208 static void
librdf_storage_sqlite_terminate(librdf_storage * storage)209 librdf_storage_sqlite_terminate(librdf_storage* storage)
210 {
211   librdf_storage_sqlite_instance* context;
212 
213   context = (librdf_storage_sqlite_instance*)storage->instance;
214 
215   if (context == NULL)
216     return;
217 
218   if(context->name)
219     LIBRDF_FREE(char*, context->name);
220 
221   LIBRDF_FREE(librdf_storage_sqlite_terminate, storage->instance);
222 }
223 
224 
225 typedef struct
226 {
227   const char *name;
228   const char *schema;
229   const char *columns; /* Excluding key column, always called id */
230 } table_info;
231 
232 
233 #define NTABLES 4
234 
235 /*
236  * INTEGER PRIMARY KEY columns can be used to implement the
237  * equivalent of AUTOINCREMENT. If you try to insert a NULL into an
238  * INTEGER PRIMARY KEY column, the column will actually be filled
239  * with a integer that is one greater than the largest key already in
240  * the table. Or if the largest key is 2147483647, then the column
241  * will be filled with a random integer. Either way, the INTEGER
242  * PRIMARY KEY column will be assigned a unique integer. You can
243  * retrieve this integer using the sqlite3_last_insert_rowid() API
244  * function or using the last_insert_rowid() SQL function in a
245  * subsequent SELECT statement.
246  */
247 
248 typedef enum {
249   TABLE_URIS,
250   TABLE_BLANKS,
251   TABLE_LITERALS,
252   TABLE_TRIPLES
253 }  sqlite_table_numbers;
254 
255 static const table_info sqlite_tables[NTABLES]={
256   { "uris",     "id INTEGER PRIMARY KEY, uri TEXT", "uri" },
257   { "blanks",   "id INTEGER PRIMARY KEY, blank TEXT", "blank" },
258   { "literals", "id INTEGER PRIMARY KEY, text TEXT, language TEXT, datatype INTEGER", "text, language, datatype" },
259   { "triples",  "subjectUri INTEGER, subjectBlank INTEGER, predicateUri INTEGER, objectUri INTEGER, objectBlank INTEGER, objectLiteral INTEGER, contextUri INTEGER", "subjectUri, subjectBlank, predicateUri, objectUri, objectBlank, objectLiteral, contextUri"  },
260 };
261 
262 
263 typedef enum {
264   TRIPLE_SUBJECT  =0,
265   TRIPLE_PREDICATE=1,
266   TRIPLE_OBJECT   =2,
267   TRIPLE_CONTEXT  =3,
268 } triple_part;
269 
270 typedef enum {
271   TRIPLE_URI    =0,
272   TRIPLE_BLANK  =1,
273   TRIPLE_LITERAL=2,
274   TRIPLE_NONE   =3,
275 } triple_node_type;
276 
277 static const char * const triples_fields[4][3] = {
278   { "subjectUri",   "subjectBlank", NULL },
279   { "predicateUri", NULL,           NULL },
280   { "objectUri",    "objectBlank",  "objectLiteral" },
281   { "contextUri",   NULL,           NULL }
282 };
283 
284 
285 static int
librdf_storage_sqlite_get_1int_callback(void * arg,int argc,char ** argv,char ** columnNames)286 librdf_storage_sqlite_get_1int_callback(void *arg,
287                                         int argc, char **argv,
288                                         char **columnNames)
289 {
290   int* count_p = (int*)arg;
291 
292   if(argc == 1) {
293     *count_p = argv[0] ? atoi(argv[0]) : 0;
294   }
295   return 0;
296 }
297 
298 
299 static unsigned char *
sqlite_string_escape(const unsigned char * raw,size_t raw_len,size_t * len_p)300 sqlite_string_escape(const unsigned char *raw, size_t raw_len, size_t *len_p)
301 {
302   size_t escapes = 0;
303   unsigned char *p;
304   unsigned char *escaped;
305   size_t len;
306 
307   for(p = (unsigned char*)raw, len = raw_len; len > 0; p++, len--) {
308     if(*p == '\'')
309       escapes++;
310   }
311 
312   len = raw_len + escapes + 2; /* for '' */
313   escaped = LIBRDF_MALLOC(unsigned char*, len + 1);
314   if(!escaped)
315     return NULL;
316 
317   p = escaped;
318   *p++ = '\'';
319   while(raw_len > 0) {
320     if(*raw == '\'') {
321       *p++ = '\'';
322     }
323     *p++ = *raw++;
324     raw_len--;
325   }
326   *p++ = '\'';
327   *p = '\0';
328 
329   if(len_p)
330     *len_p = len;
331 
332   return escaped;
333 }
334 
335 
336 static int
librdf_storage_sqlite_exec(librdf_storage * storage,unsigned char * request,sqlite3_callback callback,void * arg,int fail_ok)337 librdf_storage_sqlite_exec(librdf_storage* storage,
338                            unsigned char *request,
339                            sqlite3_callback callback, void *arg,
340                            int fail_ok)
341 {
342   librdf_storage_sqlite_instance* context;
343   int status=SQLITE_OK;
344   char *errmsg = NULL;
345 
346   context = (librdf_storage_sqlite_instance*)storage->instance;
347 
348   /* sqlite crashes if passed in a NULL sql string */
349   if(!request)
350     return 1;
351 
352 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
353   LIBRDF_DEBUG2("SQLite exec '%s'\n", request);
354 #endif
355 
356   status = sqlite3_exec(context->db, (const char*)request, callback, arg,
357                        &errmsg);
358   if(fail_ok)
359     status = SQLITE_OK;
360 
361   if(status != SQLITE_OK) {
362     if(status == SQLITE_LOCKED && !callback && context->in_stream) {
363       librdf_storage_sqlite_query *query;
364       /* error message from sqlite3_exec needs to be freed on both sqlite 2 and 3 */
365       if(errmsg)
366         sqlite3_free(errmsg);
367 
368 
369       query = LIBRDF_CALLOC(librdf_storage_sqlite_query*, 1, sizeof(*query));
370       if(!query)
371         return 1;
372 
373       query->query = LIBRDF_MALLOC(unsigned char*, strlen((char *)request) + 1);
374       if(!query->query) {
375         LIBRDF_FREE(librdf_storage_sqlite_query, query);
376         return 1;
377       }
378 
379       strcpy((char*)query->query, (char *)request);
380 
381       if(!context->in_stream_queries)
382         context->in_stream_queries = query;
383       else {
384         librdf_storage_sqlite_query *q = context->in_stream_queries;
385 
386         while(q->next)
387           q = q->next;
388 
389         q->next = query;
390       }
391 
392       status = SQLITE_OK;
393 
394     } else {
395       librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
396                  "SQLite database %s SQL exec '%s' failed - %s (%d)",
397                  context->name, request, errmsg, status);
398       /* error message from sqlite3_exec needs to be freed on both sqlite 2 and 3 */
399       if(errmsg)
400         sqlite3_free(errmsg);
401     }
402   }
403 
404   return (status != SQLITE_OK);
405 }
406 
407 
408 static int
librdf_storage_sqlite_set_helper(librdf_storage * storage,int table,const unsigned char * values,size_t values_len)409 librdf_storage_sqlite_set_helper(librdf_storage *storage,
410                                  int table,
411                                  const unsigned char *values,
412                                  size_t values_len)
413 {
414   librdf_storage_sqlite_instance* context;
415   int rc;
416   raptor_stringbuffer *sb;
417   unsigned char *request;
418 
419   context = (librdf_storage_sqlite_instance*)storage->instance;
420 
421   sb = raptor_new_stringbuffer();
422   if(!sb)
423     return -1;
424 
425   raptor_stringbuffer_append_string(sb,
426                                     (const unsigned char*)"INSERT INTO ", 1);
427   raptor_stringbuffer_append_string(sb,
428                                     (const unsigned char*)sqlite_tables[table].name, 1);
429   raptor_stringbuffer_append_counted_string(sb,
430                                     (const unsigned char*)" (id, ", 6, 1);
431   raptor_stringbuffer_append_string(sb,
432                                     (const unsigned char*)sqlite_tables[table].columns, 1);
433   raptor_stringbuffer_append_counted_string(sb,
434                                             (const unsigned char*) ") VALUES(NULL, ", 15, 1);
435   raptor_stringbuffer_append_counted_string(sb, values, values_len, 1);
436   raptor_stringbuffer_append_counted_string(sb,
437                                             (const unsigned char*)");", 2, 1);
438   request=raptor_stringbuffer_as_string(sb);
439 
440   rc=librdf_storage_sqlite_exec(storage,
441                                 request,
442                                 NULL, /* no callback */
443                                 NULL, /* arg */
444                                 0);
445 
446   raptor_free_stringbuffer(sb);
447 
448   if(rc)
449     return -1;
450 
451   return LIBRDF_BAD_CAST(int, sqlite3_last_insert_rowid(context->db));
452 }
453 
454 
455 static int
librdf_storage_sqlite_get_helper(librdf_storage * storage,int table,const unsigned char * expression)456 librdf_storage_sqlite_get_helper(librdf_storage *storage,
457                                  int table,
458                                  const unsigned char *expression)
459 {
460   int id = -1;
461   int rc;
462   raptor_stringbuffer *sb;
463   unsigned char *request;
464 
465   sb = raptor_new_stringbuffer();
466   if(!sb)
467     return -1;
468 
469   raptor_stringbuffer_append_string(sb,
470                                     (const unsigned char*)"SELECT id FROM ", 1);
471   raptor_stringbuffer_append_string(sb,
472                                     (const unsigned char*)sqlite_tables[table].name, 1);
473   raptor_stringbuffer_append_counted_string(sb,
474                                             (const unsigned char*)" WHERE ", 7, 1);
475   raptor_stringbuffer_append_string(sb,
476                                     (const unsigned char*)expression, 1);
477   raptor_stringbuffer_append_counted_string(sb,
478                                             (const unsigned char*)";", 1, 1);
479   request=raptor_stringbuffer_as_string(sb);
480 
481   rc = librdf_storage_sqlite_exec(storage,
482                                   request,
483                                   librdf_storage_sqlite_get_1int_callback,
484                                   &id,
485                                   0);
486 
487   raptor_free_stringbuffer(sb);
488 
489   if(rc)
490     return -1;
491 
492   return id;
493 }
494 
495 
496 static int
librdf_storage_sqlite_uri_helper(librdf_storage * storage,librdf_uri * uri,int add_new)497 librdf_storage_sqlite_uri_helper(librdf_storage* storage,
498                                  librdf_uri* uri,
499                                  int add_new)
500 {
501   const unsigned char *uri_string;
502   size_t uri_len;
503   unsigned char *expression = NULL;
504   unsigned char *uri_e;
505   size_t uri_e_len;
506   int id = -1;
507   static const char * const field="uri";
508 
509   uri_string = librdf_uri_as_counted_string(uri, &uri_len);
510   uri_e = sqlite_string_escape(uri_string, uri_len, &uri_e_len);
511   if(!uri_e)
512     goto tidy;
513 
514   expression = LIBRDF_MALLOC(unsigned char*, strlen(field) + 3 + uri_e_len + 1);
515   if(!expression)
516     goto tidy;
517 
518   sprintf((char*)expression, "%s = %s", field, uri_e);
519   id = librdf_storage_sqlite_get_helper(storage, TABLE_URIS, expression);
520   if(id >= 0)
521     goto tidy;
522 
523   if(add_new)
524     id = librdf_storage_sqlite_set_helper(storage, TABLE_URIS, uri_e,
525                                           uri_e_len);
526 
527   tidy:
528   if(expression)
529     LIBRDF_FREE(char*, expression);
530   if(uri_e)
531     LIBRDF_FREE(char*, uri_e);
532 
533   return id;
534 }
535 
536 
537 static int
librdf_storage_sqlite_blank_helper(librdf_storage * storage,const unsigned char * blank,int add_new)538 librdf_storage_sqlite_blank_helper(librdf_storage* storage,
539                                    const unsigned char *blank,
540                                    int add_new)
541 {
542   size_t blank_len;
543   unsigned char *expression = NULL;
544   unsigned char *blank_e;
545   size_t blank_e_len;
546   int id = -1;
547   static const char * const field="blank";
548 
549   blank_len = strlen((const char*)blank);
550   blank_e = sqlite_string_escape(blank, blank_len, &blank_e_len);
551   if(!blank_e)
552     goto tidy;
553 
554   expression = LIBRDF_MALLOC(unsigned char*,
555                              strlen(field) + 3 + blank_e_len + 1);
556   if(!expression)
557     goto tidy;
558 
559   sprintf((char*)expression, "%s = %s", field, blank_e);
560   id = librdf_storage_sqlite_get_helper(storage, TABLE_BLANKS, expression);
561   if(id >= 0)
562     goto tidy;
563 
564   if(add_new)
565     id = librdf_storage_sqlite_set_helper(storage, TABLE_BLANKS, blank_e,
566                                           blank_e_len);
567 
568   tidy:
569   if(expression)
570     LIBRDF_FREE(char*, expression);
571   if(blank_e)
572     LIBRDF_FREE(char*, blank_e);
573 
574   return id;
575 }
576 
577 
578 static int
librdf_storage_sqlite_literal_helper(librdf_storage * storage,const unsigned char * value,size_t value_len,const char * language,librdf_uri * datatype,int add_new)579 librdf_storage_sqlite_literal_helper(librdf_storage* storage,
580                                      const unsigned char *value,
581                                      size_t value_len,
582                                      const char *language,
583                                      librdf_uri *datatype,
584                                      int add_new)
585 {
586   int id = -1;
587   size_t len;
588   unsigned char *value_e;
589   size_t value_e_len;
590   unsigned char *language_e = NULL;
591   size_t language_e_len = 0;
592   int datatype_id = -1;
593   raptor_stringbuffer *sb = NULL;
594   unsigned char *expression;
595 
596   value_e = sqlite_string_escape(value, value_len, &value_e_len);
597   if(!value_e)
598     goto tidy;
599 
600   sb = raptor_new_stringbuffer();
601   if(!sb)
602     goto tidy;
603 
604   raptor_stringbuffer_append_counted_string(sb,
605                                             (const unsigned char*)"text = ",
606                                             7, 1);
607   raptor_stringbuffer_append_counted_string(sb, value_e, value_e_len, 1);
608   raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)" ", 1, 1);
609 
610   if(language) {
611     len = strlen(language);
612     language_e = sqlite_string_escape((unsigned const char*)language, len,
613                                       &language_e_len);
614     if(!language_e)
615       goto tidy;
616 
617     raptor_stringbuffer_append_string(sb, (const unsigned char*)"AND language = ", 1);
618     raptor_stringbuffer_append_counted_string(sb, language_e, language_e_len, 1);
619   } else
620     raptor_stringbuffer_append_string(sb, (const unsigned char*)"AND language IS NULL ", 1);
621 
622   if(datatype) {
623     datatype_id = librdf_storage_sqlite_uri_helper(storage, datatype, add_new);
624     raptor_stringbuffer_append_string(sb, (const unsigned char*)"AND datatype = ", 1);
625     raptor_stringbuffer_append_decimal(sb, datatype_id);
626   } else
627     raptor_stringbuffer_append_string(sb, (const unsigned char*)"AND datatype IS NULL ", 1);
628 
629   expression = raptor_stringbuffer_as_string(sb);
630   id = librdf_storage_sqlite_get_helper(storage, TABLE_LITERALS, expression);
631 
632   if(id >= 0 || !add_new)
633     goto tidy;
634 
635   raptor_free_stringbuffer(sb);
636   sb = raptor_new_stringbuffer();
637   if(!sb) {
638     id = -1;
639     goto tidy;
640   }
641 
642   raptor_stringbuffer_append_counted_string(sb, value_e, value_e_len, 1);
643 
644   raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)", ", 2, 1);
645   if(language_e)
646     raptor_stringbuffer_append_counted_string(sb,language_e, language_e_len, 1);
647   else
648     raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)"NULL", 4, 1);
649 
650   raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)", ", 2, 1);
651   if(datatype)
652     raptor_stringbuffer_append_decimal(sb, datatype_id);
653   else
654     raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)"NULL", 4, 1);
655 
656   expression = raptor_stringbuffer_as_string(sb);
657   id = librdf_storage_sqlite_set_helper(storage, TABLE_LITERALS, expression,
658                                       raptor_stringbuffer_length(sb));
659 
660   tidy:
661   if(sb)
662     raptor_free_stringbuffer(sb);
663   if(value_e)
664     LIBRDF_FREE(char*, value_e);
665   if(language_e)
666     LIBRDF_FREE(char*, language_e);
667 
668   return id;
669 }
670 
671 
672 static int
librdf_storage_sqlite_node_helper(librdf_storage * storage,librdf_node * node,int * id_p,triple_node_type * node_type_p,int add_new)673 librdf_storage_sqlite_node_helper(librdf_storage* storage,
674                                   librdf_node* node,
675                                   int* id_p,
676                                   triple_node_type *node_type_p,
677                                   int add_new)
678 {
679   int id;
680   triple_node_type node_type;
681   unsigned char *value;
682   size_t value_len;
683 
684   if(!node)
685     return 1;
686 
687   switch(librdf_node_get_type(node)) {
688     case LIBRDF_NODE_TYPE_RESOURCE:
689       id = librdf_storage_sqlite_uri_helper(storage,
690                                             librdf_node_get_uri(node),
691                                             add_new);
692       if(id < 0 && add_new)
693         return 1;
694 
695       node_type = TRIPLE_URI;
696       break;
697 
698     case LIBRDF_NODE_TYPE_LITERAL:
699       value = librdf_node_get_literal_value_as_counted_string(node, &value_len);
700       id = librdf_storage_sqlite_literal_helper(storage,
701                                                 value, value_len,
702                                                 librdf_node_get_literal_value_language(node),
703                                                 librdf_node_get_literal_value_datatype_uri(node),
704                                                 add_new);
705       if(id < 0 && add_new)
706         return 1;
707 
708       node_type = TRIPLE_LITERAL;
709       break;
710 
711     case LIBRDF_NODE_TYPE_BLANK:
712       id = librdf_storage_sqlite_blank_helper(storage,
713                                               librdf_node_get_blank_identifier(node),
714                                               add_new);
715       if(id < 0 && add_new)
716         return 1;
717 
718       node_type = TRIPLE_BLANK;
719       break;
720 
721     case LIBRDF_NODE_TYPE_UNKNOWN:
722     default:
723       librdf_log(storage->world,
724                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
725                  "Do not know how to store node type %d", node->type);
726     return 1;
727   }
728 
729   if(id_p)
730     *id_p = id;
731   if(node_type_p)
732     *node_type_p = node_type;
733 
734   return 0;
735 }
736 
737 
738 
739 static int
librdf_storage_sqlite_statement_helper(librdf_storage * storage,librdf_statement * statement,librdf_node * context_node,triple_node_type node_types[4],int node_ids[4],const unsigned char * fields[4],int add_new)740 librdf_storage_sqlite_statement_helper(librdf_storage* storage,
741                                        librdf_statement* statement,
742                                        librdf_node* context_node,
743                                        triple_node_type node_types[4],
744                                        int node_ids[4],
745                                        const unsigned char* fields[4],
746                                        int add_new)
747 {
748   librdf_node* nodes[4];
749   int i;
750 
751   nodes[0] = statement ? librdf_statement_get_subject(statement) : NULL;
752   nodes[1] = statement ? librdf_statement_get_predicate(statement) : NULL;
753   nodes[2] = statement ? librdf_statement_get_object(statement) : NULL;
754   nodes[3] = context_node;
755 
756   for(i = 0; i < 4; i++) {
757     if(!nodes[i]) {
758       fields[i] = NULL;
759       node_ids[i] = -1;
760       node_types[i] = TRIPLE_NONE;
761       continue;
762     }
763 
764     if(librdf_storage_sqlite_node_helper(storage,
765                                          nodes[i],
766                                          &node_ids[i],
767                                          &node_types[i],
768                                          add_new))
769       return 1;
770 
771     fields[i] = (const unsigned char*)triples_fields[i][node_types[i]];
772   }
773 
774   return 0;
775 }
776 
777 
778 static int
librdf_storage_sqlite_open(librdf_storage * storage,librdf_model * model)779 librdf_storage_sqlite_open(librdf_storage* storage, librdf_model* model)
780 {
781   librdf_storage_sqlite_instance* context;
782   int rc = SQLITE_OK;
783   char *errmsg = NULL;
784   int db_file_exists = 0;
785 
786   context = (librdf_storage_sqlite_instance*)storage->instance;
787 
788   if(!access((const char*)context->name, F_OK))
789     db_file_exists = 1;
790 
791   if(context->is_new && db_file_exists)
792     unlink(context->name);
793 
794   context->db = NULL;
795   rc = sqlite3_open(context->name, &context->db);
796   if(rc != SQLITE_OK)
797     errmsg = (char*)sqlite3_errmsg(context->db);
798 
799   if(rc != SQLITE_OK) {
800     librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
801                "SQLite database %s open failed - %s",
802                context->name, errmsg);
803     librdf_storage_sqlite_close(storage);
804     return 1;
805   }
806 
807 
808   if(context->synchronous >= 0) {
809     raptor_stringbuffer *sb;
810     unsigned char *request;
811 
812     sb = raptor_new_stringbuffer();
813     if(!sb) {
814       librdf_storage_sqlite_close(storage);
815       return 1;
816     }
817 
818     raptor_stringbuffer_append_string(sb,
819                                       (const unsigned char*)"PRAGMA synchronous=", 1);
820     raptor_stringbuffer_append_string(sb,
821                                       (const unsigned char*)sqlite_synchronous_flags[context->synchronous], 1);
822     raptor_stringbuffer_append_counted_string(sb, (const unsigned char*)";", 1, 1);
823 
824     request = raptor_stringbuffer_as_string(sb);
825 
826     rc = librdf_storage_sqlite_exec(storage,
827                                     request,
828                                     NULL, NULL, 0);
829     raptor_free_stringbuffer(sb);
830     if(rc) {
831       librdf_storage_sqlite_close(storage);
832       return 1;
833     }
834   }
835 
836 
837   if(context->is_new) {
838     int i;
839     unsigned char request[200];
840     int begin;
841 
842     begin = librdf_storage_sqlite_transaction_start(storage);
843 
844     for(i = 0; i < NTABLES; i++) {
845 
846 #if 0
847       sprintf((char*)request, "DROP TABLE %s;", sqlite_tables[i].name);
848       librdf_storage_sqlite_exec(storage,
849                                  request,
850                                  NULL, /* no callback */
851                                  NULL, /* arg */
852                                  1); /* don't care if this fails */
853 #endif
854 
855       sprintf((char*)request, "CREATE TABLE %s (%s);",
856               sqlite_tables[i].name, sqlite_tables[i].schema);
857 
858       if(librdf_storage_sqlite_exec(storage,
859                                     request,
860                                     NULL, /* no callback */
861                                     NULL, /* arg */
862                                     0)) {
863         if(!begin)
864           librdf_storage_sqlite_transaction_rollback(storage);
865         librdf_storage_sqlite_close(storage);
866         return 1;
867       }
868 
869     } /* end drop/create table loop */
870 
871     strcpy((char*)request,
872            "CREATE INDEX spindex ON triples (subjectUri, subjectBlank, predicateUri);");
873     if(librdf_storage_sqlite_exec(storage,
874                                   request,
875                                   NULL, /* no callback */
876                                   NULL, /* arg */
877                                   0)) {
878       if(!begin)
879         librdf_storage_sqlite_transaction_rollback(storage);
880       librdf_storage_sqlite_close(storage);
881       return 1;
882     }
883 
884     strcpy((char*)request,
885            "CREATE INDEX uriindex ON uris (uri);");
886     if(librdf_storage_sqlite_exec(storage,
887                                   request,
888                                   NULL, /* no callback */
889                                   NULL, /* arg */
890                                   0)) {
891       if(!begin)
892         librdf_storage_sqlite_transaction_rollback(storage);
893       librdf_storage_sqlite_close(storage);
894       return 1;
895     }
896 
897     if(!begin)
898       librdf_storage_sqlite_transaction_commit(storage);
899   } /* end if is new */
900 
901   return 0;
902 }
903 
904 
905 /**
906  * librdf_storage_sqlite_close:
907  * @storage: the storage
908  *
909  * Close the sqlite storage.
910  *
911  * Return value: non 0 on failure
912  **/
913 static int
librdf_storage_sqlite_close(librdf_storage * storage)914 librdf_storage_sqlite_close(librdf_storage* storage)
915 {
916   librdf_storage_sqlite_instance* context;
917   int status = 0;
918 
919   context = (librdf_storage_sqlite_instance*)storage->instance;
920 
921   if(context->db) {
922     sqlite3_close(context->db);
923     context->db = NULL;
924   }
925 
926   return status;
927 }
928 
929 
930 static int
librdf_storage_sqlite_size(librdf_storage * storage)931 librdf_storage_sqlite_size(librdf_storage* storage)
932 {
933   int count = 0;
934 
935   if(librdf_storage_sqlite_exec(storage,
936                                 (unsigned char*)"SELECT COUNT(*) FROM triples;",
937                                 librdf_storage_sqlite_get_1int_callback,
938                                 &count,
939                                 0))
940     return -1;
941 
942   return count;
943 }
944 
945 
946 static int
librdf_storage_sqlite_add_statement(librdf_storage * storage,librdf_statement * statement)947 librdf_storage_sqlite_add_statement(librdf_storage* storage,
948                                     librdf_statement* statement)
949 {
950   return librdf_storage_sqlite_context_add_statement(storage, NULL, statement);
951 }
952 
953 
954 static int
librdf_storage_sqlite_add_statements(librdf_storage * storage,librdf_stream * statement_stream)955 librdf_storage_sqlite_add_statements(librdf_storage* storage,
956                                      librdf_stream* statement_stream)
957 {
958   /*librdf_storage_sqlite_instance* context;*/
959   int status = 0;
960   int begin;
961 
962   /*context = (librdf_storage_sqlite_instance*)storage->instance;*/
963 
964   /* returns non-0 if a transaction is already active */
965   begin = librdf_storage_sqlite_transaction_start(storage);
966 
967   for(; !librdf_stream_end(statement_stream);
968       librdf_stream_next(statement_stream)) {
969     librdf_statement* statement;
970     librdf_node* context_node;
971     triple_node_type node_types[4];
972     int node_ids[4];
973     const unsigned char* fields[4];
974     raptor_stringbuffer *sb;
975     int i;
976     unsigned char* request;
977     int rc;
978     int max = 3;
979 
980     statement = librdf_stream_get_object(statement_stream);
981     context_node = librdf_stream_get_context2(statement_stream);
982 
983     if(!statement) {
984       status = 1;
985       break;
986     }
987 
988     /* Do not add duplicate statements */
989     if(librdf_storage_sqlite_context_contains_statement(storage, context_node, statement))
990       continue;
991 
992     if(librdf_storage_sqlite_statement_helper(storage,
993                                               statement,
994                                               context_node,
995                                               node_types, node_ids, fields,
996                                               1)) {
997       if(!begin)
998         librdf_storage_sqlite_transaction_rollback(storage);
999       return -1;
1000     }
1001 
1002     if(context_node)
1003       max++;
1004 
1005     /* FIXME no context field used */
1006     sb = raptor_new_stringbuffer();
1007     if(!sb) {
1008       if(!begin)
1009         librdf_storage_sqlite_transaction_rollback(storage);
1010       return -1;
1011     }
1012 
1013     raptor_stringbuffer_append_string(sb,
1014                                       (unsigned char*)"INSERT INTO ", 1);
1015     raptor_stringbuffer_append_string(sb,
1016                                       (unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
1017     raptor_stringbuffer_append_counted_string(sb,
1018                                               (unsigned char*)" ( ", 3, 1);
1019     for(i = 0; i < max; i++) {
1020       raptor_stringbuffer_append_string(sb, fields[i], 1);
1021       if(i < (max-1))
1022         raptor_stringbuffer_append_counted_string(sb,
1023                                                   (unsigned char*)", ", 2, 1);
1024     }
1025 
1026     raptor_stringbuffer_append_counted_string(sb,
1027                                               (unsigned char*)") VALUES(", 9, 1);
1028     for(i = 0; i < max; i++) {
1029       raptor_stringbuffer_append_decimal(sb, node_ids[i]);
1030       if(i < (max-1))
1031         raptor_stringbuffer_append_counted_string(sb,
1032                                                   (unsigned char*)", ", 2, 1);
1033     }
1034     raptor_stringbuffer_append_counted_string(sb,
1035                                               (unsigned char*)");", 2, 1);
1036 
1037     request = raptor_stringbuffer_as_string(sb);
1038 
1039     rc = librdf_storage_sqlite_exec(storage,
1040                                     request,
1041                                     NULL, /* no callback */
1042                                     NULL, /* arg */
1043                                     0);
1044 
1045     raptor_free_stringbuffer(sb);
1046 
1047     if(rc) {
1048       if(!begin)
1049         librdf_storage_sqlite_transaction_rollback(storage);
1050       return 1;
1051     }
1052 
1053   }
1054 
1055   if(!begin)
1056     librdf_storage_sqlite_transaction_commit(storage);
1057 
1058   return status;
1059 }
1060 
1061 
1062 static int
librdf_storage_sqlite_remove_statement(librdf_storage * storage,librdf_statement * statement)1063 librdf_storage_sqlite_remove_statement(librdf_storage* storage,
1064                                        librdf_statement* statement)
1065 {
1066   return librdf_storage_sqlite_context_remove_statement(storage, NULL,
1067                                                         statement);
1068 }
1069 
1070 
1071 static int
librdf_storage_sqlite_statement_operator_helper(librdf_storage * storage,librdf_statement * statement,librdf_node * context_node,raptor_stringbuffer * sb,int add_new)1072 librdf_storage_sqlite_statement_operator_helper(librdf_storage* storage,
1073                                                 librdf_statement* statement,
1074                                                 librdf_node* context_node,
1075                                                 raptor_stringbuffer* sb,
1076                                                 int add_new)
1077 {
1078   /* librdf_storage_sqlite_instance* context; */
1079   triple_node_type node_types[4];
1080   int node_ids[4];
1081   const unsigned char* fields[4];
1082   int i;
1083   int need_and = 0;
1084   int max=3;
1085 
1086   /* context = (librdf_storage_sqlite_instance*)storage->instance; */
1087 
1088   if(context_node)
1089     max++;
1090 
1091   if(librdf_storage_sqlite_statement_helper(storage,
1092                                             statement,
1093                                             context_node,
1094                                             node_types, node_ids, fields,
1095                                             add_new))
1096     return 1;
1097 
1098   raptor_stringbuffer_append_counted_string(sb,
1099                                             (const unsigned char*)" FROM ", 6, 1);
1100   raptor_stringbuffer_append_string(sb,
1101                                     (const unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
1102   raptor_stringbuffer_append_counted_string(sb,
1103                                             (const unsigned char*)" WHERE ", 7, 1);
1104 
1105   for(i = 0; i < max; i++) {
1106     if(need_and)
1107       raptor_stringbuffer_append_counted_string(sb,
1108                                                 (unsigned char*)" AND ", 5, 1);
1109     raptor_stringbuffer_append_string(sb, fields[i], 1);
1110     raptor_stringbuffer_append_counted_string(sb,
1111                                               (const unsigned char*)"=", 1, 1);
1112     raptor_stringbuffer_append_decimal(sb, node_ids[i]);
1113 
1114     need_and = 1;
1115   }
1116 
1117   return 0;
1118 }
1119 
1120 
1121 static int
librdf_storage_sqlite_contains_statement(librdf_storage * storage,librdf_statement * statement)1122 librdf_storage_sqlite_contains_statement(librdf_storage* storage,
1123                                          librdf_statement* statement)
1124 {
1125   return librdf_storage_sqlite_context_contains_statement(storage, NULL, statement);
1126 }
1127 
1128 
1129 static int
librdf_storage_sqlite_context_contains_statement(librdf_storage * storage,librdf_node * context_node,librdf_statement * statement)1130 librdf_storage_sqlite_context_contains_statement(librdf_storage* storage,
1131                                                  librdf_node* context_node,
1132                                                  librdf_statement* statement)
1133 {
1134   raptor_stringbuffer *sb;
1135   unsigned char *request;
1136   int count = 0;
1137   int rc, begin;
1138 
1139   sb = raptor_new_stringbuffer();
1140   if(!sb)
1141     return -1;
1142 
1143   /* returns non-0 if a transaction is already active */
1144   begin = librdf_storage_sqlite_transaction_start(storage);
1145 
1146   raptor_stringbuffer_append_string(sb,
1147                                     (const unsigned char*)"SELECT 1",
1148                                     1);
1149 
1150   if(librdf_storage_sqlite_statement_operator_helper(storage, statement,
1151                                                      context_node, sb, 0)) {
1152     if(!begin)
1153       librdf_storage_sqlite_transaction_rollback(storage);
1154     raptor_free_stringbuffer(sb);
1155     return -1;
1156   }
1157 
1158   raptor_stringbuffer_append_string(sb, (const unsigned char*)" LIMIT 1;", 1);
1159   request = raptor_stringbuffer_as_string(sb);
1160 
1161   rc = librdf_storage_sqlite_exec(storage,
1162                                   request,
1163                                   librdf_storage_sqlite_get_1int_callback,
1164                                   &count,
1165                                   0);
1166 
1167   raptor_free_stringbuffer(sb);
1168 
1169   if(!begin)
1170     librdf_storage_transaction_commit(storage);
1171 
1172   if(rc)
1173     return -1;
1174 
1175   return (count > 0);
1176 }
1177 
1178 
1179 static void
sqlite_construct_select_helper(raptor_stringbuffer * sb)1180 sqlite_construct_select_helper(raptor_stringbuffer* sb)
1181 {
1182   raptor_stringbuffer_append_counted_string(sb,
1183                                             (unsigned char*)"SELECT\n", 7, 1);
1184 
1185   /* If this order is changed MUST CHANGE order in
1186    * librdf_storage_sqlite_get_next_common
1187    */
1188   raptor_stringbuffer_append_string(sb, (unsigned char*)
1189 "  SubjectURIs.uri     AS subjectUri,\n\
1190   SubjectBlanks.blank AS subjectBlank,\n\
1191   PredicateURIs.uri   AS predicateUri,\n\
1192   ObjectURIs.uri      AS objectUri,\n\
1193   ObjectBlanks.blank  AS objectBlank,\n\
1194   ObjectLiterals.text AS objectLiteralText,\n\
1195   ObjectLiterals.language AS objectLiteralLanguage,\n\
1196   ObjectLiterals.datatype AS objectLiteralDatatype,\n\
1197   ObjectDatatypeURIs.uri  AS objectLiteralDatatypeUri,\n\
1198   ContextURIs.uri         AS contextUri\n",
1199                                     1);
1200 
1201   raptor_stringbuffer_append_counted_string(sb,
1202                                             (unsigned char*)"FROM ", 5, 1);
1203   raptor_stringbuffer_append_string(sb,
1204                                     (unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
1205   raptor_stringbuffer_append_counted_string(sb,
1206                                             (unsigned char*)" AS T\n", 6, 1);
1207 
1208   raptor_stringbuffer_append_string(sb, (unsigned char*)
1209 "  LEFT JOIN uris     AS SubjectURIs    ON SubjectURIs.id    = T.subjectUri\n\
1210   LEFT JOIN blanks   AS SubjectBlanks  ON SubjectBlanks.id  = T.subjectBlank\n\
1211   LEFT JOIN uris     AS PredicateURIs  ON PredicateURIs.id  = T.predicateUri\n\
1212   LEFT JOIN uris     AS ObjectURIs     ON ObjectURIs.id     = T.objectUri\n\
1213   LEFT JOIN blanks   AS ObjectBlanks   ON ObjectBlanks.id   = T.objectBlank\n\
1214   LEFT JOIN literals AS ObjectLiterals ON ObjectLiterals.id = T.objectLiteral\n\
1215   LEFT JOIN uris     AS ObjectDatatypeURIs ON ObjectDatatypeURIs.id = objectLiteralDatatype\n\
1216   LEFT JOIN uris     AS ContextURIs    ON ContextURIs.id     = T.contextUri\n",
1217                                     1);
1218 }
1219 
1220 
1221 typedef struct {
1222   librdf_storage *storage;
1223   librdf_storage_sqlite_instance* sqlite_context;
1224 
1225   int finished;
1226 
1227   librdf_statement *statement;
1228   librdf_node* context;
1229 
1230   /* OUT from sqlite3_prepare (V3) or sqlite_compile (V2) */
1231   sqlite3_stmt *vm;
1232   const char *zTail;
1233 } librdf_storage_sqlite_serialise_stream_context;
1234 
1235 
1236 static librdf_stream*
librdf_storage_sqlite_serialise(librdf_storage * storage)1237 librdf_storage_sqlite_serialise(librdf_storage* storage)
1238 {
1239   librdf_storage_sqlite_instance* context;
1240   librdf_storage_sqlite_serialise_stream_context* scontext;
1241   librdf_stream* stream;
1242   int status;
1243   char *errmsg = NULL;
1244   raptor_stringbuffer *sb;
1245   unsigned char *request;
1246 
1247   context = (librdf_storage_sqlite_instance*)storage->instance;
1248 
1249   scontext = LIBRDF_CALLOC(librdf_storage_sqlite_serialise_stream_context*,
1250                            1, sizeof(*scontext));
1251   if(!scontext)
1252     return NULL;
1253 
1254   scontext->storage = storage;
1255   librdf_storage_add_reference(scontext->storage);
1256 
1257   scontext->sqlite_context = context;
1258   context->in_stream++;
1259 
1260   sb = raptor_new_stringbuffer();
1261   if(!sb) {
1262     librdf_storage_sqlite_serialise_finished((void*)scontext);
1263     return NULL;
1264   }
1265 
1266   sqlite_construct_select_helper(sb);
1267   raptor_stringbuffer_append_counted_string(sb,
1268                                             (unsigned char*)";", 1, 1);
1269 
1270   request = raptor_stringbuffer_as_string(sb);
1271   if(!request) {
1272     raptor_free_stringbuffer(sb);
1273     librdf_storage_sqlite_serialise_finished((void*)scontext);
1274     return NULL;
1275   }
1276 
1277 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
1278   LIBRDF_DEBUG2("SQLite prepare '%s'\n", request);
1279 #endif
1280 
1281   status = sqlite3_prepare(context->db,
1282                            (const char*)request,
1283                            LIBRDF_GOOD_CAST(int, raptor_stringbuffer_length(sb)),
1284                            &scontext->vm,
1285                            &scontext->zTail);
1286   if(status != SQLITE_OK)
1287     errmsg = (char*)sqlite3_errmsg(context->db);
1288 
1289   raptor_free_stringbuffer(sb);
1290 
1291   if(status != SQLITE_OK) {
1292     librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1293                "SQLite database %s SQL compile failed - %s (%d)",
1294                context->name, errmsg, status);
1295 
1296     librdf_storage_sqlite_serialise_finished((void*)scontext);
1297     return NULL;
1298   }
1299 
1300   stream = librdf_new_stream(storage->world,
1301                              (void*)scontext,
1302                              &librdf_storage_sqlite_serialise_end_of_stream,
1303                              &librdf_storage_sqlite_serialise_next_statement,
1304                              &librdf_storage_sqlite_serialise_get_statement,
1305                              &librdf_storage_sqlite_serialise_finished);
1306   if(!stream) {
1307     librdf_storage_sqlite_serialise_finished((void*)scontext);
1308     return NULL;
1309   }
1310 
1311   return stream;
1312 }
1313 
1314 
1315 static int
librdf_storage_sqlite_get_next_common(librdf_storage_sqlite_instance * scontext,sqlite3_stmt * vm,librdf_statement ** statement,librdf_node ** context_node)1316 librdf_storage_sqlite_get_next_common(librdf_storage_sqlite_instance* scontext,
1317                                       sqlite3_stmt *vm,
1318                                       librdf_statement **statement,
1319                                       librdf_node **context_node)
1320 {
1321   int status = SQLITE_BUSY;
1322   int result = 0;
1323 
1324   /*
1325    * Each invocation of sqlite_step returns an integer code that
1326    * indicates what happened during that step. This code may be
1327    * SQLITE_BUSY, SQLITE_ROW, SQLITE_DONE, SQLITE_ERROR, or
1328    * SQLITE_MISUSE.
1329   */
1330   do {
1331     status = sqlite3_step(vm);
1332     if(status == SQLITE_BUSY) {
1333       /* FIXME - how to handle busy? */
1334       continue;
1335     }
1336     break;
1337   } while(1);
1338 
1339   if(status == SQLITE_ROW) {
1340     /* FIXME - turn row data into statement, scontext->context */
1341 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
1342     int i;
1343 #endif
1344     librdf_node* node;
1345     const unsigned char *uri_string, *blank;
1346 
1347 /*
1348  * MUST MATCH fields order in query in librdf_storage_sqlite_serialise
1349  *
1350  i  field name (all TEXT unless given)
1351  0  subjectUri
1352  1  subjectBlank
1353  2  predicateUri
1354  3  objectUri
1355  4  objectBlank
1356  5  objectLiteralText
1357  6  objectLiteralLanguage
1358  7  objectLiteralDatatype (INTEGER)
1359  8  objectLiteralDatatypeUri
1360  9  contextUri
1361 */
1362 
1363 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
1364     for(i = 0; i < sqlite3_column_count(vm); i++)
1365       fprintf(stderr, "%s, ", sqlite3_column_name(vm, i));
1366     fputc('\n', stderr);
1367 
1368     for(i = 0; i < sqlite3_column_count(vm); i++) {
1369       if(i == 7)
1370         fprintf(stderr, "%d, ", sqlite3_column_int(vm, i));
1371       else
1372         fprintf(stderr, "%s, ", sqlite3_column_text(vm, i));
1373     }
1374     fputc('\n', stderr);
1375 #endif
1376 
1377     if(!*statement) {
1378       if(!(*statement = librdf_new_statement(scontext->storage->world)))
1379         return 1;
1380     }
1381 
1382     librdf_statement_clear(*statement);
1383 
1384     /* subject */
1385     uri_string = sqlite3_column_text(vm, 0);
1386     if(uri_string)
1387       node = librdf_new_node_from_uri_string(scontext->storage->world,
1388                                              uri_string);
1389     else {
1390       blank = sqlite3_column_text(vm, 1);
1391       node = librdf_new_node_from_blank_identifier(scontext->storage->world,
1392                                                    blank);
1393     }
1394     if(!node)
1395       /* finished on error */
1396       return 1;
1397 
1398     librdf_statement_set_subject(*statement, node);
1399 
1400 
1401     uri_string = sqlite3_column_text(vm, 2);
1402     node = librdf_new_node_from_uri_string(scontext->storage->world,
1403                                            uri_string);
1404     if(!node)
1405       /* finished on error */
1406       return 1;
1407 
1408     librdf_statement_set_predicate(*statement, node);
1409 
1410     uri_string = sqlite3_column_text(vm, 3);
1411     blank = sqlite3_column_text(vm, 4);
1412     if(uri_string)
1413       node = librdf_new_node_from_uri_string(scontext->storage->world,
1414                                              uri_string);
1415     else if(blank)
1416       node = librdf_new_node_from_blank_identifier(scontext->storage->world,
1417                                                    blank);
1418     else {
1419       const unsigned char *literal = sqlite3_column_text(vm, 5);
1420       const unsigned char *language = sqlite3_column_text(vm, 6);
1421       librdf_uri *datatype = NULL;
1422 
1423       /* int datatype_id= sqlite3_column_int(vm, 7); */
1424       uri_string = sqlite3_column_text(vm, 8);
1425       if(uri_string) {
1426         datatype = librdf_new_uri(scontext->storage->world, uri_string);
1427         if(!datatype)
1428           /* finished on error */
1429           return 1;
1430       }
1431 
1432       node = librdf_new_node_from_typed_literal(scontext->storage->world,
1433                                                 literal,
1434                                                 (const char*)language,
1435                                                 datatype);
1436       if(datatype)
1437         librdf_free_uri(datatype);
1438 
1439     }
1440     if(!node)
1441       /* finished on error */
1442       return 1;
1443 
1444     librdf_statement_set_object(*statement, node);
1445 
1446     uri_string = sqlite3_column_text(vm, 9);
1447     if(uri_string) {
1448       node = librdf_new_node_from_uri_string(scontext->storage->world,
1449                                              uri_string);
1450       if(!node)
1451         /* finished on error */
1452         return 1;
1453 
1454       if(*context_node)
1455         librdf_free_node(*context_node);
1456       *context_node = node;
1457     }
1458   }
1459 
1460   if(status != SQLITE_ROW)
1461     result = 1;
1462 
1463   if(status == SQLITE_ERROR) {
1464     char *errmsg = NULL;
1465 
1466     status = sqlite3_finalize(vm);
1467     if(status != SQLITE_OK)
1468       errmsg = (char*)sqlite3_errmsg(scontext->db);
1469 
1470     if(status != SQLITE_OK) {
1471       librdf_log(scontext->storage->world,
1472                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1473                  "SQLite database %s finalize failed - %s (%d)",
1474                  scontext->name, errmsg, status);
1475     }
1476     result = -1;
1477   }
1478 
1479   return result;
1480 }
1481 
1482 
1483 
1484 static int
librdf_storage_sqlite_serialise_end_of_stream(void * context)1485 librdf_storage_sqlite_serialise_end_of_stream(void* context)
1486 {
1487   librdf_storage_sqlite_serialise_stream_context* scontext;
1488 
1489   scontext = (librdf_storage_sqlite_serialise_stream_context*)context;
1490 
1491   if(scontext->finished)
1492     return 1;
1493 
1494   if(scontext->statement == NULL) {
1495     int result;
1496 
1497     result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
1498                                                    scontext->vm,
1499                                                    &scontext->statement,
1500                                                    &scontext->context);
1501     if(result) {
1502       /* error or finished */
1503       if(result < 0)
1504         scontext->vm = NULL;
1505       scontext->finished = 1;
1506     }
1507   }
1508 
1509   return scontext->finished;
1510 }
1511 
1512 
1513 static int
librdf_storage_sqlite_serialise_next_statement(void * context)1514 librdf_storage_sqlite_serialise_next_statement(void* context)
1515 {
1516   librdf_storage_sqlite_serialise_stream_context* scontext;
1517   int result;
1518 
1519   scontext = (librdf_storage_sqlite_serialise_stream_context*)context;
1520   if(scontext->finished)
1521     return 1;
1522 
1523   result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
1524                                                  scontext->vm,
1525                                                  &scontext->statement,
1526                                                  &scontext->context);
1527   if(result) {
1528     /* error or finished */
1529     if(result < 0)
1530       scontext->vm = NULL;
1531     scontext->finished = 1;
1532   }
1533 
1534   return result;
1535 }
1536 
1537 
1538 static void*
librdf_storage_sqlite_serialise_get_statement(void * context,int flags)1539 librdf_storage_sqlite_serialise_get_statement(void* context, int flags)
1540 {
1541   librdf_storage_sqlite_serialise_stream_context* scontext;
1542 
1543   scontext  = (librdf_storage_sqlite_serialise_stream_context*)context;
1544 
1545   switch(flags) {
1546     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
1547       return scontext->statement;
1548 
1549     case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
1550       return scontext->context;
1551 
1552     default:
1553       librdf_log(scontext->storage->world,
1554                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1555                  "Unknown iterator method flag %d", flags);
1556       return NULL;
1557   }
1558 }
1559 
1560 
1561 static void
librdf_storage_sqlite_serialise_finished(void * context)1562 librdf_storage_sqlite_serialise_finished(void* context)
1563 {
1564   librdf_storage_sqlite_serialise_stream_context* scontext;
1565 
1566   scontext = (librdf_storage_sqlite_serialise_stream_context*)context;
1567 
1568   if(scontext->vm) {
1569     char *errmsg = NULL;
1570     int status;
1571 
1572     status = sqlite3_finalize(scontext->vm);
1573     if(status != SQLITE_OK)
1574       errmsg = (char*)sqlite3_errmsg(scontext->sqlite_context->db);
1575 
1576     if(status != SQLITE_OK) {
1577       librdf_log(scontext->storage->world,
1578                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1579                  "SQLite database %s finalize failed - %s (%d)",
1580                  scontext->sqlite_context->name, errmsg, status);
1581     }
1582   }
1583 
1584   if(scontext->storage)
1585     librdf_storage_remove_reference(scontext->storage);
1586 
1587   if(scontext->statement)
1588     librdf_free_statement(scontext->statement);
1589 
1590   if(scontext->context)
1591     librdf_free_node(scontext->context);
1592 
1593   scontext->sqlite_context->in_stream--;
1594   if(!scontext->sqlite_context->in_stream)
1595     librdf_storage_sqlite_query_flush(scontext->storage);
1596 
1597   LIBRDF_FREE(librdf_storage_sqlite_serialise_stream_context, scontext);
1598 }
1599 
1600 
1601 typedef struct {
1602   librdf_storage *storage;
1603   librdf_storage_sqlite_instance* sqlite_context;
1604 
1605   int finished;
1606 
1607   librdf_statement *query_statement;
1608 
1609   librdf_statement *statement;
1610   librdf_node* context;
1611 
1612   /* OUT from sqlite3_prepare (V3) or sqlite_compile (V2) */
1613   sqlite3_stmt *vm;
1614   const char *zTail;
1615 } librdf_storage_sqlite_find_statements_stream_context;
1616 
1617 
1618 /**
1619  * librdf_storage_sqlite_find_statements:
1620  * @storage: the storage
1621  * @statement: the statement to match
1622  *
1623  * .
1624  *
1625  * Return a stream of statements matching the given statement (or
1626  * all statements if NULL).  Parts (subject, predicate, object) of the
1627  * statement can be empty in which case any statement part will match that.
1628  * Uses #librdf_statement_match to do the matching.
1629  *
1630  * Return value: a #librdf_stream or NULL on failure
1631  **/
1632 static librdf_stream*
librdf_storage_sqlite_find_statements(librdf_storage * storage,librdf_statement * statement)1633 librdf_storage_sqlite_find_statements(librdf_storage* storage,
1634                                       librdf_statement* statement)
1635 {
1636   librdf_storage_sqlite_instance* context;
1637   librdf_storage_sqlite_find_statements_stream_context* scontext;
1638   librdf_stream* stream;
1639   unsigned char* request;
1640   int status;
1641   triple_node_type node_types[4];
1642   int node_ids[4];
1643   const unsigned char* fields[4];
1644   char *errmsg = NULL;
1645   raptor_stringbuffer *sb;
1646   int need_where = 1;
1647   int need_and = 0;
1648   int i;
1649 
1650   context = (librdf_storage_sqlite_instance*)storage->instance;
1651 
1652   scontext = LIBRDF_CALLOC(librdf_storage_sqlite_find_statements_stream_context*,
1653                            1, sizeof(*scontext));
1654   if(!scontext)
1655     return NULL;
1656 
1657   scontext->storage = storage;
1658   librdf_storage_add_reference(scontext->storage);
1659 
1660   scontext->sqlite_context = context;
1661   context->in_stream++;
1662 
1663   scontext->query_statement = librdf_new_statement_from_statement(statement);
1664   if(!scontext->query_statement) {
1665     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1666     return NULL;
1667   }
1668 
1669   if(librdf_storage_sqlite_statement_helper(storage,
1670                                             statement,
1671                                             NULL,
1672                                             node_types, node_ids, fields,
1673                                             0)) {
1674     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1675     return NULL;
1676   }
1677 
1678   sb = raptor_new_stringbuffer();
1679   if(!sb) {
1680     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1681     return NULL;
1682   }
1683 
1684   sqlite_construct_select_helper(sb);
1685 
1686   for(i = 0; i < 3; i++) {
1687     if(node_types[i] == TRIPLE_NONE)
1688       continue;
1689 
1690     if(need_where) {
1691       raptor_stringbuffer_append_counted_string(sb,
1692                                                 (unsigned char*)" WHERE ", 7, 1);
1693       need_where = 0;
1694       need_and = 1;
1695     } else if(need_and)
1696       raptor_stringbuffer_append_counted_string(sb,
1697                                                 (unsigned char*)" AND ", 5, 1);
1698     raptor_stringbuffer_append_counted_string(sb,
1699                                               (unsigned char*)"T.", 2, 1);
1700     raptor_stringbuffer_append_string(sb, fields[i], 1);
1701     raptor_stringbuffer_append_counted_string(sb,
1702                                               (unsigned char*)"=", 1, 1);
1703     raptor_stringbuffer_append_decimal(sb, node_ids[i]);
1704     raptor_stringbuffer_append_counted_string(sb,
1705                                               (unsigned char*)"\n", 1, 1);
1706   }
1707   raptor_stringbuffer_append_counted_string(sb,
1708                                             (unsigned char*)";", 1, 1);
1709 
1710   request = raptor_stringbuffer_as_string(sb);
1711   if(!request) {
1712     raptor_free_stringbuffer(sb);
1713     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1714     return NULL;
1715   }
1716 
1717 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
1718   LIBRDF_DEBUG2("SQLite prepare '%s'\n", request);
1719 #endif
1720 
1721   status = sqlite3_prepare(context->db,
1722                            (const char*)request,
1723                            LIBRDF_GOOD_CAST(int, raptor_stringbuffer_length(sb)),
1724                            &scontext->vm,
1725                            &scontext->zTail);
1726   if(status != SQLITE_OK)
1727     errmsg = (char*)sqlite3_errmsg(context->db);
1728 
1729   raptor_free_stringbuffer(sb);
1730 
1731   if(status != SQLITE_OK) {
1732     librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1733                "SQLite database %s SQL compile '%s' failed - %s (%d)",
1734                context->name, request, errmsg, status);
1735 
1736     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1737     return NULL;
1738   }
1739 
1740   stream = librdf_new_stream(storage->world,
1741                              (void*)scontext,
1742                              &librdf_storage_sqlite_find_statements_end_of_stream,
1743                              &librdf_storage_sqlite_find_statements_next_statement,
1744                              &librdf_storage_sqlite_find_statements_get_statement,
1745                              &librdf_storage_sqlite_find_statements_finished);
1746   if(!stream) {
1747     librdf_storage_sqlite_find_statements_finished((void*)scontext);
1748     return NULL;
1749   }
1750 
1751   return stream;
1752 }
1753 
1754 
1755 static int
librdf_storage_sqlite_find_statements_end_of_stream(void * context)1756 librdf_storage_sqlite_find_statements_end_of_stream(void* context)
1757 {
1758   librdf_storage_sqlite_find_statements_stream_context* scontext;
1759 
1760   scontext = (librdf_storage_sqlite_find_statements_stream_context*)context;
1761 
1762   if(scontext->finished)
1763     return 1;
1764 
1765   if(scontext->statement == NULL) {
1766     int result;
1767     result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
1768                                                    scontext->vm,
1769                                                    &scontext->statement,
1770                                                    &scontext->context);
1771     if(result) {
1772       /* error or finished */
1773       if(result < 0)
1774         scontext->vm = NULL;
1775       scontext->finished = 1;
1776     }
1777   }
1778 
1779 
1780   return scontext->finished;
1781 }
1782 
1783 
1784 static int
librdf_storage_sqlite_find_statements_next_statement(void * context)1785 librdf_storage_sqlite_find_statements_next_statement(void* context)
1786 {
1787   librdf_storage_sqlite_find_statements_stream_context* scontext;
1788   int result;
1789 
1790   scontext = (librdf_storage_sqlite_find_statements_stream_context*)context;
1791 
1792   if(scontext->finished)
1793     return 1;
1794 
1795   result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
1796                                                  scontext->vm,
1797                                                  &scontext->statement,
1798                                                  &scontext->context);
1799   if(result) {
1800     /* error or finished */
1801     if(result < 0)
1802       scontext->vm = NULL;
1803     scontext->finished = 1;
1804   }
1805 
1806   return result;
1807 }
1808 
1809 
1810 static void*
librdf_storage_sqlite_find_statements_get_statement(void * context,int flags)1811 librdf_storage_sqlite_find_statements_get_statement(void* context, int flags)
1812 {
1813   librdf_storage_sqlite_find_statements_stream_context* scontext;
1814 
1815   scontext = (librdf_storage_sqlite_find_statements_stream_context*)context;
1816 
1817   switch(flags) {
1818     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
1819       return scontext->statement;
1820 
1821     case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
1822       return scontext->context;
1823 
1824     default:
1825       librdf_log(scontext->storage->world,
1826                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1827                  "Unknown iterator method flag %d", flags);
1828       return NULL;
1829   }
1830 }
1831 
1832 
1833 static void
librdf_storage_sqlite_find_statements_finished(void * context)1834 librdf_storage_sqlite_find_statements_finished(void* context)
1835 {
1836   librdf_storage_sqlite_find_statements_stream_context* scontext;
1837 
1838   scontext  = (librdf_storage_sqlite_find_statements_stream_context*)context;
1839 
1840   if(scontext->vm) {
1841     char *errmsg = NULL;
1842     int status;
1843 
1844     status = sqlite3_finalize(scontext->vm);
1845     if(status != SQLITE_OK)
1846       errmsg = (char*)sqlite3_errmsg(scontext->sqlite_context->db);
1847 
1848     if(status != SQLITE_OK) {
1849       librdf_log(scontext->storage->world,
1850                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
1851                  "SQLite database %s finalize failed - %s (%d)",
1852                  scontext->sqlite_context->name, errmsg, status);
1853     }
1854   }
1855 
1856   if(scontext->storage)
1857     librdf_storage_remove_reference(scontext->storage);
1858 
1859   if(scontext->query_statement)
1860     librdf_free_statement(scontext->query_statement);
1861 
1862   if(scontext->statement)
1863     librdf_free_statement(scontext->statement);
1864 
1865   if(scontext->context)
1866     librdf_free_node(scontext->context);
1867 
1868   scontext->sqlite_context->in_stream--;
1869   if(!scontext->sqlite_context->in_stream)
1870     librdf_storage_sqlite_query_flush(scontext->storage);
1871 
1872   LIBRDF_FREE(librdf_storage_sqlite_find_statements_stream_context, scontext);
1873 }
1874 
1875 
1876 /**
1877  * librdf_storage_sqlite_context_add_statement:
1878  * @storage: #librdf_storage object
1879  * @context_node: #librdf_node object
1880  * @statement: #librdf_statement statement to add
1881  *
1882  * Add a statement to a storage context.
1883  *
1884  * Return value: non 0 on failure
1885  **/
1886 static int
librdf_storage_sqlite_context_add_statement(librdf_storage * storage,librdf_node * context_node,librdf_statement * statement)1887 librdf_storage_sqlite_context_add_statement(librdf_storage* storage,
1888                                             librdf_node* context_node,
1889                                             librdf_statement* statement)
1890 {
1891   /* librdf_storage_sqlite_instance* context; */
1892   triple_node_type node_types[4];
1893   int node_ids[4];
1894   const unsigned char* fields[4];
1895   raptor_stringbuffer *sb;
1896   unsigned char* request;
1897   int i;
1898   int rc, begin;
1899   int max=3;
1900 
1901   /* Do not add duplicate statements */
1902   if(librdf_storage_sqlite_context_contains_statement(storage, context_node, statement))
1903     return 0;
1904 
1905   /* context = (librdf_storage_sqlite_instance*)storage->instance; */
1906 
1907   sb = raptor_new_stringbuffer();
1908   if(!sb)
1909     return -1;
1910 
1911   /* returns non-0 if transaction is already active */
1912   begin = librdf_storage_sqlite_transaction_start(storage);
1913 
1914   if(librdf_storage_sqlite_statement_helper(storage,
1915                                             statement,
1916                                             context_node,
1917                                             node_types, node_ids, fields,
1918                                             1)) {
1919 
1920     if(!begin)
1921       librdf_storage_sqlite_transaction_rollback(storage);
1922     raptor_free_stringbuffer(sb);
1923     return -1;
1924   }
1925 
1926   if(context_node)
1927     max++;
1928 
1929   raptor_stringbuffer_append_string(sb,
1930                                     (unsigned char*)"INSERT INTO ", 1);
1931   raptor_stringbuffer_append_string(sb,
1932                                     (unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
1933   raptor_stringbuffer_append_counted_string(sb,
1934                                             (unsigned char*)" ( ", 3, 1);
1935   for(i = 0; i < max; i++) {
1936     raptor_stringbuffer_append_string(sb, fields[i], 1);
1937     if(i < (max-1))
1938       raptor_stringbuffer_append_counted_string(sb,
1939                                                 (unsigned char*)", ", 2, 1);
1940   }
1941 
1942   raptor_stringbuffer_append_counted_string(sb,
1943                                             (unsigned char*)") VALUES(", 9, 1);
1944   for(i = 0; i < max; i++) {
1945     raptor_stringbuffer_append_decimal(sb, node_ids[i]);
1946     if(i < (max-1))
1947       raptor_stringbuffer_append_counted_string(sb,
1948                                                 (unsigned char*)", ", 2, 1);
1949   }
1950   raptor_stringbuffer_append_counted_string(sb,
1951                                             (unsigned char*)");", 2, 1);
1952 
1953   request = raptor_stringbuffer_as_string(sb);
1954 
1955   rc = librdf_storage_sqlite_exec(storage,
1956                                   request,
1957                                   NULL, /* no callback */
1958                                   NULL, /* arg */
1959                                   0);
1960 
1961   raptor_free_stringbuffer(sb);
1962 
1963   if(rc) {
1964     if(!begin)
1965       librdf_storage_transaction_rollback(storage);
1966     return rc;
1967   }
1968 
1969   if(!begin)
1970     librdf_storage_transaction_commit(storage);
1971 
1972   return 0;
1973 }
1974 
1975 
1976 /**
1977  * librdf_storage_sqlite_context_remove_statement:
1978  * @storage: #librdf_storage object
1979  * @context_node: #librdf_node object
1980  * @statement: #librdf_statement statement to remove
1981  *
1982  * Remove a statement from a storage context.
1983  *
1984  * Return value: non 0 on failure
1985  **/
1986 static int
librdf_storage_sqlite_context_remove_statement(librdf_storage * storage,librdf_node * context_node,librdf_statement * statement)1987 librdf_storage_sqlite_context_remove_statement(librdf_storage* storage,
1988                                                librdf_node* context_node,
1989                                                librdf_statement* statement)
1990 {
1991   /* librdf_storage_sqlite_instance* context; */
1992   int rc;
1993   raptor_stringbuffer *sb;
1994   unsigned char *request;
1995 
1996   /* context = (librdf_storage_sqlite_instance*)storage->instance; */
1997 
1998   sb = raptor_new_stringbuffer();
1999   if(!sb)
2000     return -1;
2001 
2002   raptor_stringbuffer_append_string(sb, (const unsigned char*)"DELETE", 1);
2003   if(librdf_storage_sqlite_statement_operator_helper(storage, statement,
2004                                                      context_node, sb, 0)) {
2005     raptor_free_stringbuffer(sb);
2006     return -1;
2007   }
2008 
2009   raptor_stringbuffer_append_counted_string(sb,
2010                                             (const unsigned char*)";", 1, 1);
2011 
2012   request = raptor_stringbuffer_as_string(sb);
2013 
2014   rc = librdf_storage_sqlite_exec(storage,
2015                                   request,
2016                                   NULL,
2017                                   NULL,
2018                                   0);
2019 
2020   raptor_free_stringbuffer(sb);
2021 
2022   return rc;
2023 }
2024 
2025 
2026 static  int
librdf_storage_sqlite_context_remove_statements(librdf_storage * storage,librdf_node * context_node)2027 librdf_storage_sqlite_context_remove_statements(librdf_storage* storage,
2028                                                 librdf_node* context_node)
2029 {
2030   triple_node_type node_types[4];
2031   int node_ids[4];
2032   const unsigned char* fields[4];
2033   raptor_stringbuffer *sb;
2034   unsigned char *request;
2035   int rc = 0;
2036 
2037 
2038   if(librdf_storage_sqlite_statement_helper(storage,
2039                                             NULL,
2040                                             context_node,
2041                                             node_types, node_ids, fields, 0))
2042     return -1;
2043 
2044   sb = raptor_new_stringbuffer();
2045   if(!sb)
2046     return -1;
2047 
2048   raptor_stringbuffer_append_counted_string(sb,
2049                                     (unsigned char*)"DELETE FROM ", 12, 1);
2050   raptor_stringbuffer_append_string(sb,
2051                                     (unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
2052 
2053   raptor_stringbuffer_append_counted_string(sb,
2054                                             (unsigned char*)" WHERE ", 7, 1);
2055 
2056   raptor_stringbuffer_append_string(sb, fields[TRIPLE_CONTEXT], 1);
2057   raptor_stringbuffer_append_counted_string(sb,
2058                                             (unsigned char*)"=", 1, 1);
2059   raptor_stringbuffer_append_decimal(sb, node_ids[TRIPLE_CONTEXT]);
2060   raptor_stringbuffer_append_counted_string(sb,
2061                                             (unsigned char*)"\n", 1, 1);
2062   raptor_stringbuffer_append_counted_string(sb,
2063                                             (unsigned char*)";", 1, 1);
2064 
2065   request = raptor_stringbuffer_as_string(sb);
2066 
2067   rc = librdf_storage_sqlite_exec(storage,
2068                                   request,
2069                                   NULL, /* no callback */
2070                                   NULL, /* arg */
2071                                   0);
2072 
2073   raptor_free_stringbuffer(sb);
2074 
2075   if(rc)
2076     return -1;
2077 
2078   return 0;
2079 }
2080 
2081 
2082 typedef struct {
2083   librdf_storage *storage;
2084   librdf_storage_sqlite_instance* sqlite_context;
2085 
2086   int finished;
2087 
2088   librdf_node *context_node;
2089 
2090   librdf_statement *statement;
2091   librdf_node* context;
2092 
2093   /* OUT from sqlite3_prepare (V3) or sqlite_compile (V2) */
2094   sqlite3_stmt *vm;
2095   const char *zTail;
2096 } librdf_storage_sqlite_context_serialise_stream_context;
2097 
2098 
2099 /**
2100  * librdf_storage_sqlite_context_serialise:
2101  * @storage: #librdf_storage object
2102  * @context_node: #librdf_node object
2103  *
2104  * Sqlite all statements in a storage context.
2105  *
2106  * Return value: #librdf_stream of statements or NULL on failure or context is empty
2107  **/
2108 static librdf_stream*
librdf_storage_sqlite_context_serialise(librdf_storage * storage,librdf_node * context_node)2109 librdf_storage_sqlite_context_serialise(librdf_storage* storage,
2110                                         librdf_node* context_node)
2111 {
2112   librdf_storage_sqlite_instance* context;
2113   librdf_storage_sqlite_context_serialise_stream_context* scontext;
2114   librdf_stream* stream;
2115   int status;
2116   char *errmsg = NULL;
2117   triple_node_type node_types[4];
2118   int node_ids[4];
2119   const unsigned char* fields[4];
2120   raptor_stringbuffer *sb;
2121   unsigned char *request;
2122 
2123   context = (librdf_storage_sqlite_instance*)storage->instance;
2124 
2125   scontext = LIBRDF_CALLOC(librdf_storage_sqlite_context_serialise_stream_context*,
2126                            1, sizeof(*scontext));
2127   if(!scontext)
2128     return NULL;
2129 
2130   scontext->storage = storage;
2131   librdf_storage_add_reference(scontext->storage);
2132 
2133   scontext->sqlite_context = context;
2134   context->in_stream++;
2135 
2136   scontext->context_node = librdf_new_node_from_node(context_node);
2137 
2138   if(librdf_storage_sqlite_statement_helper(storage,
2139                                             NULL,
2140                                             scontext->context_node,
2141                                             node_types, node_ids, fields,
2142                                             0)) {
2143     librdf_storage_sqlite_context_serialise_finished((void*)scontext);
2144     return NULL;
2145   }
2146 
2147   sb = raptor_new_stringbuffer();
2148   if(!sb) {
2149     librdf_storage_sqlite_context_serialise_finished((void*)scontext);
2150     return NULL;
2151   }
2152 
2153   sqlite_construct_select_helper(sb);
2154   raptor_stringbuffer_append_counted_string(sb,
2155                                             (unsigned char*)" WHERE ", 7, 1);
2156   raptor_stringbuffer_append_counted_string(sb,
2157                                             (unsigned char*)"T.", 2, 1);
2158   raptor_stringbuffer_append_string(sb, fields[TRIPLE_CONTEXT], 1);
2159   raptor_stringbuffer_append_counted_string(sb,
2160                                             (unsigned char*)"=", 1, 1);
2161   raptor_stringbuffer_append_decimal(sb, node_ids[TRIPLE_CONTEXT]);
2162   raptor_stringbuffer_append_counted_string(sb,
2163                                             (unsigned char*)"\n", 1, 1);
2164   raptor_stringbuffer_append_counted_string(sb,
2165                                             (unsigned char*)";", 1, 1);
2166 
2167   request = raptor_stringbuffer_as_string(sb);
2168   if(!request) {
2169     raptor_free_stringbuffer(sb);
2170     librdf_storage_sqlite_context_serialise_finished((void*)scontext);
2171     return NULL;
2172   }
2173 
2174 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
2175   LIBRDF_DEBUG2("SQLite prepare '%s'\n", request);
2176 #endif
2177 
2178   status = sqlite3_prepare(context->db,
2179                            (const char*)request,
2180                            LIBRDF_GOOD_CAST(int, raptor_stringbuffer_length(sb)),
2181                            &scontext->vm,
2182                            &scontext->zTail);
2183   if(status != SQLITE_OK)
2184     errmsg = (char*)sqlite3_errmsg(context->db);
2185 
2186   raptor_free_stringbuffer(sb);
2187 
2188   if(status != SQLITE_OK) {
2189     librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2190                "SQLite database %s SQL compile failed - %s (%d)",
2191                context->name, errmsg, status);
2192 
2193     librdf_storage_sqlite_context_serialise_finished((void*)scontext);
2194     return NULL;
2195   }
2196 
2197   stream = librdf_new_stream(storage->world,
2198                              (void*)scontext,
2199                              &librdf_storage_sqlite_context_serialise_end_of_stream,
2200                              &librdf_storage_sqlite_context_serialise_next_statement,
2201                              &librdf_storage_sqlite_context_serialise_get_statement,
2202                              &librdf_storage_sqlite_context_serialise_finished);
2203   if(!stream) {
2204     librdf_storage_sqlite_context_serialise_finished((void*)scontext);
2205     return NULL;
2206   }
2207 
2208   return stream;
2209 }
2210 
2211 
2212 static int
librdf_storage_sqlite_context_serialise_end_of_stream(void * context)2213 librdf_storage_sqlite_context_serialise_end_of_stream(void* context)
2214 {
2215   librdf_storage_sqlite_context_serialise_stream_context* scontext;
2216 
2217   scontext = (librdf_storage_sqlite_context_serialise_stream_context*)context;
2218 
2219   if(scontext->finished)
2220     return 1;
2221 
2222   if(scontext->statement == NULL) {
2223     int result;
2224 
2225     result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
2226                                                    scontext->vm,
2227                                                    &scontext->statement,
2228                                                    &scontext->context);
2229     if(result) {
2230       /* error or finished */
2231       if(result < 0)
2232         scontext->vm = NULL;
2233       scontext->finished = 1;
2234     }
2235   }
2236 
2237 
2238   return scontext->finished;
2239 }
2240 
2241 
2242 static int
librdf_storage_sqlite_context_serialise_next_statement(void * context)2243 librdf_storage_sqlite_context_serialise_next_statement(void* context)
2244 {
2245   librdf_storage_sqlite_context_serialise_stream_context* scontext;
2246   int result;
2247 
2248   scontext = (librdf_storage_sqlite_context_serialise_stream_context*)context;
2249 
2250   if(scontext->finished)
2251     return 1;
2252 
2253   result = librdf_storage_sqlite_get_next_common(scontext->sqlite_context,
2254                                                  scontext->vm,
2255                                                  &scontext->statement,
2256                                                  &scontext->context);
2257   if(result) {
2258     /* error or finished */
2259     if(result < 0)
2260       scontext->vm = NULL;
2261     scontext->finished = 1;
2262   }
2263 
2264   return result;
2265 }
2266 
2267 
2268 static void*
librdf_storage_sqlite_context_serialise_get_statement(void * context,int flags)2269 librdf_storage_sqlite_context_serialise_get_statement(void* context, int flags)
2270 {
2271   librdf_storage_sqlite_context_serialise_stream_context* scontext;
2272 
2273   scontext = (librdf_storage_sqlite_context_serialise_stream_context*)context;
2274 
2275   switch(flags) {
2276     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
2277       return scontext->statement;
2278 
2279     case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
2280       return scontext->context;
2281 
2282     default:
2283       librdf_log(scontext->storage->world,
2284                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2285                  "Unknown iterator method flag %d", flags);
2286       return NULL;
2287   }
2288 }
2289 
2290 
2291 static void
librdf_storage_sqlite_context_serialise_finished(void * context)2292 librdf_storage_sqlite_context_serialise_finished(void* context)
2293 {
2294   librdf_storage_sqlite_context_serialise_stream_context* scontext;
2295 
2296   scontext = (librdf_storage_sqlite_context_serialise_stream_context*)context;
2297 
2298   if(scontext->vm) {
2299     char *errmsg = NULL;
2300     int status;
2301 
2302     status = sqlite3_finalize(scontext->vm);
2303     if(status != SQLITE_OK)
2304       errmsg = (char*)sqlite3_errmsg(scontext->sqlite_context->db);
2305 
2306     if(status != SQLITE_OK) {
2307       librdf_log(scontext->storage->world,
2308                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2309                  "SQLite database %s finalize failed - %s (%d)",
2310                  scontext->sqlite_context->name, errmsg, status);
2311     }
2312   }
2313 
2314   if(scontext->storage)
2315     librdf_storage_remove_reference(scontext->storage);
2316 
2317   if(scontext->statement)
2318     librdf_free_statement(scontext->statement);
2319 
2320   if(scontext->context)
2321     librdf_free_node(scontext->context);
2322 
2323   if(scontext->context_node)
2324     librdf_free_node(scontext->context_node);
2325 
2326   scontext->sqlite_context->in_stream--;
2327   if(!scontext->sqlite_context->in_stream)
2328     librdf_storage_sqlite_query_flush(scontext->storage);
2329 
2330   LIBRDF_FREE(librdf_storage_sqlite_context_serialise_stream_context, scontext);
2331 }
2332 
2333 
2334 
2335 typedef struct {
2336   librdf_storage *storage;
2337   librdf_storage_sqlite_instance* sqlite_context;
2338 
2339   int finished;
2340 
2341   librdf_node *current;
2342 
2343   /* OUT from sqlite3_prepare (V3) or sqlite_compile (V2) */
2344   sqlite3_stmt *vm;
2345   const char *zTail;
2346 } librdf_storage_sqlite_get_contexts_iterator_context;
2347 
2348 
2349 
2350 static int
librdf_storage_sqlite_get_next_context_common(librdf_storage_sqlite_instance * scontext,sqlite3_stmt * vm,librdf_node ** context_node)2351 librdf_storage_sqlite_get_next_context_common(librdf_storage_sqlite_instance* scontext,
2352                                               sqlite3_stmt *vm,
2353                                               librdf_node **context_node)
2354 {
2355   int status = SQLITE_BUSY;
2356   int result = 0;
2357 
2358   /*
2359    * Each invocation of sqlite_step returns an integer code that
2360    * indicates what happened during that step. This code may be
2361    * SQLITE_BUSY, SQLITE_ROW, SQLITE_DONE, SQLITE_ERROR, or
2362    * SQLITE_MISUSE.
2363   */
2364   do {
2365     status = sqlite3_step(vm);
2366     if(status == SQLITE_BUSY) {
2367       /* FIXME - how to handle busy? */
2368       continue;
2369     }
2370     break;
2371   } while(1);
2372 
2373   if(status == SQLITE_ROW) {
2374     /* Turns row data into scontext->context */
2375 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
2376     int i;
2377 #endif
2378     const unsigned char *uri_string;
2379 
2380 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
2381     for(i = 0; i < sqlite3_column_count(vm); i++)
2382       fprintf(stderr, "%s, ", sqlite3_column_name(vm, i));
2383     fputc('\n', stderr);
2384 
2385     for(i = 0; i < sqlite3_column_count(vm); i++) {
2386       if(i == 7)
2387         fprintf(stderr, "%d, ", sqlite3_column_int(vm, i));
2388       else
2389         fprintf(stderr, "%s, ", sqlite3_column_text(vm, i));
2390     }
2391     fputc('\n', stderr);
2392 #endif
2393 
2394     uri_string = sqlite3_column_text(vm, 0);
2395     if(uri_string) {
2396       librdf_node *node;
2397       node = librdf_new_node_from_uri_string(scontext->storage->world,
2398                                              uri_string);
2399       if(!node)
2400         /* finished on error */
2401         return 1;
2402 
2403       if(*context_node)
2404         librdf_free_node(*context_node);
2405       *context_node = node;
2406     }
2407   }
2408 
2409   if(status != SQLITE_ROW)
2410     result = 1;
2411 
2412   if(status == SQLITE_ERROR) {
2413     char *errmsg = NULL;
2414 
2415     status = sqlite3_finalize(vm);
2416     if(status != SQLITE_OK)
2417       errmsg = (char*)sqlite3_errmsg(scontext->db);
2418 
2419     if(status != SQLITE_OK) {
2420       librdf_log(scontext->storage->world,
2421                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2422                  "SQLite database %s finalize failed - %s (%d)",
2423                  scontext->name, errmsg, status);
2424     }
2425     result = -1;
2426   }
2427 
2428   return result;
2429 }
2430 
2431 
2432 
2433 static int
librdf_storage_sqlite_get_contexts_is_end(void * iterator)2434 librdf_storage_sqlite_get_contexts_is_end(void* iterator)
2435 {
2436   librdf_storage_sqlite_get_contexts_iterator_context* icontext;
2437 
2438   icontext = (librdf_storage_sqlite_get_contexts_iterator_context*)iterator;
2439 
2440   if(icontext->finished)
2441     return 1;
2442 
2443   if(!icontext->current) {
2444     int result;
2445 
2446     result = librdf_storage_sqlite_get_next_context_common(icontext->sqlite_context,
2447                                                          icontext->vm,
2448                                                          &icontext->current);
2449     if(result) {
2450       /* error or finished */
2451       if(result < 0)
2452         icontext->vm = NULL;
2453       icontext->finished = 1;
2454     }
2455   }
2456 
2457 
2458   return icontext->finished;
2459 }
2460 
2461 
2462 static int
librdf_storage_sqlite_get_contexts_next_method(void * iterator)2463 librdf_storage_sqlite_get_contexts_next_method(void* iterator)
2464 {
2465   librdf_storage_sqlite_get_contexts_iterator_context* icontext;
2466   int result;
2467 
2468   icontext = (librdf_storage_sqlite_get_contexts_iterator_context*)iterator;
2469 
2470   if(icontext->finished)
2471     return 1;
2472 
2473   result = librdf_storage_sqlite_get_next_context_common(icontext->sqlite_context,
2474                                                          icontext->vm,
2475                                                          &icontext->current);
2476   if(result) {
2477     /* error or finished */
2478     if(result < 0)
2479       icontext->vm = NULL;
2480     icontext->finished = 1;
2481   }
2482 
2483   return result;
2484 }
2485 
2486 
2487 static void*
librdf_storage_sqlite_get_contexts_get_method(void * iterator,int flags)2488 librdf_storage_sqlite_get_contexts_get_method(void* iterator, int flags)
2489 {
2490   librdf_storage_sqlite_get_contexts_iterator_context* icontext;
2491   void *result = NULL;
2492 
2493   icontext = (librdf_storage_sqlite_get_contexts_iterator_context*)iterator;
2494 
2495   switch(flags) {
2496     case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
2497       return icontext->current;
2498       break;
2499 
2500     case LIBRDF_ITERATOR_GET_METHOD_GET_KEY:
2501     case LIBRDF_ITERATOR_GET_METHOD_GET_VALUE:
2502       result = NULL;
2503       break;
2504 
2505     default:
2506       librdf_log(icontext->storage->world,
2507                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2508                  "Unknown iterator method flag %d", flags);
2509       result = NULL;
2510       break;
2511   }
2512 
2513   return result;
2514 }
2515 
2516 
2517 static void
librdf_storage_sqlite_get_contexts_finished(void * iterator)2518 librdf_storage_sqlite_get_contexts_finished(void* iterator)
2519 {
2520   librdf_storage_sqlite_get_contexts_iterator_context* icontext;
2521 
2522   icontext = (librdf_storage_sqlite_get_contexts_iterator_context*)iterator;
2523 
2524   if(icontext->vm) {
2525     char *errmsg = NULL;
2526     int status;
2527 
2528     status = sqlite3_finalize(icontext->vm);
2529     if(status != SQLITE_OK)
2530       errmsg = (char*)sqlite3_errmsg(icontext->sqlite_context->db);
2531 
2532     if(status != SQLITE_OK) {
2533       librdf_log(icontext->storage->world,
2534                  0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2535                  "SQLite database %s finalize failed - %s (%d)",
2536                  icontext->sqlite_context->name, errmsg, status);
2537     }
2538   }
2539 
2540   if(icontext->storage)
2541     librdf_storage_remove_reference(icontext->storage);
2542 
2543   if(icontext->current)
2544     librdf_free_node(icontext->current);
2545 
2546   LIBRDF_FREE(librdf_storage_sqlite_get_contexts_iterator_context, icontext);
2547 }
2548 
2549 
2550 /**
2551  * librdf_storage_sqlite_context_get_contexts:
2552  * @storage: #librdf_storage object
2553  *
2554  * Sqlite all context nodes in a storage.
2555  *
2556  * Return value: #librdf_iterator of context_nodes or NULL on failure or no contexts
2557  **/
2558 static librdf_iterator*
librdf_storage_sqlite_get_contexts(librdf_storage * storage)2559 librdf_storage_sqlite_get_contexts(librdf_storage* storage)
2560 {
2561   librdf_storage_sqlite_instance* context;
2562   librdf_storage_sqlite_get_contexts_iterator_context* icontext;
2563   int status;
2564   char *errmsg = NULL;
2565   raptor_stringbuffer *sb;
2566   unsigned char *request;
2567   librdf_iterator* iterator;
2568 
2569   context = (librdf_storage_sqlite_instance*)storage->instance;
2570 
2571   icontext = LIBRDF_CALLOC(librdf_storage_sqlite_get_contexts_iterator_context*,
2572                            1, sizeof(*icontext));
2573   if(!icontext)
2574     return NULL;
2575 
2576   icontext->sqlite_context = context;
2577 
2578   sb = raptor_new_stringbuffer();
2579   if(!sb) {
2580     LIBRDF_FREE(librdf_storage_sqlite_get_contexts_iterator_context, icontext);
2581     return NULL;
2582   }
2583 
2584   raptor_stringbuffer_append_string(sb, (unsigned char*)
2585                                     "SELECT DISTINCT uris.uri", 1);
2586   raptor_stringbuffer_append_counted_string(sb,
2587                                             (const unsigned char*)" FROM ", 6, 1);
2588   raptor_stringbuffer_append_string(sb,
2589                                     (const unsigned char*)sqlite_tables[TABLE_TRIPLES].name, 1);
2590   raptor_stringbuffer_append_string(sb,
2591                                     (const unsigned char*)" LEFT JOIN uris ON uris.id = contextUri WHERE contextUri NOT NULL;", 1);
2592 
2593   request = raptor_stringbuffer_as_string(sb);
2594   if(!request) {
2595     raptor_free_stringbuffer(sb);
2596     LIBRDF_FREE(librdf_storage_sqlite_get_contexts_iterator_context, icontext);
2597     return NULL;
2598   }
2599 
2600 #if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 2
2601   LIBRDF_DEBUG2("SQLite prepare '%s'\n", request);
2602 #endif
2603 
2604   status = sqlite3_prepare(context->db,
2605                            (const char*)request,
2606                            LIBRDF_GOOD_CAST(int, raptor_stringbuffer_length(sb)),
2607                            &icontext->vm,
2608                            &icontext->zTail);
2609   if(status != SQLITE_OK)
2610     errmsg = (char*)sqlite3_errmsg(context->db);
2611 
2612   raptor_free_stringbuffer(sb);
2613 
2614   if(status != SQLITE_OK) {
2615     librdf_log(storage->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
2616                "SQLite database %s SQL compile failed - %s (%d)",
2617                context->name, errmsg, status);
2618 
2619     librdf_storage_sqlite_get_contexts_finished((void*)icontext);
2620     return NULL;
2621   }
2622 
2623   icontext->storage = storage;
2624   librdf_storage_add_reference(icontext->storage);
2625 
2626   iterator = librdf_new_iterator(storage->world,
2627                                  (void*)icontext,
2628                                  &librdf_storage_sqlite_get_contexts_is_end,
2629                                  &librdf_storage_sqlite_get_contexts_next_method,
2630                                  &librdf_storage_sqlite_get_contexts_get_method,
2631                                  &librdf_storage_sqlite_get_contexts_finished);
2632   if(!iterator)
2633     librdf_storage_sqlite_get_contexts_finished(icontext);
2634   return iterator;
2635 }
2636 
2637 
2638 
2639 /**
2640  * librdf_storage_sqlite_get_feature:
2641  * @storage: #librdf_storage object
2642  * @feature: #librdf_uri feature property
2643  *
2644  * Get the value of a storage feature.
2645  *
2646  * Return value: #librdf_node feature value or NULL if no such feature
2647  * exists or the value is empty.
2648  **/
2649 static librdf_node*
librdf_storage_sqlite_get_feature(librdf_storage * storage,librdf_uri * feature)2650 librdf_storage_sqlite_get_feature(librdf_storage* storage, librdf_uri* feature)
2651 {
2652   /* librdf_storage_sqlite_instance* scontext; */
2653   unsigned char *uri_string;
2654 
2655   /* scontext = (librdf_storage_sqlite_instance*)storage->instance; */
2656 
2657   if(!feature)
2658     return NULL;
2659 
2660   uri_string = librdf_uri_as_string(feature);
2661   if(!uri_string)
2662     return NULL;
2663 
2664   if(!strcmp((const char*)uri_string, LIBRDF_MODEL_FEATURE_CONTEXTS)) {
2665     return librdf_new_node_from_typed_literal(storage->world,
2666                                               (const unsigned char*)"1",
2667                                               NULL, NULL);
2668   }
2669 
2670   return NULL;
2671 }
2672 
2673 
2674 /**
2675  * librdf_storage_sqlite_transaction_start:
2676  * @storage: #librdf_storage object
2677  *
2678  * Start a new transaction unless one is already active.
2679  *
2680  * Return value: 0 if transaction successfully started, non-0 on error
2681  * (including a transaction already active)
2682  **/
2683 static int
librdf_storage_sqlite_transaction_start(librdf_storage * storage)2684 librdf_storage_sqlite_transaction_start(librdf_storage *storage)
2685 {
2686   librdf_storage_sqlite_instance* context;
2687   int rc;
2688 
2689   context = (librdf_storage_sqlite_instance* )storage->instance;
2690 
2691   if(context->in_transaction)
2692     return 1;
2693 
2694   rc = librdf_storage_sqlite_exec(storage,
2695                                   (unsigned char *)"BEGIN IMMEDIATE;",
2696                                   NULL, NULL, 0);
2697   if(!rc)
2698     context->in_transaction = 1;
2699 
2700   return rc;
2701 }
2702 
2703 
2704 /**
2705  * librdf_storage_sqlite_transaction_commit:
2706  * @storage: #librdf_storage object
2707  *
2708  * Commit an active transaction.
2709  *
2710  * Return value: 0 if transaction successfully committed, non-0 on error
2711  * (including no transaction active)
2712  **/
2713 static int
librdf_storage_sqlite_transaction_commit(librdf_storage * storage)2714 librdf_storage_sqlite_transaction_commit(librdf_storage *storage)
2715 {
2716   librdf_storage_sqlite_instance* context;
2717   int rc;
2718 
2719   context = (librdf_storage_sqlite_instance* )storage->instance;
2720 
2721   if(!context->in_transaction)
2722     return 1;
2723 
2724   rc = librdf_storage_sqlite_exec(storage,
2725                                   (unsigned char *)"END;",
2726                                   NULL, NULL, 0);
2727   if(!rc)
2728     context->in_transaction = 0;
2729 
2730   return rc;
2731 }
2732 
2733 
2734 /**
2735  * librdf_storage_sqlite_transaction_rollback:
2736  * @storage: #librdf_storage object
2737  *
2738  * Roll back an active transaction.
2739  *
2740  * Return value: 0 if transaction successfully committed, non-0 on error
2741  * (including no transaction active)
2742  **/
2743 static int
librdf_storage_sqlite_transaction_rollback(librdf_storage * storage)2744 librdf_storage_sqlite_transaction_rollback(librdf_storage *storage)
2745 {
2746   librdf_storage_sqlite_instance* context;
2747   int rc;
2748 
2749   context = (librdf_storage_sqlite_instance* )storage->instance;
2750 
2751   if(!context->in_transaction)
2752     return 1;
2753 
2754   rc = librdf_storage_sqlite_exec(storage,
2755                                   (unsigned char *)"ROLLBACK;",
2756                                   NULL, NULL, 0);
2757   if(!rc)
2758     context->in_transaction = 0;
2759 
2760   return rc;
2761 }
2762 
2763 
2764 static void
librdf_storage_sqlite_query_flush(librdf_storage * storage)2765 librdf_storage_sqlite_query_flush(librdf_storage *storage)
2766 {
2767   librdf_storage_sqlite_query *query;
2768   librdf_storage_sqlite_instance* context;
2769   int begin;
2770 
2771   if(!storage)
2772     return;
2773 
2774   context = (librdf_storage_sqlite_instance*)storage->instance;
2775 
2776   if(!context->in_stream_queries)
2777     return;
2778 
2779   /* returns non-0 if a transaction is already active */
2780   begin = librdf_storage_sqlite_transaction_start(storage);
2781 
2782   while(context->in_stream_queries) {
2783     query = context->in_stream_queries;
2784     context->in_stream_queries = query->next;
2785 
2786     librdf_storage_sqlite_exec(storage, query->query, NULL, NULL, 0);
2787 
2788     LIBRDF_FREE(char*, query->query);
2789     LIBRDF_FREE(librdf_storage_sqlite_query, query);
2790   }
2791 
2792   if(!begin)
2793     librdf_storage_sqlite_transaction_commit(storage);
2794 }
2795 
2796 
2797 /** Local entry point for dynamically loaded storage module */
2798 static void
librdf_storage_sqlite_register_factory(librdf_storage_factory * factory)2799 librdf_storage_sqlite_register_factory(librdf_storage_factory *factory)
2800 {
2801   LIBRDF_ASSERT_CONDITION(!strcmp(factory->name, "sqlite"));
2802 
2803   factory->version            = LIBRDF_STORAGE_INTERFACE_VERSION;
2804   factory->init               = librdf_storage_sqlite_init;
2805   factory->terminate          = librdf_storage_sqlite_terminate;
2806   factory->open               = librdf_storage_sqlite_open;
2807   factory->close              = librdf_storage_sqlite_close;
2808   factory->size               = librdf_storage_sqlite_size;
2809   factory->add_statement      = librdf_storage_sqlite_add_statement;
2810   factory->add_statements     = librdf_storage_sqlite_add_statements;
2811   factory->remove_statement   = librdf_storage_sqlite_remove_statement;
2812   factory->contains_statement = librdf_storage_sqlite_contains_statement;
2813   factory->serialise          = librdf_storage_sqlite_serialise;
2814   factory->find_statements    = librdf_storage_sqlite_find_statements;
2815   factory->context_add_statement    = librdf_storage_sqlite_context_add_statement;
2816   factory->context_remove_statement = librdf_storage_sqlite_context_remove_statement;
2817   factory->context_remove_statements = librdf_storage_sqlite_context_remove_statements;
2818   factory->context_serialise        = librdf_storage_sqlite_context_serialise;
2819   factory->get_contexts             = librdf_storage_sqlite_get_contexts;
2820   factory->get_feature              = librdf_storage_sqlite_get_feature;
2821   factory->transaction_start        = librdf_storage_sqlite_transaction_start;
2822   factory->transaction_commit       = librdf_storage_sqlite_transaction_commit;
2823   factory->transaction_rollback     = librdf_storage_sqlite_transaction_rollback;
2824 }
2825 
2826 #ifdef MODULAR_LIBRDF
2827 
2828 /** Entry point for dynamically loaded storage module */
2829 void
librdf_storage_module_register_factory(librdf_world * world)2830 librdf_storage_module_register_factory(librdf_world *world)
2831 {
2832   librdf_storage_register_factory(world, "sqlite", "SQLite",
2833                                   &librdf_storage_sqlite_register_factory);
2834 }
2835 
2836 #else
2837 
2838 /*
2839  * librdf_init_storage_sqlite:
2840  * @world: world object
2841  *
2842  * INTERNAL - Initialise the built-in storage_sqlite module.
2843  */
2844 void
librdf_init_storage_sqlite(librdf_world * world)2845 librdf_init_storage_sqlite(librdf_world *world)
2846 {
2847   librdf_storage_register_factory(world, "sqlite", "SQLite",
2848                                   &librdf_storage_sqlite_register_factory);
2849 }
2850 
2851 #endif
2852 
2853