1 /*
2 ##############################################################################
3 # Copyright (c) 2000-2006 All rights reserved
4 # Alberto Reggiori <areggiori@webweaving.org>
5 # Dirk-Willem van Gulik <dirkx@webweaving.org>
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # 1. Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 #
14 # 2. Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in
16 # the documentation and/or other materials provided with the
17 # distribution.
18 #
19 # 3. The end-user documentation included with the redistribution,
20 # if any, must include the following acknowledgment:
21 # "This product includes software developed by
22 # Alberto Reggiori <areggiori@webweaving.org> and
23 # Dirk-Willem van Gulik <dirkx@webweaving.org>."
24 # Alternately, this acknowledgment may appear in the software itself,
25 # if and wherever such third-party acknowledgments normally appear.
26 #
27 # 4. All advertising materials mentioning features or use of this software
28 # must display the following acknowledgement:
29 # This product includes software developed by the University of
30 # California, Berkeley and its contributors.
31 #
32 # 5. Neither the name of the University nor the names of its contributors
33 # may be used to endorse or promote products derived from this software
34 # without specific prior written permission.
35 #
36 # 6. Products derived from this software may not be called "RDFStore"
37 # nor may "RDFStore" appear in their names without prior written
38 # permission.
39 #
40 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41 # ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44 # FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 # OF THE POSSIBILITY OF SUCH DAMAGE.
52 #
53 # ====================================================================
54 #
55 # This software consists of work developed by Alberto Reggiori and
56 # Dirk-Willem van Gulik. The RDF specific part is based based on public
57 # domain software written at the Stanford University Database Group by
58 # Sergey Melnik. For more information on the RDF API Draft work,
59 # please see <http://www-db.stanford.edu/~melnik/rdf/api.html>
60 # The DBMS TCP/IP server part is based on software originally written
61 # by Dirk-Willem van Gulik for Web Weaving Internet Engineering m/v Enschede,
62 # The Netherlands.
63 #
64 ##############################################################################
65 #
66 # $Id: rdfstore_iterator.c,v 1.16 2006/06/19 10:10:21 areggiori Exp $
67 #
68 */
69
70 #if !defined(WIN32)
71 #include <sys/param.h>
72 #endif
73
74 #include <sys/types.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <errno.h>
78 #include <strings.h>
79 #include <fcntl.h>
80
81 #include <time.h>
82 #include <sys/stat.h>
83
84 #include "rdfstore_log.h"
85 #include "rdfstore.h"
86 #include "rdfstore_iterator.h"
87 #include "rdfstore_serializer.h"
88 #include "rdfstore_digest.h"
89 #include "rdfstore_bits.h"
90 #include "rdfstore_utf8.h"
91
92 /*
93 #define RDFSTORE_DEBUG
94 */
95
96 RDF_Statement *
97 rdfstore_iterator_fetch_statement (
98 rdfstore_iterator * me
99 );
100
rdfstore_iterator_close(rdfstore_iterator * me)101 int rdfstore_iterator_close (
102 rdfstore_iterator * me
103 ) {
104 if ( ( me != NULL ) &&
105 ( me->store != NULL ) &&
106 ( me->store->cursor != NULL ) &&
107 ( me != me->store->cursor ) ) { /* do not touch internal cursors - still needed????!!??! */
108 me->store->attached--; /* detach myself from the storage */
109
110 /* dispose the storage (if possible) */
111 if ( me->store->tobeclosed ) {
112 #ifdef RDFSTORE_DEBUG
113 printf(">>>>>>>>>>>>>>>>>>>>%p GOING TO CLOSE\n",me->store);
114 #endif
115 rdfstore_disconnect( me->store );
116 };
117
118 RDFSTORE_FREE( me );
119 me = NULL;
120
121 return 1;
122 } else {
123 return 0;
124 };
125 };
126
rdfstore_iterator_hasnext(rdfstore_iterator * me)127 int rdfstore_iterator_hasnext (
128 rdfstore_iterator * me
129 ) {
130 if ( me == NULL )
131 return 0;
132 #ifdef RDFSTORE_DEBUG
133 printf("HASNEXT %d < %d\n",me->st_counter, me->size);
134 #endif
135 if ( me->st_counter < me->size ) {
136 return 1;
137 } else {
138 return 0;
139 };
140 };
141
142 RDF_Statement *
rdfstore_iterator_next(rdfstore_iterator * me)143 rdfstore_iterator_next (
144 rdfstore_iterator * me
145 ) {
146 RDF_Statement * s=NULL;
147
148 if ( me == NULL )
149 return NULL;
150
151 /* advance to the next item */
152 me->st_counter++;
153
154 /* get the next one if any */
155 me->pos++;
156 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
157 return NULL;
158
159 #ifdef RDFSTORE_DEBUG
160 printf("rdfstore_iterator_next( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
161 #endif
162
163 s = rdfstore_iterator_fetch_statement ( me );
164
165 #ifdef RDFSTORE_DEBUG
166 if (s != NULL ){
167 fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
168 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
169 if ( s->object->type != 1 ) {
170 fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
171 } else {
172 fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
173 };
174 if ( s->context != NULL )
175 fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
176 if ( s->node != NULL )
177 fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
178 };
179 #endif
180
181 return s;
182 };
183
184 RDF_Node *
rdfstore_iterator_next_subject(rdfstore_iterator * me)185 rdfstore_iterator_next_subject (
186 rdfstore_iterator * me
187 ) {
188 RDF_Statement * s=NULL;
189 RDF_Node * r=NULL;
190
191 if ( me == NULL )
192 return NULL;
193 /* advance to the next item */
194 me->st_counter++;
195
196 /* get the next one if any */
197 me->pos++;
198 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
199 return NULL;
200
201 s = rdfstore_iterator_fetch_statement ( me );
202
203 if ( s != NULL ) {
204 r = s->subject;
205
206 RDFSTORE_FREE( s->predicate->value.resource.identifier );
207 RDFSTORE_FREE( s->predicate );
208 if ( s->object->type == 1 ) {
209 if ( s->object->value.literal.dataType != NULL )
210 RDFSTORE_FREE( s->object->value.literal.dataType );
211 RDFSTORE_FREE( s->object->value.literal.string );
212 } else {
213 RDFSTORE_FREE( s->object->value.resource.identifier );
214 };
215 RDFSTORE_FREE( s->object );
216 if ( s->context != NULL ) {
217 RDFSTORE_FREE( s->context->value.resource.identifier );
218 RDFSTORE_FREE( s->context );
219 };
220 if ( s->node != NULL ) {
221 RDFSTORE_FREE( s->node->value.resource.identifier );
222 RDFSTORE_FREE( s->node );
223 };
224 RDFSTORE_FREE( s );
225 };
226
227 return r;
228 };
229
230 RDF_Node *
rdfstore_iterator_next_predicate(rdfstore_iterator * me)231 rdfstore_iterator_next_predicate (
232 rdfstore_iterator * me
233 ) {
234 RDF_Statement * s=NULL;
235 RDF_Node * r=NULL;
236
237 if ( me == NULL )
238 return NULL;
239
240 /* advance to the next item */
241 me->st_counter++;
242
243 /* get the next one if any */
244 me->pos++;
245 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
246 return NULL;
247
248 s = rdfstore_iterator_fetch_statement ( me );
249
250 if ( s != NULL ) {
251 RDFSTORE_FREE( s->subject->value.resource.identifier );
252 RDFSTORE_FREE( s->subject );
253
254 r = s->predicate;
255
256 if ( s->object->type == 1 ) {
257 if ( s->object->value.literal.dataType != NULL )
258 RDFSTORE_FREE( s->object->value.literal.dataType );
259 RDFSTORE_FREE( s->object->value.literal.string );
260 } else {
261 RDFSTORE_FREE( s->object->value.resource.identifier );
262 };
263 RDFSTORE_FREE( s->object );
264 if ( s->context != NULL ) {
265 RDFSTORE_FREE( s->context->value.resource.identifier );
266 RDFSTORE_FREE( s->context );
267 };
268 if ( s->node != NULL ) {
269 RDFSTORE_FREE( s->node->value.resource.identifier );
270 RDFSTORE_FREE( s->node );
271 };
272 RDFSTORE_FREE( s );
273 };
274
275 return r;
276 };
277
278 RDF_Node *
rdfstore_iterator_next_object(rdfstore_iterator * me)279 rdfstore_iterator_next_object (
280 rdfstore_iterator * me
281 ) {
282 RDF_Statement * s=NULL;
283 RDF_Node * p=NULL;
284
285 if ( me == NULL )
286 return NULL;
287
288 /* advance to the next item */
289 me->st_counter++;
290
291 /* get the next one if any */
292 me->pos++;
293 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
294 return NULL;
295
296 s = rdfstore_iterator_fetch_statement ( me );
297
298 if ( s != NULL ) {
299 RDFSTORE_FREE( s->subject->value.resource.identifier );
300 RDFSTORE_FREE( s->subject );
301 RDFSTORE_FREE( s->predicate->value.resource.identifier );
302 RDFSTORE_FREE( s->predicate );
303
304 p = s->object;
305
306 if ( s->context != NULL ) {
307 RDFSTORE_FREE( s->context->value.resource.identifier );
308 RDFSTORE_FREE( s->context );
309 };
310 if ( s->node != NULL ) {
311 RDFSTORE_FREE( s->node->value.resource.identifier );
312 RDFSTORE_FREE( s->node );
313 };
314 RDFSTORE_FREE( s );
315 };
316
317 return p;
318 };
319
320 RDF_Node *
rdfstore_iterator_next_context(rdfstore_iterator * me)321 rdfstore_iterator_next_context (
322 rdfstore_iterator * me
323 ) {
324 RDF_Statement * s=NULL;
325 RDF_Node * r=NULL;
326
327 if ( me == NULL )
328 return NULL;
329
330 /* advance to the next item */
331 me->st_counter++;
332
333 /* get the next one if any */
334 me->pos++;
335 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
336 return NULL;
337
338 s = rdfstore_iterator_fetch_statement ( me );
339
340 if ( s != NULL ) {
341 RDFSTORE_FREE( s->subject->value.resource.identifier );
342 RDFSTORE_FREE( s->subject );
343 RDFSTORE_FREE( s->predicate->value.resource.identifier );
344 RDFSTORE_FREE( s->predicate );
345 if ( s->object->type == 1 ) {
346 if ( s->object->value.literal.dataType != NULL )
347 RDFSTORE_FREE( s->object->value.literal.dataType );
348 RDFSTORE_FREE( s->object->value.literal.string );
349 } else {
350 RDFSTORE_FREE( s->object->value.resource.identifier );
351 };
352 RDFSTORE_FREE( s->object );
353
354 r = s->context;
355
356 if ( s->node != NULL ) {
357 RDFSTORE_FREE( s->node->value.resource.identifier );
358 RDFSTORE_FREE( s->node );
359 };
360 RDFSTORE_FREE( s );
361 };
362
363 return r;
364 };
365
366 RDF_Statement *
rdfstore_iterator_current(rdfstore_iterator * me)367 rdfstore_iterator_current (
368 rdfstore_iterator * me
369 ) {
370 if ( me == NULL )
371 return NULL;
372 return rdfstore_iterator_fetch_statement ( me );
373 };
374
375 RDF_Node *
rdfstore_iterator_current_subject(rdfstore_iterator * me)376 rdfstore_iterator_current_subject (
377 rdfstore_iterator * me
378 ) {
379 RDF_Statement * s=NULL;
380 RDF_Node * r=NULL;
381
382 if ( me == NULL )
383 return NULL;
384
385 s = rdfstore_iterator_fetch_statement ( me );
386
387 if ( s != NULL ) {
388 r = s->subject;
389
390 RDFSTORE_FREE( s->predicate->value.resource.identifier );
391 RDFSTORE_FREE( s->predicate );
392 if ( s->object->type == 1 ) {
393 if ( s->object->value.literal.dataType != NULL )
394 RDFSTORE_FREE( s->object->value.literal.dataType );
395 RDFSTORE_FREE( s->object->value.literal.string );
396 } else {
397 RDFSTORE_FREE( s->object->value.resource.identifier );
398 };
399 RDFSTORE_FREE( s->object );
400 if ( s->context != NULL ) {
401 RDFSTORE_FREE( s->context->value.resource.identifier );
402 RDFSTORE_FREE( s->context );
403 };
404 if ( s->node != NULL ) {
405 RDFSTORE_FREE( s->node->value.resource.identifier );
406 RDFSTORE_FREE( s->node );
407 };
408 RDFSTORE_FREE( s );
409 };
410
411 return r;
412 };
413
414 RDF_Node *
rdfstore_iterator_current_predicate(rdfstore_iterator * me)415 rdfstore_iterator_current_predicate (
416 rdfstore_iterator * me
417 ) {
418 RDF_Statement * s=NULL;
419 RDF_Node * r=NULL;
420
421 if ( me == NULL )
422 return NULL;
423
424 s = rdfstore_iterator_fetch_statement ( me );
425
426 if ( s != NULL ) {
427 RDFSTORE_FREE( s->subject->value.resource.identifier );
428 RDFSTORE_FREE( s->subject );
429
430 r = s->predicate;
431
432 if ( s->object->type == 1 ) {
433 if ( s->object->value.literal.dataType != NULL )
434 RDFSTORE_FREE( s->object->value.literal.dataType );
435 RDFSTORE_FREE( s->object->value.literal.string );
436 } else {
437 RDFSTORE_FREE( s->object->value.resource.identifier );
438 };
439 RDFSTORE_FREE( s->object );
440 if ( s->context != NULL ) {
441 RDFSTORE_FREE( s->context->value.resource.identifier );
442 RDFSTORE_FREE( s->context );
443 };
444 if ( s->node != NULL ) {
445 RDFSTORE_FREE( s->node->value.resource.identifier );
446 RDFSTORE_FREE( s->node );
447 };
448 RDFSTORE_FREE( s );
449 };
450
451 return r;
452 };
453
454 RDF_Node *
rdfstore_iterator_current_object(rdfstore_iterator * me)455 rdfstore_iterator_current_object (
456 rdfstore_iterator * me
457 ) {
458 RDF_Statement * s=NULL;
459 RDF_Node * p=NULL;
460
461 if ( me == NULL )
462 return NULL;
463
464 s = rdfstore_iterator_fetch_statement ( me );
465
466 if ( s != NULL ) {
467 RDFSTORE_FREE( s->subject->value.resource.identifier );
468 RDFSTORE_FREE( s->subject );
469 RDFSTORE_FREE( s->predicate->value.resource.identifier );
470 RDFSTORE_FREE( s->predicate );
471
472 p = s->object;
473
474 if ( s->context != NULL ) {
475 RDFSTORE_FREE( s->context->value.resource.identifier );
476 RDFSTORE_FREE( s->context );
477 };
478 if ( s->node != NULL ) {
479 RDFSTORE_FREE( s->node->value.resource.identifier );
480 RDFSTORE_FREE( s->node );
481 };
482 RDFSTORE_FREE( s );
483 };
484
485 return p;
486 };
487
488 RDF_Node *
rdfstore_iterator_current_context(rdfstore_iterator * me)489 rdfstore_iterator_current_context (
490 rdfstore_iterator * me
491 ) {
492 RDF_Statement * s=NULL;
493 RDF_Node * r=NULL;
494
495 if ( me == NULL )
496 return NULL;
497
498 s = rdfstore_iterator_fetch_statement ( me );
499
500 if ( s != NULL ) {
501 RDFSTORE_FREE( s->subject->value.resource.identifier );
502 RDFSTORE_FREE( s->subject );
503 RDFSTORE_FREE( s->predicate->value.resource.identifier );
504 RDFSTORE_FREE( s->predicate );
505 if ( s->object->type == 1 ) {
506 if ( s->object->value.literal.dataType != NULL )
507 RDFSTORE_FREE( s->object->value.literal.dataType );
508 RDFSTORE_FREE( s->object->value.literal.string );
509 } else {
510 RDFSTORE_FREE( s->object->value.resource.identifier );
511 };
512 RDFSTORE_FREE( s->object );
513
514 r = s->context;
515
516 if ( s->node != NULL ) {
517 RDFSTORE_FREE( s->node->value.resource.identifier );
518 RDFSTORE_FREE( s->node );
519 };
520 RDFSTORE_FREE( s );
521 };
522
523 return r;
524 };
525
526 /* the following 4 methods reset the iterator and return the first item in the list */
527 RDF_Statement *
rdfstore_iterator_first(rdfstore_iterator * me)528 rdfstore_iterator_first (
529 rdfstore_iterator * me
530 ) {
531 RDF_Statement * s=NULL;
532 if ( me == NULL )
533 return NULL;
534
535 /* reset iterator */
536 me->st_counter = 0;
537
538 /* get the first one if any */
539 me->pos = 0;
540 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
541 return NULL;
542
543 #ifdef RDFSTORE_DEBUG
544 printf("rdfstore_iterator_first( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
545 #endif
546
547 s = rdfstore_iterator_current ( me );
548
549 #ifdef RDFSTORE_DEBUG
550 if (s != NULL ){
551 fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
552 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
553 if ( s->object->type != 1 ) {
554 fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
555 } else {
556 fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
557 };
558 if ( s->context != NULL )
559 fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
560 if ( s->node != NULL )
561 fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
562 };
563 #endif
564
565 return s;
566 };
567
568 RDF_Node *
rdfstore_iterator_first_subject(rdfstore_iterator * me)569 rdfstore_iterator_first_subject (
570 rdfstore_iterator * me
571 ) {
572 if ( me == NULL )
573 return NULL;
574
575 /* reset iterator */
576 me->st_counter = 0;
577
578 /* get the first one if any */
579 me->pos = 0;
580 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
581 return NULL;
582
583 return rdfstore_iterator_current_subject ( me );
584 };
585
586 RDF_Node *
rdfstore_iterator_first_predicate(rdfstore_iterator * me)587 rdfstore_iterator_first_predicate (
588 rdfstore_iterator * me
589 ) {
590 if ( me == NULL )
591 return NULL;
592
593 /* reset iterator */
594 me->st_counter = 0;
595
596 /* get the first one if any */
597 me->pos = 0;
598 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
599 return NULL;
600
601 return rdfstore_iterator_current_predicate ( me );
602 };
603
604 RDF_Node *
rdfstore_iterator_first_object(rdfstore_iterator * me)605 rdfstore_iterator_first_object (
606 rdfstore_iterator * me
607 ) {
608 if ( me == NULL )
609 return NULL;
610
611 /* reset iterator */
612 me->st_counter = 0;
613
614 /* get the first one if any */
615 me->pos = 0;
616 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
617 return NULL;
618
619 return rdfstore_iterator_current_object ( me );
620 };
621
622 RDF_Node *
rdfstore_iterator_first_context(rdfstore_iterator * me)623 rdfstore_iterator_first_context (
624 rdfstore_iterator * me
625 ) {
626 if ( me == NULL )
627 return NULL;
628
629 /* reset iterator */
630 me->st_counter = 0;
631
632 /* get the first one if any */
633 me->pos = 0;
634 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
635 return NULL;
636
637 return rdfstore_iterator_current_context ( me );
638 };
639
640 /* return items one by one till the end; then reset and return undef i.e. while( s = rdfstore_iterator_each(me) ) { ..... }; */
641 RDF_Statement *
rdfstore_iterator_each(rdfstore_iterator * me)642 rdfstore_iterator_each (
643 rdfstore_iterator * me
644 ) {
645 RDF_Statement * s=NULL;
646
647 if ( me == NULL )
648 return NULL;
649
650 if (! rdfstore_iterator_hasnext( me ) ) {
651 /* reset and return undef */
652 me->st_counter = 0;
653 me->pos = 0;
654 return NULL;
655 };
656
657 /* set pos to the current one */
658 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
659 /* reset and return undef */
660 me->st_counter = 0;
661 me->pos = 0;
662 return NULL; /* but this is an error not end of iteration! */
663 };
664
665 #ifdef RDFSTORE_DEBUG
666 printf("rdfstore_iterator_each( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
667 #endif
668
669 s = rdfstore_iterator_fetch_statement ( me );
670
671 if ( s == NULL ) {
672 /* reset and return undef */
673 me->st_counter = 0;
674 me->pos = 0;
675 return NULL; /* but this is an error not end of iteration! */
676 };
677
678 /* hop to the next one if any */
679 me->st_counter++;
680 me->pos++;
681
682 #ifdef RDFSTORE_DEBUG
683 if (s != NULL ){
684 fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
685 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
686 if ( s->object->type != 1 ) {
687 fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
688 } else {
689 fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
690 };
691 if ( s->context != NULL )
692 fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
693 if ( s->node != NULL )
694 fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
695 };
696 #endif
697
698 return s;
699 };
700
701 RDF_Node *
rdfstore_iterator_each_subject(rdfstore_iterator * me)702 rdfstore_iterator_each_subject (
703 rdfstore_iterator * me
704 ) {
705 RDF_Statement * s=NULL;
706 RDF_Node * r=NULL;
707
708 if ( me == NULL )
709 return NULL;
710
711 if (! rdfstore_iterator_hasnext( me ) ) {
712 /* reset and return undef */
713 me->st_counter = 0;
714 me->pos = 0;
715 return NULL;
716 };
717
718 /* set pos to the current one */
719 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
720 /* reset and return undef */
721 me->st_counter = 0;
722 me->pos = 0;
723 return NULL; /* but this is an error not end of iteration! */
724 };
725
726 s = rdfstore_iterator_fetch_statement ( me );
727
728 if ( s != NULL ) {
729 r = s->subject;
730
731 RDFSTORE_FREE( s->predicate->value.resource.identifier );
732 RDFSTORE_FREE( s->predicate );
733 if ( s->object->type == 1 ) {
734 if ( s->object->value.literal.dataType != NULL )
735 RDFSTORE_FREE( s->object->value.literal.dataType );
736 RDFSTORE_FREE( s->object->value.literal.string );
737 } else {
738 RDFSTORE_FREE( s->object->value.resource.identifier );
739 };
740 RDFSTORE_FREE( s->object );
741 if ( s->context != NULL ) {
742 RDFSTORE_FREE( s->context->value.resource.identifier );
743 RDFSTORE_FREE( s->context );
744 };
745 if ( s->node != NULL ) {
746 RDFSTORE_FREE( s->node->value.resource.identifier );
747 RDFSTORE_FREE( s->node );
748 };
749 RDFSTORE_FREE( s );
750 };
751
752 if ( r == NULL ) {
753 /* reset and return undef */
754 me->st_counter = 0;
755 me->pos = 0;
756 return NULL; /* but this is an error not end of iteration! */
757 };
758
759 /* hop to the next one if any */
760 me->st_counter++;
761 me->pos++;
762
763 return r;
764 };
765
766 RDF_Node *
rdfstore_iterator_each_predicate(rdfstore_iterator * me)767 rdfstore_iterator_each_predicate (
768 rdfstore_iterator * me
769 ) {
770 RDF_Statement * s=NULL;
771 RDF_Node * r=NULL;
772
773 if ( me == NULL )
774 return NULL;
775
776 if (! rdfstore_iterator_hasnext( me ) ) {
777 /* reset and return undef */
778 me->st_counter = 0;
779 me->pos = 0;
780 return NULL;
781 };
782
783 /* set pos to the current one */
784 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
785 /* reset and return undef */
786 me->st_counter = 0;
787 me->pos = 0;
788 return NULL; /* but this is an error not end of iteration! */
789 };
790
791 s = rdfstore_iterator_fetch_statement ( me );
792
793 if ( s != NULL ) {
794 RDFSTORE_FREE( s->subject->value.resource.identifier );
795 RDFSTORE_FREE( s->subject );
796
797 r = s->predicate;
798
799 if ( s->object->type == 1 ) {
800 if ( s->object->value.literal.dataType != NULL )
801 RDFSTORE_FREE( s->object->value.literal.dataType );
802 RDFSTORE_FREE( s->object->value.literal.string );
803 } else {
804 RDFSTORE_FREE( s->object->value.resource.identifier );
805 };
806 RDFSTORE_FREE( s->object );
807 if ( s->context != NULL ) {
808 RDFSTORE_FREE( s->context->value.resource.identifier );
809 RDFSTORE_FREE( s->context );
810 };
811 if ( s->node != NULL ) {
812 RDFSTORE_FREE( s->node->value.resource.identifier );
813 RDFSTORE_FREE( s->node );
814 };
815 RDFSTORE_FREE( s );
816 };
817
818 if ( r == NULL ) {
819 /* reset and return undef */
820 me->st_counter = 0;
821 me->pos = 0;
822 return NULL; /* but this is an error not end of iteration! */
823 };
824
825 /* hop to the next one if any */
826 me->st_counter++;
827 me->pos++;
828
829 return r;
830 };
831
832 RDF_Node *
rdfstore_iterator_each_object(rdfstore_iterator * me)833 rdfstore_iterator_each_object (
834 rdfstore_iterator * me
835 ) {
836 RDF_Statement * s=NULL;
837 RDF_Node * p=NULL;
838
839 if ( me == NULL )
840 return NULL;
841
842 if (! rdfstore_iterator_hasnext( me ) ) {
843 /* reset and return undef */
844 me->st_counter = 0;
845 me->pos = 0;
846 return NULL;
847 };
848
849 /* set pos to the current one */
850 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
851 /* reset and return undef */
852 me->st_counter = 0;
853 me->pos = 0;
854 return NULL; /* but this is an error not end of iteration! */
855 };
856
857 s = rdfstore_iterator_fetch_statement ( me );
858
859 if ( s != NULL ) {
860 RDFSTORE_FREE( s->subject->value.resource.identifier );
861 RDFSTORE_FREE( s->subject );
862 RDFSTORE_FREE( s->predicate->value.resource.identifier );
863 RDFSTORE_FREE( s->predicate );
864
865 p = s->object;
866
867 if ( s->context != NULL ) {
868 RDFSTORE_FREE( s->context->value.resource.identifier );
869 RDFSTORE_FREE( s->context );
870 };
871 if ( s->node != NULL ) {
872 RDFSTORE_FREE( s->node->value.resource.identifier );
873 RDFSTORE_FREE( s->node );
874 };
875 RDFSTORE_FREE( s );
876 };
877
878 if ( p == NULL ) {
879 /* reset and return undef */
880 me->st_counter = 0;
881 me->pos = 0;
882 return NULL; /* but this is an error not end of iteration! */
883 };
884
885 /* hop to the next one if any */
886 me->st_counter++;
887 me->pos++;
888
889 return p;
890 };
891
892 RDF_Node *
rdfstore_iterator_each_context(rdfstore_iterator * me)893 rdfstore_iterator_each_context (
894 rdfstore_iterator * me
895 ) {
896 RDF_Statement * s=NULL;
897 RDF_Node * r=NULL;
898
899 if ( me == NULL )
900 return NULL;
901
902 if (! rdfstore_iterator_hasnext( me ) ) {
903 /* reset and return undef */
904 me->st_counter = 0;
905 me->pos = 0;
906 return NULL;
907 };
908
909 /* set pos to the current one */
910 if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
911 /* reset and return undef */
912 me->st_counter = 0;
913 me->pos = 0;
914 return NULL; /* but this is an error not end of iteration! */
915 };
916
917 s = rdfstore_iterator_fetch_statement ( me );
918
919 if ( s != NULL ) {
920 RDFSTORE_FREE( s->subject->value.resource.identifier );
921 RDFSTORE_FREE( s->subject );
922 RDFSTORE_FREE( s->predicate->value.resource.identifier );
923 RDFSTORE_FREE( s->predicate );
924 if ( s->object->type == 1 ) {
925 if ( s->object->value.literal.dataType != NULL )
926 RDFSTORE_FREE( s->object->value.literal.dataType );
927 RDFSTORE_FREE( s->object->value.literal.string );
928 } else {
929 RDFSTORE_FREE( s->object->value.resource.identifier );
930 };
931 RDFSTORE_FREE( s->object );
932
933 r = s->context;
934
935 if ( s->node != NULL ) {
936 RDFSTORE_FREE( s->node->value.resource.identifier );
937 RDFSTORE_FREE( s->node );
938 };
939 RDFSTORE_FREE( s );
940 };
941
942 if ( r == NULL ) {
943 /* reset and return undef */
944 me->st_counter = 0;
945 me->pos = 0;
946 return NULL; /* but this is an error not end of iteration! */
947 };
948
949 /* hop to the next one if any */
950 me->st_counter++;
951 me->pos++;
952
953 return r;
954 };
955
rdfstore_iterator_remove(rdfstore_iterator * me)956 int rdfstore_iterator_remove (
957 rdfstore_iterator * me
958 ) {
959
960 #ifdef RDFSTORE_DEBUG
961 {
962 int i=0;
963 printf("iterator remove ACTUAL (BEFORE remove):\n");
964 for ( i=0; i<me->ids_size; i++) {
965 printf("%02X",me->ids[i]);
966 };
967 printf("' (%d)\n",me->ids_size);
968 }
969 #endif
970
971 /* zap current pos - we do not check whether is zero already or not....yet :) */
972 if( ! rdfstore_bits_setmask(& me->ids_size, me->ids, me->pos, 1, 0, sizeof(me->ids)) )
973 return 0;
974
975 #ifdef RDFSTORE_DEBUG
976 {
977 int i=0;
978 printf("iterator remove ACTUAL (AFTER remove):\n");
979 for ( i=0; i<me->ids_size; i++) {
980 printf("%02X",me->ids[i]);
981 };
982 printf("' (%d)\n",me->ids_size);
983 }
984 #endif
985
986 me->size--;
987 me->ids_size = rdfstore_bits_shorten( me->ids_size, me->ids );
988
989 return 1;
990 };
991
992 int
rdfstore_iterator_contains(rdfstore_iterator * me,RDF_Statement * statement,RDF_Node * given_context)993 rdfstore_iterator_contains (
994 rdfstore_iterator * me,
995 RDF_Statement * statement,
996 RDF_Node * given_context
997 ) {
998 RDF_Node * context = NULL;
999 unsigned char outbuf[256];
1000 DBT key, data;
1001 unsigned int pos=0,err=0;
1002 unsigned int st_id=0;
1003 int hc=0;
1004
1005 if ( ( statement == NULL ) ||
1006 ( statement->subject == NULL ) ||
1007 ( statement->predicate == NULL ) ||
1008 ( statement->subject->value.resource.identifier == NULL ) ||
1009 ( statement->predicate->value.resource.identifier == NULL ) ||
1010 ( statement->object == NULL ) ||
1011 ( ( statement->object->type != 1 ) &&
1012 ( statement->object->value.resource.identifier == NULL ) ) ||
1013 ( ( given_context != NULL ) &&
1014 ( given_context->value.resource.identifier == NULL ) ) ||
1015 ( ( statement->node != NULL ) &&
1016 ( statement->node->value.resource.identifier == NULL ) ) )
1017 return -1;
1018
1019 if (given_context == NULL) {
1020 if (statement->context != NULL)
1021 context = statement->context;
1022 /* we do not use the default context of the store because an iterator could contain different contexts and it would mess everything up */
1023 } else {
1024 /* use given context instead */
1025 context = given_context;
1026 };
1027
1028 /* compute statement hashcode */
1029 hc = rdfstore_digest_get_statement_hashCode( statement, context );
1030
1031 /* cache the hashcode if the statement has a "proper" identity */
1032 if ( given_context == NULL )
1033 statement->hashcode = hc;
1034
1035 memset(&key, 0, sizeof(key));
1036 memset(&data, 0, sizeof(data));
1037
1038 #ifdef RDFSTORE_DEBUG
1039 {
1040 char * buff;
1041 fprintf(stderr,"ITERATOR CONTAINS:\n");
1042 fprintf(stderr,"\tS='%s'\n",statement->subject->value.resource.identifier);
1043 fprintf(stderr,"\tP='%s'\n",statement->predicate->value.resource.identifier);
1044 if ( statement->object->type != 1 ) {
1045 fprintf(stderr,"\tO='%s'\n",statement->object->value.resource.identifier);
1046 } else {
1047 fprintf(stderr,"\tOLIT='%s'\n",statement->object->value.literal.string);
1048 };
1049 if ( context != NULL ) {
1050 fprintf(stderr,"\tC='%s'\n",context->value.resource.identifier);
1051 };
1052 if ( statement->node != NULL )
1053 fprintf(stderr,"\tSRES='%s'\n",statement->node->value.resource.identifier);
1054 if( (buff=rdfstore_ntriples_statement( statement, context )) != NULL ) {
1055 fprintf(stderr," N-triples: %s\n", buff );
1056 RDFSTORE_FREE( buff );
1057 };
1058 };
1059 #endif
1060
1061 /* look for the statement internal identifier */
1062 bzero(outbuf,sizeof(int));
1063 packInt( hc, outbuf );
1064 key.data = outbuf;
1065 key.size = sizeof(int);
1066 err = rdfstore_flat_store_fetch( me->store->statements, key, &data );
1067 if(err!=0) {
1068 if (err!=FLAT_STORE_E_NOTFOUND) {
1069 perror("rdfstore_iterator_contains");
1070 fprintf(stderr,"Could not fetch key '%s' in statements for store '%s': %s\n",(char *)key.data,(me->store->name != NULL) ? me->store->name : "(in-memory)", rdfstore_flat_store_get_error( me->store->statements ) );
1071 return -1;
1072 } else {
1073 return 0;
1074 };
1075 } else {
1076 unpackInt( data.data, &st_id);
1077 RDFSTORE_FREE( data.data );
1078 pos = st_id;
1079 return ( ( rdfstore_bits_isanyset(&me->ids_size,me->ids,&pos,1) != 0 ) && /* are we sure that rdfstore_bits_isanyset() work here??!?! */
1080 ( pos == st_id ) ) ? 1 : 0;
1081 };
1082 };
1083
1084 rdfstore_iterator *
rdfstore_iterator_intersect(rdfstore_iterator * me,rdfstore_iterator * you)1085 rdfstore_iterator_intersect (
1086 rdfstore_iterator * me,
1087 rdfstore_iterator * you
1088 ) {
1089 rdfstore_iterator * results;
1090
1091 if ( ( me == NULL ) ||
1092 ( you == NULL ) )
1093 return NULL;
1094
1095 if ( me->store != you->store ) {
1096 perror("rdfstore_iterator_intersect");
1097 fprintf(stderr,"Cannot intersect cursors from different stores\n");
1098 return NULL;
1099 };
1100
1101 results = NULL;
1102 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1103 if ( results == NULL ) {
1104 perror("rdfstore_iterator_intersect");
1105 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1106 return NULL;
1107 };
1108 results->store = me->store;
1109 me->store->attached++;
1110 results->remove_holes = 0;
1111 results->st_counter = 0;
1112
1113 #ifdef RDFSTORE_DEBUG
1114 {
1115 int j;
1116 printf("rdfstore_iterator_intersect (ME bits only) '");
1117 for ( j=0; j<me->ids_size; j++) {
1118 printf("%02X",me->ids[j]);
1119 };
1120 printf("'\n");
1121 }
1122 {
1123 int j;
1124 printf("rdfstore_iterator_intersect (YOU bits only) '");
1125 for ( j=0; j<you->ids_size; j++) {
1126 printf("%02X",you->ids[j]);
1127 };
1128 printf("'\n");
1129 }
1130 #endif
1131
1132 /* A & B */
1133 results->ids_size = rdfstore_bits_and( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1134 results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1135
1136 #ifdef RDFSTORE_DEBUG
1137 {
1138 int j;
1139 printf("rdfstore_iterator_intersect (RESULTS bits only) '");
1140 for ( j=0; j<results->ids_size; j++) {
1141 printf("%02X",results->ids[j]);
1142 };
1143 printf("'\n");
1144 }
1145 #endif
1146
1147 results->size = 0;
1148 results->pos = 0;
1149 while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1150 results->pos++;
1151 results->size++;
1152 };
1153 results->pos = 0;
1154
1155 return results;
1156 };
1157
1158 rdfstore_iterator *
rdfstore_iterator_unite(rdfstore_iterator * me,rdfstore_iterator * you)1159 rdfstore_iterator_unite (
1160 rdfstore_iterator * me,
1161 rdfstore_iterator * you
1162 ) {
1163 rdfstore_iterator * results;
1164
1165 if ( ( me == NULL ) ||
1166 ( you == NULL ) )
1167 return NULL;
1168
1169 if ( me->store != you->store ) {
1170 perror("rdfstore_iterator_unite");
1171 fprintf(stderr,"Cannot unite cursors from different stores\n");
1172 return NULL;
1173 };
1174
1175 results = NULL;
1176 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1177 if ( results == NULL ) {
1178 perror("rdfstore_iterator_unite");
1179 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1180 return NULL;
1181 };
1182 results->store = me->store;
1183 me->store->attached++;
1184 results->remove_holes = 0;
1185 results->st_counter = 0;
1186
1187 #ifdef RDFSTORE_DEBUG
1188 {
1189 int j;
1190 printf("rdfstore_iterator_unite (ME bits only) '");
1191 for ( j=0; j<me->ids_size; j++) {
1192 printf("%02X",me->ids[j]);
1193 };
1194 printf("'\n");
1195 }
1196 {
1197 int j;
1198 printf("rdfstore_iterator_unite (YOU bits only) '");
1199 for ( j=0; j<you->ids_size; j++) {
1200 printf("%02X",you->ids[j]);
1201 };
1202 printf("'\n");
1203 }
1204 #endif
1205
1206 /* A | B */
1207 results->ids_size = rdfstore_bits_or( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1208 results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1209
1210 #ifdef RDFSTORE_DEBUG
1211 {
1212 int j;
1213 printf("rdfstore_iterator_unite (RESULTS bits only) '");
1214 for ( j=0; j<results->ids_size; j++) {
1215 printf("%02X",results->ids[j]);
1216 };
1217 printf("'\n");
1218 }
1219 #endif
1220
1221 results->size = 0;
1222 results->pos = 0;
1223 while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1224 results->pos++;
1225 results->size++;
1226 };
1227 results->pos = 0;
1228
1229 return results;
1230 };
1231
1232 rdfstore_iterator *
rdfstore_iterator_subtract(rdfstore_iterator * me,rdfstore_iterator * you)1233 rdfstore_iterator_subtract (
1234 rdfstore_iterator * me,
1235 rdfstore_iterator * you
1236 ) {
1237 rdfstore_iterator * results;
1238 register int i=0;
1239 unsigned char not[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1240
1241 if ( ( me == NULL ) ||
1242 ( you == NULL ) )
1243 return NULL;
1244
1245 if ( me->store != you->store ) {
1246 perror("rdfstore_iterator_subtract");
1247 fprintf(stderr,"Cannot subtract cursors from different stores\n");
1248 return NULL;
1249 };
1250
1251 results = NULL;
1252 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1253 if ( results == NULL ) {
1254 perror("rdfstore_iterator_subtract");
1255 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1256 return NULL;
1257 };
1258 results->store = me->store;
1259 me->store->attached++;
1260 results->remove_holes = 0;
1261 results->st_counter = 0;
1262
1263 #ifdef RDFSTORE_DEBUG
1264 {
1265 int j;
1266 printf("rdfstore_iterator_subtract (ME bits only) '");
1267 for ( j=0; j<me->ids_size; j++) {
1268 printf("%02X",me->ids[j]);
1269 };
1270 printf("'\n");
1271 }
1272 {
1273 int j;
1274 printf("rdfstore_iterator_subtract (YOU bits only) '");
1275 for ( j=0; j<you->ids_size; j++) {
1276 printf("%02X",you->ids[j]);
1277 };
1278 printf("'\n");
1279 }
1280 #endif
1281
1282 /* A & (~B) */
1283 for ( i=0;
1284 i<you->ids_size;
1285 i++ ) {
1286 not[i] = ( ~ you->ids[i] );
1287 };
1288 #ifdef RDFSTORE_DEBUG
1289 {
1290 int j;
1291 printf("rdfstore_iterator_subtract ( *NOT* YOU bits only) '");
1292 for ( j=0; j<you->ids_size; j++) {
1293 printf("%02X",not[j]);
1294 };
1295 printf("'\n");
1296 }
1297 #endif
1298
1299 results->ids_size = rdfstore_bits_and( me->ids_size, me->ids, you->ids_size, not, results->ids );
1300 results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1301
1302 #ifdef RDFSTORE_DEBUG
1303 {
1304 int j;
1305 printf("rdfstore_iterator_subtract (RESULTS bits only) '");
1306 for ( j=0; j<results->ids_size; j++) {
1307 printf("%02X",results->ids[j]);
1308 };
1309 printf("'\n");
1310 }
1311 #endif
1312
1313 results->size = 0;
1314 results->pos = 0;
1315 while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1316 results->pos++;
1317 results->size++;
1318 };
1319 results->pos = 0;
1320
1321 return results;
1322 };
1323
1324 rdfstore_iterator *
rdfstore_iterator_complement(rdfstore_iterator * me)1325 rdfstore_iterator_complement (
1326 rdfstore_iterator * me
1327 ) {
1328 rdfstore_iterator * results;
1329 rdfstore_iterator * results1;
1330 rdfstore_iterator * results2;
1331
1332 if ( me == NULL )
1333 return NULL;
1334
1335 results = NULL;
1336 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1337 if ( results == NULL ) {
1338 perror("rdfstore_iterator_complement");
1339 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1340 return NULL;
1341 };
1342 results->store = me->store;
1343 me->store->attached++;
1344 results->remove_holes = 0;
1345 results->st_counter = 0;
1346
1347 #ifdef RDFSTORE_DEBUG
1348 {
1349 int j;
1350 printf("rdfstore_iterator_complement (ME bits only) '");
1351 for ( j=0; j<me->ids_size; j++) {
1352 printf("%02X",me->ids[j]);
1353 };
1354 printf("'\n");
1355 }
1356 #endif
1357
1358 results->ids_size = rdfstore_bits_not( me->ids_size, me->ids, results->ids );
1359 results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1360
1361 #ifdef RDFSTORE_DEBUG
1362 {
1363 int j;
1364 printf("rdfstore_iterator_complement (RESULTS bits only) '");
1365 for ( j=0; j<results->ids_size; j++) {
1366 printf("%02X",results->ids[j]);
1367 };
1368 printf("'\n");
1369 }
1370 #endif
1371
1372 results->size = 0;
1373 results->pos = 0;
1374 while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1375 results->pos++;
1376 results->size++;
1377 };
1378 results->pos = 0;
1379
1380 results1 = rdfstore_elements ( me->store );
1381
1382 if ( results1 == NULL ) {
1383 perror("rdfstore_iterator_complement");
1384 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1385 rdfstore_iterator_close( results );
1386 return NULL;
1387 };
1388
1389 /* make sure that result set is sane */
1390 results2 = rdfstore_iterator_intersect( results, results1 );
1391
1392 rdfstore_iterator_close( results1 );
1393 rdfstore_iterator_close( results );
1394
1395 if ( results2 == NULL ) {
1396 perror("rdfstore_iterator_complement");
1397 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1398 return NULL;
1399 };
1400
1401 return results2;
1402 };
1403
1404 /* it returns a one when A is set and B is not set. But NOT the other way round. */
1405 rdfstore_iterator *
rdfstore_iterator_exor(rdfstore_iterator * me,rdfstore_iterator * you)1406 rdfstore_iterator_exor (
1407 rdfstore_iterator * me,
1408 rdfstore_iterator * you
1409 ) {
1410 rdfstore_iterator * results;
1411
1412 if ( ( me == NULL ) ||
1413 ( you == NULL ) )
1414 return NULL;
1415
1416 if ( me->store != you->store ) {
1417 perror("rdfstore_iterator_exor");
1418 fprintf(stderr,"Cannot carry out exor of cursors from different stores\n");
1419 return NULL;
1420 };
1421
1422 results = NULL;
1423 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1424 if ( results == NULL ) {
1425 perror("rdfstore_iterator_exor");
1426 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1427 return NULL;
1428 };
1429 results->store = me->store;
1430 me->store->attached++;
1431 results->remove_holes = 0;
1432 results->st_counter = 0;
1433
1434 #ifdef RDFSTORE_DEBUG
1435 {
1436 int j;
1437 printf("rdfstore_iterator_exor (ME bits only) '");
1438 for ( j=0; j<me->ids_size; j++) {
1439 printf("%02X",me->ids[j]);
1440 };
1441 printf("'\n");
1442 }
1443 {
1444 int j;
1445 printf("rdfstore_iterator_exor (YOU bits only) '");
1446 for ( j=0; j<you->ids_size; j++) {
1447 printf("%02X",you->ids[j]);
1448 };
1449 printf("'\n");
1450 }
1451 #endif
1452
1453 /* (A | B) ^ B aka Exor */
1454 results->ids_size = rdfstore_bits_exor( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1455 results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1456
1457 #ifdef RDFSTORE_DEBUG
1458 {
1459 int j;
1460 printf("rdfstore_iterator_exor (RESULTS bits only) '");
1461 for ( j=0; j<results->ids_size; j++) {
1462 printf("%02X",results->ids[j]);
1463 };
1464 printf("'\n");
1465 }
1466 #endif
1467
1468 results->size = 0;
1469 results->pos = 0;
1470 while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1471 results->pos++;
1472 results->size++;
1473 };
1474 results->pos = 0;
1475
1476 return results;
1477 };
1478
1479 rdfstore_iterator *
rdfstore_iterator_duplicate(rdfstore_iterator * me)1480 rdfstore_iterator_duplicate (
1481 rdfstore_iterator * me
1482 ) {
1483 rdfstore_iterator * results;
1484
1485 results = NULL;
1486 results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1487 if ( results == NULL ) {
1488 perror("rdfstore_iterator_duplicate");
1489 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1490 return NULL;
1491 };
1492 results->store = me->store;
1493 results->store->attached++; /* one more attached I guess */
1494 /*bzero(results->ids,sizeof(results->ids)); */
1495 bcopy(me->ids,results->ids,sizeof(unsigned char)*me->ids_size);
1496 results->ids_size = me->ids_size;
1497 results->remove_holes = me->remove_holes;
1498 results->pos = me->pos;
1499 results->st_counter = me->st_counter;
1500 results->size = me->size;
1501
1502 return results;
1503 };
1504
rdfstore_iterator_size(rdfstore_iterator * me)1505 unsigned int rdfstore_iterator_size (
1506 rdfstore_iterator * me
1507 ) {
1508
1509 if ( me == NULL )
1510 return -1;
1511
1512 return me->size;
1513 };
1514
1515 /* return a statement given its ID; the statement structure needs to be disposed by the caller */
1516 RDF_Statement *
rdfstore_iterator_fetch_statement(rdfstore_iterator * me)1517 rdfstore_iterator_fetch_statement (
1518 rdfstore_iterator * me
1519 ) {
1520 DBT key, data;
1521 unsigned char outbuf[256];
1522 RDF_Statement * statement;
1523 unsigned int st_id;
1524 int length=0;
1525 char * p;
1526 char mask=0;
1527 int err=0;
1528
1529 if ( me == NULL )
1530 return NULL;
1531
1532 if ( me->size <= 0 )
1533 return NULL;
1534
1535 memset(&key, 0, sizeof(key));
1536 memset(&data, 0, sizeof(data));
1537
1538 st_id = (unsigned int)me->pos; /* this is set by other iterator methods such as first() and next() */
1539
1540 #ifdef RDFSTORE_DEBUG
1541 printf(">>>>>>>>>>>>>>>>>> rdfstore_iterator_fetch_statement: st_id=%d\n",st_id);
1542 #endif
1543
1544 /* create memory structures */
1545 statement = (RDF_Statement *) RDFSTORE_MALLOC(sizeof(RDF_Statement));
1546 if ( statement == NULL ) {
1547 perror("rdfstore_iterator_fetch_statement");
1548 fprintf(stderr,"Could not even create statement for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1549
1550 return NULL;
1551 };
1552 statement->node = NULL;
1553 statement->hashcode = 0;
1554 statement->isreified = 0; /* expensive to check this in the database ?!??? */
1555 statement->subject = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1556 if ( statement->subject == NULL ) {
1557 perror("rdfstore_iterator_fetch_statement");
1558 fprintf(stderr,"Could not even create statement subject for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1559
1560 RDFSTORE_FREE(statement);
1561
1562 return NULL;
1563 };
1564 statement->subject->hashcode=0;
1565 statement->predicate = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1566 if ( statement->predicate == NULL ) {
1567 perror("rdfstore_iterator_fetch_statement");
1568 fprintf(stderr,"Could not even create statement predicate for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1569
1570 RDFSTORE_FREE(statement->subject);
1571 RDFSTORE_FREE(statement);
1572
1573 return NULL;
1574 };
1575 statement->predicate->hashcode=0;
1576 statement->object = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1577 if ( statement->object == NULL ) {
1578 perror("rdfstore_iterator_fetch_statement");
1579 fprintf(stderr,"Could not even create statement object property for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1580
1581 RDFSTORE_FREE(statement->subject);
1582 RDFSTORE_FREE(statement->predicate);
1583 RDFSTORE_FREE(statement);
1584
1585 return NULL;
1586 };
1587 statement->object->hashcode=0;
1588
1589 /* here are all the DB operations needed to fetch a statement */
1590
1591 /* fetch statement */
1592 bzero(outbuf,sizeof(int));
1593 packInt( st_id, outbuf );
1594 key.data = outbuf;
1595 key.size = sizeof(int);
1596 err = rdfstore_flat_store_fetch ( me->store->nodes, key, &data );
1597 if ( err == 0 ) {
1598 length = ( sizeof(int) * 7 ) + 1; /* see doc/SWADe-rdfstore.html about how info is stored */
1599
1600 #ifdef RDFSTORE_DEBUG
1601 fprintf(stderr,"GOT statement '%s' %d\n",(char *)data.data+length);
1602 #endif
1603
1604 /* sort out various components */
1605 p = data.data + length;
1606 mask = *(p-1);
1607
1608 /* subject */
1609 length=0;
1610 unpackInt( data.data, &length );
1611 statement->subject->value.resource.identifier = NULL;
1612 statement->subject->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1613 if ( statement->subject->value.resource.identifier == NULL ) {
1614 perror("rdfstore_iterator_fetch_statement");
1615 fprintf(stderr,"Could not even fetch statement subject for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1616 RDFSTORE_FREE( data.data );
1617 RDFSTORE_FREE( statement->subject );
1618 RDFSTORE_FREE( statement->predicate );
1619 RDFSTORE_FREE( statement->object );
1620 RDFSTORE_FREE( statement );
1621
1622 return NULL;
1623 };
1624 statement->subject->type= (mask & 2) ? 2 : 0;
1625 memcpy(statement->subject->value.resource.identifier,p,length);
1626 memcpy(statement->subject->value.resource.identifier+length,"\0",1);
1627 statement->subject->value.resource.identifier_len = length;
1628 p+=length;
1629
1630 /* predicate */
1631 length=0;
1632 unpackInt( data.data+(sizeof(int)), &length );
1633 statement->predicate->value.resource.identifier=NULL;
1634 statement->predicate->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1635 if ( statement->predicate->value.resource.identifier == NULL ) {
1636 perror("rdfstore_iterator_fetch_statement");
1637 fprintf(stderr,"Could not even fetch statement predicate for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1638 RDFSTORE_FREE( data.data );
1639 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1640 RDFSTORE_FREE( statement->subject );
1641 RDFSTORE_FREE( statement->predicate );
1642 RDFSTORE_FREE( statement->object );
1643 RDFSTORE_FREE( statement );
1644
1645 return NULL;
1646 };
1647 statement->predicate->type= (mask & 4) ? 2 : 0;
1648 memcpy(statement->predicate->value.resource.identifier,p,length);
1649 memcpy(statement->predicate->value.resource.identifier+length,"\0",1);
1650 statement->predicate->value.resource.identifier_len = length;
1651 p+=length;
1652
1653 /* object */
1654 length=0;
1655 unpackInt( data.data+(sizeof(int)*2), &length );
1656 if ( mask & 1 ) {
1657 /* object literal value */
1658 statement->object->value.literal.string = NULL;
1659 statement->object->value.literal.string = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1660 if ( statement->object->value.literal.string == NULL ) {
1661 perror("rdfstore_iterator_fetch_statement");
1662 fprintf(stderr,"Could not even fetch statement object literal for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1663 RDFSTORE_FREE( data.data );
1664 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1665 RDFSTORE_FREE( statement->subject );
1666 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1667 RDFSTORE_FREE( statement->predicate );
1668 RDFSTORE_FREE( statement->object );
1669 RDFSTORE_FREE( statement );
1670
1671 return NULL;
1672 };
1673 statement->object->type = 1; /* literal */
1674 memcpy(statement->object->value.literal.string,p,length);
1675 memcpy(statement->object->value.literal.string+length,"\0",1);
1676 statement->object->value.literal.string_len = length;
1677 p+=length;
1678
1679 /* object xml:lang */
1680 length=0;
1681 unpackInt( data.data+(sizeof(int)*3), &length );
1682 if ( length ) {
1683 memcpy(statement->object->value.literal.lang,p,length);
1684 memcpy(statement->object->value.literal.lang+length,"\0",1);
1685 p+=length;
1686 } else {
1687 memcpy(statement->object->value.literal.lang,"\0",1); /* or =NULL ??? */
1688 };
1689
1690 /* object rdf:dataType */
1691 length=0;
1692 unpackInt( data.data+(sizeof(int)*4), &length );
1693 statement->object->value.literal.dataType = NULL;
1694 if ( length ) {
1695 statement->object->value.literal.dataType = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1696 if ( statement->object->value.literal.dataType == NULL ) {
1697 perror("rdfstore_iterator_fetch_statement");
1698 fprintf(stderr,"Could not even fetch statement object literal rdf:dataType for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1699 RDFSTORE_FREE( data.data );
1700 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1701 RDFSTORE_FREE( statement->subject );
1702 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1703 RDFSTORE_FREE( statement->predicate );
1704 RDFSTORE_FREE( statement->object->value.literal.string );
1705 RDFSTORE_FREE( statement->object );
1706 RDFSTORE_FREE( statement );
1707
1708 return NULL;
1709 };
1710 statement->object->value.literal.parseType= ( strncmp(p,RDFSTORE_RDF_PARSETYPE_LITERAL,length) == 0 ) ? 1 : 0;
1711 memcpy(statement->object->value.literal.dataType,p,length);
1712 memcpy(statement->object->value.literal.dataType+length,"\0",1);
1713 p+=length;
1714 } else {
1715 statement->object->value.literal.parseType = 0;
1716 };
1717 } else {
1718 statement->object->value.resource.identifier=NULL;
1719 statement->object->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1720 if ( statement->object->value.resource.identifier == NULL ) {
1721 perror("rdfstore_iterator_fetch_statement");
1722 fprintf(stderr,"Could not even fetch statement object for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1723 RDFSTORE_FREE( data.data );
1724 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1725 RDFSTORE_FREE( statement->subject );
1726 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1727 RDFSTORE_FREE( statement->predicate );
1728 RDFSTORE_FREE( statement->object );
1729 RDFSTORE_FREE( statement );
1730
1731 return NULL;
1732 };
1733 statement->object->type= (mask & 8) ? 2 : 0;
1734 memcpy(statement->object->value.resource.identifier,p,length);
1735 memcpy(statement->object->value.resource.identifier+length,"\0",1);
1736 statement->object->value.resource.identifier_len = length;
1737 p+=length;
1738 };
1739
1740 /* context */
1741 length=0;
1742 unpackInt( data.data+(sizeof(int)*5), &length );
1743 statement->context = NULL;
1744 if ( length ) {
1745 statement->context = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1746 if ( statement->context == NULL ) {
1747 perror("rdfstore_iterator_fetch_statement");
1748 fprintf(stderr,"Could not even create statement context for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1749 RDFSTORE_FREE( data.data );
1750 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1751 RDFSTORE_FREE( statement->subject );
1752 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1753 RDFSTORE_FREE( statement->predicate );
1754 if ( statement->object->type != 1 ) {
1755 RDFSTORE_FREE( statement->object->value.resource.identifier );
1756 } else {
1757 RDFSTORE_FREE( statement->object->value.literal.string );
1758 if ( statement->object->value.literal.dataType != NULL )
1759 RDFSTORE_FREE( statement->object->value.literal.dataType );
1760 };
1761 RDFSTORE_FREE( statement->object );
1762 RDFSTORE_FREE( statement );
1763
1764 return NULL;
1765 };
1766 statement->context->hashcode=0;
1767
1768 statement->context->value.resource.identifier=NULL;
1769 statement->context->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1770 if ( statement->context->value.resource.identifier == NULL ) {
1771 perror("rdfstore_iterator_fetch_statement");
1772 fprintf(stderr,"Could not even fetch statement context for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1773
1774 RDFSTORE_FREE( data.data );
1775 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1776 RDFSTORE_FREE( statement->subject );
1777 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1778 RDFSTORE_FREE( statement->predicate );
1779 if ( statement->object->type != 1 ) {
1780 RDFSTORE_FREE( statement->object->value.resource.identifier );
1781 } else {
1782 RDFSTORE_FREE( statement->object->value.literal.string );
1783 if ( statement->object->value.literal.dataType != NULL )
1784 RDFSTORE_FREE( statement->object->value.literal.dataType );
1785 };
1786 RDFSTORE_FREE( statement->object );
1787 RDFSTORE_FREE( statement->context );
1788 RDFSTORE_FREE( statement );
1789
1790 return NULL;
1791 };
1792 statement->context->type= (mask & 16) ? 2 : 0;
1793 memcpy(statement->context->value.resource.identifier,p,length);
1794 memcpy(statement->context->value.resource.identifier+length,"\0",1);
1795 statement->context->value.resource.identifier_len = length;
1796 p+=length;
1797 };
1798
1799 /* statement as resource stuff */
1800 length=0;
1801 unpackInt( data.data+(sizeof(int)*6), &length );
1802 statement->node = NULL;
1803 if ( length ) {
1804 statement->node = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1805 if ( statement->node == NULL ) {
1806 perror("rdfstore_iterator_fetch_statement");
1807 fprintf(stderr,"Could not even create statement as resource for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1808 RDFSTORE_FREE( data.data );
1809 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1810 RDFSTORE_FREE( statement->subject );
1811 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1812 RDFSTORE_FREE( statement->predicate );
1813 if ( statement->object->type != 1 ) {
1814 RDFSTORE_FREE( statement->object->value.resource.identifier );
1815 } else {
1816 RDFSTORE_FREE( statement->object->value.literal.string );
1817 if ( statement->object->value.literal.dataType != NULL )
1818 RDFSTORE_FREE( statement->object->value.literal.dataType );
1819 };
1820 RDFSTORE_FREE( statement->object );
1821 if ( statement->context != NULL ) {
1822 RDFSTORE_FREE( statement->context->value.resource.identifier );
1823 RDFSTORE_FREE( statement->context );
1824 };
1825 RDFSTORE_FREE( statement );
1826
1827 return NULL;
1828 };
1829 statement->node->hashcode=0;
1830
1831 statement->node->value.resource.identifier=NULL;
1832 statement->node->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1833 if ( statement->node->value.resource.identifier == NULL ) {
1834 perror("rdfstore_iterator_fetch_statement");
1835 fprintf(stderr,"Could not even fetch statement as resource for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1836
1837 RDFSTORE_FREE( data.data );
1838 RDFSTORE_FREE( statement->subject->value.resource.identifier );
1839 RDFSTORE_FREE( statement->subject );
1840 RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1841 RDFSTORE_FREE( statement->predicate );
1842 if ( statement->object->type != 1 ) {
1843 RDFSTORE_FREE( statement->object->value.resource.identifier );
1844 } else {
1845 RDFSTORE_FREE( statement->object->value.literal.string );
1846 if ( statement->object->value.literal.dataType != NULL )
1847 RDFSTORE_FREE( statement->object->value.literal.dataType );
1848 };
1849 RDFSTORE_FREE( statement->object );
1850 if ( statement->context != NULL ) {
1851 RDFSTORE_FREE( statement->context->value.resource.identifier );
1852 RDFSTORE_FREE( statement->context );
1853 };
1854 RDFSTORE_FREE( statement->node );
1855 RDFSTORE_FREE( statement );
1856
1857 return NULL;
1858 };
1859 statement->node->type = 0; /* see http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-reifying why */
1860 memcpy(statement->node->value.resource.identifier,p,length);
1861 memcpy(statement->node->value.resource.identifier+length,"\0",1);
1862 statement->node->value.resource.identifier_len = length;
1863 p+=length;
1864 };
1865
1866 RDFSTORE_FREE( data.data );
1867 } else {
1868 perror("rdfstore_iterator_fetch_statement");
1869 fprintf(stderr,"Could not even fetch statement '%d' (key is %d bytes) for store '%s': %s\n",st_id, (int)key.size, (me->store->name != NULL) ? me->store->name : "(in-memory)", rdfstore_flat_store_get_error( me->store->nodes ) );
1870
1871 RDFSTORE_FREE(statement->subject);
1872 RDFSTORE_FREE(statement->predicate);
1873 RDFSTORE_FREE(statement->object);
1874 RDFSTORE_FREE(statement);
1875
1876 return NULL;
1877 };
1878
1879 #ifdef RDFSTORE_DEBUG
1880 if (statement != NULL ) {
1881 fprintf(stderr,"\tS='%s'\n",statement->subject->value.resource.identifier);
1882 fprintf(stderr,"\tP='%s'\n",statement->predicate->value.resource.identifier);
1883 if ( statement->object->type != 1 ) {
1884 fprintf(stderr,"\tO='%s'\n",statement->object->value.resource.identifier);
1885 } else {
1886 fprintf(stderr,"\tOLIT='%s'\n",statement->object->value.literal.string);
1887 };
1888 if ( statement->context != NULL )
1889 fprintf(stderr,"\tC='%s'\n",statement->context->value.resource.identifier);
1890 if ( statement->node != NULL )
1891 fprintf(stderr,"\tSRES='%s'\n",statement->node->value.resource.identifier);
1892 };
1893 #endif
1894
1895 return statement;
1896 };
1897