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_flat_store.c,v 1.25 2006/06/19 10:10:21 areggiori Exp $
67 */
68 #include "dbms.h"
69 #include "dbms_compat.h"
70 #include "dbms_comms.h"
71 
72 /* Public API of flat store */
73 #include "rdfstore_flat_store.h"
74 
75 /* Generic backend API */
76 #include "backend_store.h"
77 
78 #include "rdfstore_log.h"
79 #include "rdfstore.h"
80 
81 #include "rdfstore_flat_store_private.h"
82 
83 #include "backend_bdb_store.h"
84 #include "backend_dbms_store.h"
85 #include "backend_caching_store.h"
86 
default_myfree(void * adr)87 static void     default_myfree(void *adr) {
88 	RDFSTORE_FREE(adr);
89 }
default_mymalloc(size_t x)90 static void    *default_mymalloc(size_t x) {
91 	return RDFSTORE_MALLOC(x);
92 }
default_myerror(char * err,int erx)93 static void     default_myerror(char *err, int erx) {
94 	fprintf(stderr, "rdfstore_flat_store Error[%d]: %s\n", erx, err);
95 }
96 
97 void
rdfstore_flat_store_set_error(FLATDB * me,char * msg,rdfstore_flat_store_error_t erx)98 rdfstore_flat_store_set_error(FLATDB * me, char *msg, rdfstore_flat_store_error_t erx) {
99 	if ( me == NULL )
100 		return;
101 
102 	if (me && me->store)
103 		(*(me->store->set_error)) (me->instance, msg, erx);
104 	else
105 		perror(msg);
106 	};
107 
108 char *
rdfstore_flat_store_get_error(FLATDB * me)109 rdfstore_flat_store_get_error(FLATDB * me) {
110 	if ( me == NULL )
111                 return NULL;
112 
113 	return (*(me->store->get_error)) (me->instance);
114 	};
115 
116 /* clone a key or value for older BDB */
117 DBT
rdfstore_flat_store_kvdup(FLATDB * me,DBT data)118 rdfstore_flat_store_kvdup(FLATDB * me, DBT data) {
119 	return (*(me->store->kvdup)) (me->instance, data);
120 	};
121 
122 #ifdef RDFSTORE_FLAT_STORE_DEBUG
123 void
rdfstore_flat_store_reset_debuginfo(FLATDB * me)124 rdfstore_flat_store_reset_debuginfo(
125 				    FLATDB * me
126 ) {
127 	if ( me == NULL )
128                 return;
129 
130 	(*(me->store->reset_debuginfo)) (me->instance);
131 }
132 #endif
133 
134 /*
135  * NOTE: all the functions return 0 on success and non zero value if error
136  * (see above and include/rdfstore_flat_store.h for known error codes)
137  */
138 rdfstore_flat_store_error_t
rdfstore_flat_store_open(int remote,int ro,FLATDB ** mme,char * dir,char * name,unsigned int local_hash_flags,char * host,int port,void * (* _my_malloc)(size_t size),void (* _my_free)(void *),void (* _my_report)(dbms_cause_t cause,int count),void (* _my_error)(char * err,int erx),int bt_compare_fcn_type)139 rdfstore_flat_store_open(
140 			 int remote,
141 			 int ro,
142 			 FLATDB * *mme,
143 			 char *dir,
144 			 char *name,
145 			 unsigned int local_hash_flags,
146 			 char *host,
147 			 int port,
148 			 void *(*_my_malloc) (size_t size),
149 			 void (*_my_free) (void *),
150 			 void (*_my_report) (dbms_cause_t cause, int count),
151 			 void (*_my_error) (char *err, int erx),
152 			 int bt_compare_fcn_type ) {
153 	FLATDB         *me;
154 	rdfstore_flat_store_error_t err;
155 
156 	if (getenv("RDFSTORE_CACHE"))
157 		remote |= 0x10;
158 
159 	if (_my_error == NULL)
160 		_my_error = default_myerror;
161 
162 	if (_my_malloc == NULL)
163 		_my_malloc = default_mymalloc;
164 
165 	if (_my_free == NULL)
166 		_my_free = default_myfree;
167 
168 	me = (FLATDB *) _my_malloc(sizeof(FLATDB));
169 
170 	if (me == NULL) {
171 		perror("Out of memory during flat store backend creation.");
172 		return FLAT_STORE_E_NOMEM;
173 	};
174 
175 	switch (remote) {
176 	case 0x0:
177 		me->store = backend_bdb;
178 		break;
179 	case 0x1:
180 		me->store = backend_dbms;
181 		break;
182 	case 0x10:
183 	case 0x11:
184 		me->store = backend_caching;
185 		break;
186 	default:
187 		perror("Backend type is not available");
188 		return FLAT_STORE_E_NOMEM;
189 		break;
190 	};
191 
192 
193 	err = (*(me->store->open)) (
194 	 			remote, ro, (void **) &(me->instance),
195 				dir, name, local_hash_flags, host, port,
196 			       _my_malloc, _my_free, _my_report, _my_error,
197 				bt_compare_fcn_type
198 	);
199 	if (err) {
200 		(*_my_free) (me);
201 		return err;
202 	}
203 	me->free = _my_free;
204 
205 #ifdef RDFSTORE_FLAT_STORE_DEBUG
206 	rdfstore_flat_store_reset_debuginfo(me);
207 #endif
208 
209 	*mme = me;		/* XXX need to check with alberto what this
210 				 * is XXX */
211 	return 0;
212 	};
213 
214 rdfstore_flat_store_error_t
rdfstore_flat_store_close(FLATDB * me)215 rdfstore_flat_store_close(
216 			  FLATDB * me
217 ) {
218 	void            (*_my_free) (void *) = me->free;
219 	int             retval = 0;
220 
221 	if ( me == NULL )
222                 return FLAT_STORE_E_UNDEF;
223 
224 	retval = (*(me->store->close)) (me->instance);
225 	_my_free(me);
226 
227 #ifdef RDFSTORE_FLAT_STORE_DEBUG
228 	fprintf(stderr, "rdfstore_flat_store_close '%s'\n", me->filename);
229 #endif
230 
231 	return retval;
232 	};
233 
234 rdfstore_flat_store_error_t
rdfstore_flat_store_fetch(FLATDB * me,DBT key,DBT * val)235 rdfstore_flat_store_fetch(
236 			  FLATDB * me,
237 			  DBT key,
238 			  DBT * val
239 ) {
240 	if ( me == NULL )
241                 return FLAT_STORE_E_UNDEF;
242 
243 	return (*(me->store->fetch)) (me->instance, key, val);
244 	};
245 
246 rdfstore_flat_store_error_t
rdfstore_flat_store_fetch_compressed(FLATDB * me,void (* func_decode)(unsigned int,unsigned char *,unsigned int *,unsigned char *),DBT key,unsigned int * outsize,unsigned char * outchar)247 rdfstore_flat_store_fetch_compressed (
248         FLATDB * me,
249         void(*func_decode)(unsigned int,unsigned char*, unsigned int *, unsigned char *),
250         DBT     key,
251         unsigned int * outsize, unsigned char * outchar ) {
252 
253 	if ( me == NULL )
254                 return FLAT_STORE_E_UNDEF;
255 
256 	return (*(me->store->fetch_compressed))(me->instance,func_decode,key,outsize,outchar);
257 	};
258 
259 
260 rdfstore_flat_store_error_t
rdfstore_flat_store_store(FLATDB * me,DBT key,DBT val)261 rdfstore_flat_store_store(
262 			  FLATDB * me,
263 			  DBT key,
264 			  DBT val ) {
265 
266 	if ( me == NULL )
267                 return FLAT_STORE_E_UNDEF;
268 
269 	return (*(me->store->store)) (me->instance, key, val);
270 	};
271 
272 rdfstore_flat_store_error_t
rdfstore_flat_store_store_compressed(FLATDB * me,void (* func_encode)(unsigned int,unsigned char *,unsigned int *,unsigned char *),DBT key,unsigned int insize,unsigned char * inchar,unsigned char * buff)273 rdfstore_flat_store_store_compressed (
274         FLATDB * me,
275         void(*func_encode)(unsigned int,unsigned char*, unsigned int *, unsigned char *),
276         DBT     key,
277         unsigned int insize, unsigned char * inchar,
278         unsigned char * buff ) {
279 
280 	if ( me == NULL )
281                 return FLAT_STORE_E_UNDEF;
282 
283 	return (*(me->store->store_compressed))(me->instance,func_encode,key,insize,inchar,buff);
284 	};
285 
286 rdfstore_flat_store_error_t
rdfstore_flat_store_exists(FLATDB * me,DBT key)287 rdfstore_flat_store_exists(
288 			   FLATDB * me,
289 			   DBT key ) {
290 
291 	if ( me == NULL )
292                 return FLAT_STORE_E_UNDEF;
293 
294 	return (*(me->store->exists)) (me->instance, key);
295 	};
296 
297 rdfstore_flat_store_error_t
rdfstore_flat_store_delete(FLATDB * me,DBT key)298 rdfstore_flat_store_delete(
299 			   FLATDB * me,
300 			   DBT key ) {
301 
302 	if ( me == NULL )
303                 return FLAT_STORE_E_UNDEF;
304 
305 	return (*(me->store->delete)) (me->instance, key);
306 	};
307 
308 rdfstore_flat_store_error_t
rdfstore_flat_store_clear(FLATDB * me)309 rdfstore_flat_store_clear(
310 			  FLATDB * me ) {
311 
312 	if ( me == NULL )
313                 return FLAT_STORE_E_UNDEF;
314 
315 	return (*(me->store->clear)) (me->instance);
316 	};
317 
318 rdfstore_flat_store_error_t
rdfstore_flat_store_from(FLATDB * me,DBT closest_key,DBT * key)319 rdfstore_flat_store_from(
320 			  FLATDB * me,
321 			  DBT closest_key,
322 			  DBT * key ) {
323 
324 	if ( me == NULL )
325                 return FLAT_STORE_E_UNDEF;
326 
327 	return (*(me->store->from)) (me->instance, closest_key, key);
328 	};
329 
330 rdfstore_flat_store_error_t
rdfstore_flat_store_first(FLATDB * me,DBT * key)331 rdfstore_flat_store_first(
332 			  FLATDB * me,
333 			  DBT * key ) {
334 
335 	if ( me == NULL )
336                 return FLAT_STORE_E_UNDEF;
337 
338 	return (*(me->store->first)) (me->instance, key);
339 	};
340 
341 rdfstore_flat_store_error_t
rdfstore_flat_store_next(FLATDB * me,DBT previous_key,DBT * next_key)342 rdfstore_flat_store_next(
343 			 FLATDB * me,
344 			 DBT previous_key,
345 			 DBT * next_key ) {
346 
347 	if ( me == NULL )
348                 return FLAT_STORE_E_UNDEF;
349 
350 	return (*(me->store->next)) (me->instance, previous_key, next_key);
351 	};
352 
353 rdfstore_flat_store_error_t
rdfstore_flat_store_inc(FLATDB * me,DBT key,DBT * new_value)354 rdfstore_flat_store_inc(
355 			FLATDB * me,
356 			DBT key,
357 			DBT * new_value ) {
358 
359 	if ( me == NULL )
360                 return FLAT_STORE_E_UNDEF;
361 
362 	return (*(me->store->inc)) (me->instance, key, new_value);
363 	};
364 
365 /* packed rdf_store_counter_t decrement */
366 rdfstore_flat_store_error_t
rdfstore_flat_store_dec(FLATDB * me,DBT key,DBT * new_value)367 rdfstore_flat_store_dec(
368 			FLATDB * me,
369 			DBT key,
370 			DBT * new_value ) {
371 
372 	if ( me == NULL )
373                 return FLAT_STORE_E_UNDEF;
374 
375 	return (*(me->store->dec)) (me->instance, key, new_value);
376 	};
377 
378 rdfstore_flat_store_error_t
rdfstore_flat_store_sync(FLATDB * me)379 rdfstore_flat_store_sync(
380 			 FLATDB * me ) {
381 
382 	if ( me == NULL )
383                 return FLAT_STORE_E_UNDEF;
384 
385 	return (*(me->store->sync)) (me->instance);
386 	};
387 
388 int
rdfstore_flat_store_isremote(FLATDB * me)389 rdfstore_flat_store_isremote(
390 			     FLATDB * me ) {
391 
392 	if ( me == NULL )
393                 return -1;
394 
395 	return (*(me->store->isremote)) (me->instance);
396 	};
397 
398