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