1 /*************************************************************************************************
2 * Implementation of Villa for C++
3 * Copyright (C) 2000-2005 Mikio Hirabayashi
4 * This file is part of QDBM, Quick Database Manager.
5 * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * Lesser General Public License as published by the Free Software Foundation; either version
7 * 2.1 of the License or any later version. QDBM is distributed in the hope that it will be
8 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10 * details.
11 * You should have received a copy of the GNU Lesser General Public License along with QDBM; if
12 * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13 * 02111-1307 USA.
14 *************************************************************************************************/
15
16
17 #include "xvilla.h"
18 #include <new>
19 #include <cstdlib>
20 #include <ctime>
21
22 extern "C" {
23 #include <depot.h>
24 #include <cabin.h>
25 #include <villa.h>
26 #include <pthread.h>
27 }
28
29 using namespace qdbm;
30
31
32
33 /*************************************************************************************************
34 * Villa_error
35 *************************************************************************************************/
36
37
Villa_error()38 Villa_error::Villa_error() throw()
39 : DBM_error(){
40 ecode = DP_EMISC;
41 return;
42 }
43
44
Villa_error(int ecode)45 Villa_error::Villa_error(int ecode) throw()
46 : DBM_error(){
47 this->ecode = ecode;
48 return;
49 }
50
51
Villa_error(const Villa_error & ve)52 Villa_error::Villa_error(const Villa_error& ve) throw()
53 : DBM_error(ve){
54 ecode = ve.ecode;
55 return;
56 }
57
58
~Villa_error()59 Villa_error::~Villa_error() throw(){
60 return;
61 }
62
63
operator =(const Villa_error & ve)64 Villa_error& Villa_error::operator =(const Villa_error& ve) throw(){
65 this->ecode = ve.ecode;
66 return *this;
67 }
68
69
operator =(int ecode)70 Villa_error& Villa_error::operator =(int ecode) throw(){
71 this->ecode = ecode;
72 return *this;
73 }
74
75
operator ==(const Villa_error & ve) const76 bool Villa_error::operator ==(const Villa_error& ve) const throw(){
77 return ecode == ve.ecode;
78 }
79
80
operator !=(const Villa_error & ve) const81 bool Villa_error::operator !=(const Villa_error& ve) const throw(){
82 return ecode != ve.ecode;
83 }
84
85
operator ==(int ecode) const86 bool Villa_error::operator ==(int ecode) const throw(){
87 return this->ecode == ecode;
88 }
89
90
operator !=(int ecode) const91 bool Villa_error::operator !=(int ecode) const throw(){
92 return this->ecode != ecode;
93 }
94
95
operator const char*() const96 Villa_error::operator const char*() const throw(){
97 return dperrmsg(ecode);
98 }
99
100
code() const101 int Villa_error::code() const throw(){
102 return ecode;
103 }
104
105
message() const106 const char* Villa_error::message() const throw(){
107 return dperrmsg(ecode);
108 }
109
110
111
112 /*************************************************************************************************
113 * Villa
114 *************************************************************************************************/
115
116
117 const int Villa::ENOERR = DP_ENOERR;
118 const int Villa::EFATAL = DP_EFATAL;
119 const int Villa::EMODE = DP_EMODE;
120 const int Villa::EBROKEN = DP_EBROKEN;
121 const int Villa::EKEEP = DP_EKEEP;
122 const int Villa::ENOITEM = DP_ENOITEM;
123 const int Villa::EALLOC = DP_EALLOC;
124 const int Villa::EMAP = DP_EMAP;
125 const int Villa::EOPEN = DP_EOPEN;
126 const int Villa::ECLOSE = DP_ECLOSE;
127 const int Villa::ETRUNC = DP_ETRUNC;
128 const int Villa::ESYNC = DP_ESYNC;
129 const int Villa::ESTAT = DP_ESTAT;
130 const int Villa::ESEEK = DP_ESEEK;
131 const int Villa::EREAD = DP_EREAD;
132 const int Villa::EWRITE = DP_EWRITE;
133 const int Villa::ELOCK = DP_ELOCK;
134 const int Villa::EUNLINK = DP_EUNLINK;
135 const int Villa::EMKDIR = DP_EMKDIR;
136 const int Villa::ERMDIR = DP_ERMDIR;
137 const int Villa::EMISC = DP_EMISC;
138 const int Villa::OREADER = VL_OREADER;
139 const int Villa::OWRITER = VL_OWRITER;
140 const int Villa::OCREAT = VL_OCREAT;
141 const int Villa::OTRUNC = VL_OTRUNC;
142 const int Villa::ONOLCK = VL_ONOLCK;
143 const int Villa::OLCKNB = VL_OLCKNB;
144 const int Villa::OZCOMP = VL_OZCOMP;
145 const int Villa::OYCOMP = VL_OYCOMP;
146 const int Villa::OXCOMP = VL_OXCOMP;
147 const int Villa::DOVER = VL_DOVER;
148 const int Villa::DKEEP = VL_DKEEP;
149 const int Villa::DCAT = VL_DCAT;
150 const int Villa::DDUP = VL_DDUP;
151 const int Villa::DDUPR = VL_DDUPR;
152 const int Villa::JFORWARD = VL_JFORWARD;
153 const int Villa::JBACKWARD = VL_JBACKWARD;
154 const int Villa::CPCURRENT = VL_CPCURRENT;
155 const int Villa::CPBEFORE = VL_CPBEFORE;
156 const int Villa::CPAFTER = VL_CPAFTER;
157
158
version()159 const char* Villa::version() throw(){
160 return dpversion;
161 }
162
163
remove(const char * name)164 void Villa::remove(const char* name) throw(Villa_error){
165 if(pthread_mutex_lock(&ourmutex) != 0) throw Villa_error();
166 if(!vlremove(name)){
167 int ecode = dpecode;
168 pthread_mutex_unlock(&ourmutex);
169 throw Villa_error(ecode);
170 }
171 pthread_mutex_unlock(&ourmutex);
172 }
173
174
cmplex(const char * aptr,int asiz,const char * bptr,int bsiz)175 int Villa::cmplex(const char *aptr, int asiz, const char *bptr, int bsiz) throw(){
176 return VL_CMPLEX(aptr, asiz, bptr, bsiz);
177 }
178
179
cmpint(const char * aptr,int asiz,const char * bptr,int bsiz)180 int Villa::cmpint(const char *aptr, int asiz, const char *bptr, int bsiz) throw(){
181 return VL_CMPINT(aptr, asiz, bptr, bsiz);
182 }
183
184
cmpnum(const char * aptr,int asiz,const char * bptr,int bsiz)185 int Villa::cmpnum(const char *aptr, int asiz, const char *bptr, int bsiz) throw(){
186 return VL_CMPNUM(aptr, asiz, bptr, bsiz);
187 }
188
189
cmpdec(const char * aptr,int asiz,const char * bptr,int bsiz)190 int Villa::cmpdec(const char *aptr, int asiz, const char *bptr, int bsiz) throw(){
191 return VL_CMPDEC(aptr, asiz, bptr, bsiz);
192 }
193
194
Villa(const char * name,int omode,VLCFUNC cmp)195 Villa::Villa(const char* name, int omode, VLCFUNC cmp) throw(Villa_error)
196 : ADBM(){
197 pthread_mutex_init(&mymutex, NULL);
198 silent = false;
199 if(!lock()) throw Villa_error();
200 if(!(villa = vlopen(name, omode, cmp))){
201 int ecode = dpecode;
202 unlock();
203 throw Villa_error(ecode);
204 }
205 pthread_mutex_init(&tranmutex, NULL);
206 unlock();
207 }
208
209
~Villa()210 Villa::~Villa() throw(){
211 pthread_mutex_destroy(&tranmutex);
212 if(!villa){
213 pthread_mutex_destroy(&mymutex);
214 return;
215 }
216 if(lock()){
217 vlclose(villa);
218 unlock();
219 }
220 villa = 0;
221 pthread_mutex_destroy(&mymutex);
222 }
223
224
close()225 void Villa::close() throw(Villa_error){
226 if(!villa) throw Villa_error();
227 if(!lock()) throw Villa_error();
228 if(!vlclose(villa)){
229 int ecode = dpecode;
230 villa = 0;
231 unlock();
232 throw Villa_error(ecode);
233 }
234 villa = 0;
235 unlock();
236 }
237
238
put(const char * kbuf,int ksiz,const char * vbuf,int vsiz,int dmode)239 bool Villa::put(const char* kbuf, int ksiz, const char* vbuf, int vsiz, int dmode)
240 throw(Villa_error){
241 if(!villa) throw Villa_error();
242 if(!lock()) throw Villa_error();
243 if(!vlput(villa, kbuf, ksiz, vbuf, vsiz, dmode)){
244 int ecode = dpecode;
245 unlock();
246 if(silent && ecode == EKEEP) return false;
247 throw Villa_error(ecode);
248 }
249 unlock();
250 return true;
251 }
252
253
out(const char * kbuf,int ksiz)254 bool Villa::out(const char* kbuf, int ksiz) throw(Villa_error){
255 if(!villa) throw Villa_error();
256 if(!lock()) throw Villa_error();
257 if(!vlout(villa, kbuf, ksiz)){
258 int ecode = dpecode;
259 unlock();
260 if(silent && ecode == ENOITEM) return false;
261 throw Villa_error(ecode);
262 }
263 unlock();
264 return true;
265 }
266
267
get(const char * kbuf,int ksiz,int * sp)268 char* Villa::get(const char* kbuf, int ksiz, int* sp) throw(Villa_error){
269 char* vbuf;
270 if(!villa) throw Villa_error();
271 if(!lock()) throw Villa_error();
272 if(!(vbuf = vlget(villa, kbuf, ksiz, sp))){
273 int ecode = dpecode;
274 unlock();
275 if(silent && ecode == ENOITEM) return 0;
276 throw Villa_error(ecode);
277 }
278 unlock();
279 return vbuf;
280 }
281
282
vsiz(const char * kbuf,int ksiz)283 int Villa::vsiz(const char *kbuf, int ksiz) throw(Villa_error){
284 int vsiz;
285 if(!villa) throw Villa_error();
286 if(!lock()) throw Villa_error();
287 if((vsiz = vlvsiz(villa, kbuf, ksiz)) == -1){
288 int ecode = dpecode;
289 unlock();
290 if(silent && ecode == ENOITEM) return 0;
291 throw Villa_error(ecode);
292 }
293 unlock();
294 return vsiz;
295 }
296
297
vnum(const char * kbuf,int ksiz)298 int Villa::vnum(const char *kbuf, int ksiz) throw(Villa_error){
299 int vnum;
300 if(!villa) throw Villa_error();
301 if(!lock()) throw Villa_error();
302 vnum = vlvnum(villa, kbuf, ksiz);
303 unlock();
304 return vnum;
305 }
306
307
curfirst()308 bool Villa::curfirst() throw(Villa_error){
309 if(!villa) throw Villa_error();
310 if(!lock()) throw Villa_error();
311 if(!vlcurfirst(villa)){
312 int ecode = dpecode;
313 unlock();
314 if(silent && ecode == ENOITEM) return 0;
315 throw Villa_error(ecode);
316 }
317 unlock();
318 return true;
319 }
320
321
curlast()322 bool Villa::curlast() throw(Villa_error){
323 if(!villa) throw Villa_error();
324 if(!lock()) throw Villa_error();
325 if(!vlcurlast(villa)){
326 int ecode = dpecode;
327 unlock();
328 if(silent && ecode == ENOITEM) return 0;
329 throw Villa_error(ecode);
330 }
331 unlock();
332 return true;
333 }
334
335
curprev()336 bool Villa::curprev() throw(Villa_error){
337 if(!villa) throw Villa_error();
338 if(!lock()) throw Villa_error();
339 if(!vlcurprev(villa)){
340 int ecode = dpecode;
341 unlock();
342 if(silent && ecode == ENOITEM) return 0;
343 throw Villa_error(ecode);
344 }
345 unlock();
346 return true;
347 }
348
349
curnext()350 bool Villa::curnext() throw(Villa_error){
351 if(!villa) throw Villa_error();
352 if(!lock()) throw Villa_error();
353 if(!vlcurnext(villa)){
354 int ecode = dpecode;
355 unlock();
356 if(silent && ecode == ENOITEM) return 0;
357 throw Villa_error(ecode);
358 }
359 unlock();
360 return true;
361 }
362
363
curjump(const char * kbuf,int ksiz,int jmode)364 bool Villa::curjump(const char* kbuf, int ksiz, int jmode) throw(Villa_error){
365 if(!villa) throw Villa_error();
366 if(!lock()) throw Villa_error();
367 if(!vlcurjump(villa, kbuf, ksiz, jmode)){
368 int ecode = dpecode;
369 unlock();
370 if(silent && ecode == ENOITEM) return 0;
371 throw Villa_error(ecode);
372 }
373 unlock();
374 return true;
375 }
376
377
curkey(int * sp)378 char* Villa::curkey(int *sp) throw(Villa_error){
379 char* kbuf;
380 if(!villa) throw Villa_error();
381 if(!lock()) throw Villa_error();
382 if(!(kbuf = vlcurkey(villa, sp))){
383 int ecode = dpecode;
384 unlock();
385 if(silent && ecode == ENOITEM) return 0;
386 throw Villa_error(ecode);
387 }
388 unlock();
389 return kbuf;
390 }
391
392
curval(int * sp)393 char* Villa::curval(int *sp) throw(Villa_error){
394 char* vbuf;
395 if(!villa) throw Villa_error();
396 if(!lock()) throw Villa_error();
397 if(!(vbuf = vlcurval(villa, sp))){
398 int ecode = dpecode;
399 unlock();
400 if(silent && ecode == ENOITEM) return 0;
401 throw Villa_error(ecode);
402 }
403 unlock();
404 return vbuf;
405 }
406
407
curput(const char * vbuf,int vsiz,int cpmode)408 bool Villa::curput(const char* vbuf, int vsiz, int cpmode) throw(Villa_error){
409 if(!villa) throw Villa_error();
410 if(!lock()) throw Villa_error();
411 if(!vlcurput(villa, vbuf, vsiz, cpmode)){
412 int ecode = dpecode;
413 unlock();
414 if(silent && ecode == ENOITEM) return false;
415 throw Villa_error(ecode);
416 }
417 unlock();
418 return true;
419 }
420
421
curout()422 bool Villa::curout() throw(Villa_error){
423 if(!villa) throw Villa_error();
424 if(!lock()) throw Villa_error();
425 if(!vlcurout(villa)){
426 int ecode = dpecode;
427 unlock();
428 if(silent && ecode == ENOITEM) return false;
429 throw Villa_error(ecode);
430 }
431 unlock();
432 return true;
433 }
434
435
settuning(int lrecmax,int nidxmax,int lcnum,int ncnum)436 void Villa::settuning(int lrecmax, int nidxmax, int lcnum, int ncnum) throw(Villa_error){
437 if(!villa) throw Villa_error();
438 if(!lock()) throw Villa_error();
439 vlsettuning(villa, lrecmax, nidxmax, lcnum, ncnum);
440 unlock();
441 }
442
443
sync()444 void Villa::sync() throw(Villa_error){
445 if(!villa) throw Villa_error();
446 if(!lock()) throw Villa_error();
447 if(!vlsync(villa)){
448 int ecode = dpecode;
449 unlock();
450 throw Villa_error(ecode);
451 }
452 unlock();
453 }
454
455
optimize()456 void Villa::optimize() throw(Villa_error){
457 if(!villa) throw Villa_error();
458 if(!lock()) throw Villa_error();
459 if(!vloptimize(villa)){
460 int ecode = dpecode;
461 unlock();
462 throw Villa_error(ecode);
463 }
464 unlock();
465 }
466
467
name()468 char* Villa::name() throw(Villa_error){
469 char* buf;
470 if(!villa) throw Villa_error();
471 if(!lock()) throw Villa_error();
472 if(!(buf = vlname(villa))){
473 int ecode = dpecode;
474 unlock();
475 throw Villa_error(ecode);
476 }
477 unlock();
478 return buf;
479 }
480
481
fsiz()482 int Villa::fsiz() throw(Villa_error){
483 int rv;
484 if(!villa) throw Villa_error();
485 if(!lock()) throw Villa_error();
486 if((rv = vlfsiz(villa)) == -1){
487 int ecode = dpecode;
488 unlock();
489 throw Villa_error(ecode);
490 }
491 unlock();
492 return rv;
493 }
494
495
lnum()496 int Villa::lnum() throw(Villa_error){
497 int rv;
498 if(!villa) throw Villa_error();
499 if(!lock()) throw Villa_error();
500 if((rv = vllnum(villa)) == -1){
501 int ecode = dpecode;
502 unlock();
503 throw Villa_error(ecode);
504 }
505 unlock();
506 return rv;
507 }
508
509
nnum()510 int Villa::nnum() throw(Villa_error){
511 int rv;
512 if(!villa) throw Villa_error();
513 if(!lock()) throw Villa_error();
514 if((rv = vlnnum(villa)) == -1){
515 int ecode = dpecode;
516 unlock();
517 throw Villa_error(ecode);
518 }
519 unlock();
520 return rv;
521 }
522
523
rnum()524 int Villa::rnum() throw(Villa_error){
525 int rv;
526 if(!villa) throw Villa_error();
527 if(!lock()) throw Villa_error();
528 if((rv = vlrnum(villa)) == -1){
529 int ecode = dpecode;
530 unlock();
531 throw Villa_error(ecode);
532 }
533 unlock();
534 return rv;
535 }
536
537
writable()538 bool Villa::writable() throw(Villa_error){
539 int rv;
540 if(!villa) throw Villa_error();
541 if(!lock()) throw Villa_error();
542 rv = vlwritable(villa);
543 unlock();
544 return rv ? true : false;
545 }
546
547
fatalerror()548 bool Villa::fatalerror() throw(Villa_error){
549 int rv;
550 if(!villa) throw Villa_error();
551 if(!lock()) throw Villa_error();
552 rv = vlfatalerror(villa);
553 unlock();
554 return rv ? true : false;
555 }
556
557
inode()558 int Villa::inode() throw(Villa_error){
559 int rv;
560 if(!villa) throw Villa_error();
561 if(!lock()) throw Villa_error();
562 rv = vlinode(villa);
563 unlock();
564 return rv;
565 }
566
567
mtime()568 time_t Villa::mtime() throw(Villa_error){
569 time_t rv;
570 if(!villa) throw Villa_error();
571 if(!lock()) throw Villa_error();
572 rv = vlmtime(villa);
573 unlock();
574 return rv;
575 }
576
577
tranbegin()578 void Villa::tranbegin() throw(Villa_error){
579 if(!villa) throw Villa_error();
580 if(pthread_mutex_lock(&tranmutex) != 0) throw Villa_error();
581 if(!lock()){
582 pthread_mutex_unlock(&tranmutex);
583 throw Villa_error();
584 }
585 if(!vltranbegin(villa)){
586 int ecode = dpecode;
587 unlock();
588 pthread_mutex_unlock(&tranmutex);
589 throw Villa_error(ecode);
590 }
591 unlock();
592 }
593
594
trancommit()595 void Villa::trancommit() throw(Villa_error){
596 if(!villa) throw Villa_error();
597 if(!lock()) throw Villa_error();
598 if(!vltrancommit(villa)){
599 int ecode = dpecode;
600 unlock();
601 pthread_mutex_unlock(&tranmutex);
602 throw Villa_error(ecode);
603 }
604 unlock();
605 if(pthread_mutex_unlock(&tranmutex) != 0) throw Villa_error();
606 }
607
608
tranabort()609 void Villa::tranabort() throw(Villa_error){
610 if(!villa) throw Villa_error();
611 if(!lock()) throw Villa_error();
612 if(!vltranabort(villa)){
613 int ecode = dpecode;
614 unlock();
615 pthread_mutex_unlock(&tranmutex);
616 throw Villa_error(ecode);
617 }
618 unlock();
619 if(pthread_mutex_unlock(&tranmutex) != 0) throw Villa_error();
620 }
621
622
storerec(const Datum & key,const Datum & val,bool replace)623 void Villa::storerec(const Datum& key, const Datum& val, bool replace) throw(Villa_error){
624 if(!put(key.ptr(), key.size(), val.ptr(), val.size(), replace ? VL_DOVER : VL_DKEEP))
625 throw Villa_error(EKEEP);
626 }
627
628
deleterec(const Datum & key)629 void Villa::deleterec(const Datum& key) throw(Villa_error){
630 if(!out(key.ptr(), key.size())) throw Villa_error(ENOITEM);
631 }
632
633
fetchrec(const Datum & key)634 Datum Villa::fetchrec(const Datum& key) throw(Villa_error){
635 char* vbuf;
636 int vsiz;
637 vbuf = get(key.ptr(), key.size(), &vsiz);
638 if(!vbuf) throw Villa_error(ENOITEM);
639 return Datum(vbuf, vsiz, true);
640 }
641
642
firstkey()643 Datum Villa::firstkey() throw(Villa_error){
644 char* kbuf;
645 int ksiz;
646 curfirst();
647 kbuf = curkey(&ksiz);
648 if(!kbuf) throw Villa_error(ENOITEM);
649 return Datum(kbuf, ksiz, true);
650 }
651
652
nextkey()653 Datum Villa::nextkey() throw(Villa_error){
654 char* kbuf;
655 int ksiz;
656 curnext();
657 kbuf = curkey(&ksiz);
658 if(!kbuf) throw Villa_error(ENOITEM);
659 return Datum(kbuf, ksiz, true);
660 }
661
662
error()663 bool Villa::error() throw(Villa_error){
664 return fatalerror();
665 }
666
667
Villa(const Villa & villa)668 Villa::Villa(const Villa& villa) throw(Villa_error){
669 throw Villa_error();
670 }
671
672
operator =(const Villa & villa)673 Villa& Villa::operator =(const Villa& villa) throw(Villa_error){
674 throw Villa_error();
675 }
676
677
lock()678 bool Villa::lock(){
679 if(dpisreentrant){
680 if(pthread_mutex_lock(&mymutex) != 0) return false;
681 return true;
682 }
683 if(pthread_mutex_lock(&ourmutex) != 0) return false;
684 return true;
685 }
686
687
unlock()688 void Villa::unlock(){
689 if(dpisreentrant){
690 pthread_mutex_unlock(&mymutex);
691 } else {
692 pthread_mutex_unlock(&ourmutex);
693 }
694 }
695
696
697
698 /* END OF FILE */
699