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