1#-------------------------------------------------------------------------------------------------
2# Perl binding of Tokyo Cabinet
3#                                                                Copyright (C) 2006-2010 FAL Labs
4# This file is part of Tokyo Cabinet.
5# Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
6# the GNU Lesser General Public License as published by the Free Software Foundation; either
7# version 2.1 of the License or any later version.  Tokyo Cabinet is distributed in the hope
8# that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
10# License for more details.
11# You should have received a copy of the GNU Lesser General Public License along with Tokyo
12# Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13# Boston, MA 02111-1307 USA.
14#-------------------------------------------------------------------------------------------------
15
16
17package TokyoCabinet;
18
19use strict;
20use warnings;
21use bytes;
22use Carp;
23
24require Exporter;
25require XSLoader;
26use base qw(Exporter);
27our $VERSION = '1.34';
28our $DEBUG = 0;
29XSLoader::load('TokyoCabinet', $VERSION);
30
31
32
33#----------------------------------------------------------------
34# utilities
35#----------------------------------------------------------------
36
37
38sub VERSION {
39    return TokyoCabinet::tc_version();
40}
41
42
43sub atoi {
44    my $str = shift;
45    return 0 if(!defined($str));
46    return tc_atoi($str);
47}
48
49
50sub atof {
51    my $str = shift;
52    return 0 if(!defined($str));
53    return tc_atof($str);
54}
55
56
57sub bercompress {
58    my $aryref = shift;
59    if(scalar(@_) != 0 || !defined($aryref) || ref($aryref) ne "ARRAY"){
60        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
61        return undef;
62    }
63    return tc_bercompress($aryref);
64}
65
66
67sub beruncompress {
68    my $selref = shift;
69    if(scalar(@_) != 0 || !defined($selref) || ref($selref) ne "SCALAR"){
70        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
71        return undef;
72    }
73    return tc_beruncompress($selref);
74}
75
76
77sub diffcompress {
78    my $aryref = shift;
79    if(scalar(@_) != 0 || !defined($aryref) || ref($aryref) ne "ARRAY"){
80        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
81        return undef;
82    }
83    return tc_diffcompress($aryref);
84}
85
86
87sub diffuncompress {
88    my $selref = shift;
89    if(scalar(@_) != 0 || !defined($selref) || ref($selref) ne "SCALAR"){
90        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
91        return undef;
92    }
93    return tc_diffuncompress($selref);
94}
95
96
97sub strdistance {
98    my $aref = shift;
99    my $bref = shift;
100    my $isutf = shift;
101    if(scalar(@_) != 0 || !defined($aref) || ref($aref) ne "SCALAR" ||
102       !defined($bref) || ref($bref) ne "SCALAR"){
103        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
104        return undef;
105    }
106    $isutf = 0 if(!defined($isutf));
107    return tc_strdistance($aref, $bref, $isutf);
108}
109
110
111
112#----------------------------------------------------------------
113# the hash database API
114#----------------------------------------------------------------
115
116
117package TokyoCabinet::HDB;
118
119use strict;
120use warnings;
121use bytes;
122use Carp;
123use Encode;
124
125
126use constant {
127    ESUCCESS => 0,
128    ETHREAD => 1,
129    EINVALID => 2,
130    ENOFILE => 3,
131    ENOPERM => 4,
132    EMETA => 5,
133    ERHEAD => 6,
134    EOPEN => 7,
135    ECLOSE => 8,
136    ETRUNC => 9,
137    ESYNC => 10,
138    ESTAT => 11,
139    ESEEK => 12,
140    EREAD => 13,
141    EWRITE => 14,
142    EMMAP => 15,
143    ELOCK => 16,
144    EUNLINK => 17,
145    ERENAME => 18,
146    EMKDIR => 19,
147    ERMDIR => 20,
148    EKEEP => 21,
149    ENOREC => 22,
150    EMISC => 9999,
151};
152
153use constant {
154    TLARGE => 1 << 0,
155    TDEFLATE => 1 << 1,
156    TBZIP => 1 << 2,
157    TTCBS => 1 << 3,
158};
159
160use constant {
161    OREADER => 1 << 0,
162    OWRITER => 1 << 1,
163    OCREAT => 1 << 2,
164    OTRUNC => 1 << 3,
165    ONOLCK => 1 << 4,
166    OLCKNB => 1 << 5,
167    OTSYNC => 1 << 6,
168};
169
170
171sub new {
172    my $class = shift;
173    if(scalar(@_) != 0){
174        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
175        return undef;
176    }
177    my $self = [0];
178    $$self[0] = TokyoCabinet::hdb_new();
179    bless($self, $class);
180    return $self;
181}
182
183
184sub DESTROY {
185    my $self = shift;
186    return undef unless($$self[0]);
187    TokyoCabinet::hdb_del($$self[0]);
188    return undef;
189}
190
191
192sub errmsg {
193    my $self = shift;
194    my $ecode = shift;
195    if(scalar(@_) != 0){
196        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
197        return undef;
198    }
199    $ecode = $self->ecode() if(!defined($ecode) || $ecode < 0);
200    return TokyoCabinet::hdb_errmsg($ecode);
201}
202
203
204sub ecode {
205    my $self = shift;
206    if(scalar(@_) != 0){
207        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
208        return undef;
209    }
210    return TokyoCabinet::hdb_ecode($$self[0]);
211}
212
213
214sub tune {
215    my $self = shift;
216    my $bnum = shift;
217    my $apow = shift;
218    my $fpow = shift;
219    my $opts = shift;
220    if(scalar(@_) != 0){
221        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
222        return undef;
223    }
224    $bnum = -1 if(!defined($bnum));
225    $apow = -1 if(!defined($apow));
226    $fpow = -1 if(!defined($fpow));
227    $opts = 0 if(!defined($opts));
228    return TokyoCabinet::hdb_tune($$self[0], $bnum, $apow, $fpow, $opts);
229}
230
231
232sub setcache {
233    my $self = shift;
234    my $rcnum = shift;
235    if(scalar(@_) != 0){
236        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
237        return undef;
238    }
239    $rcnum = -1 if(!defined($rcnum));
240    return TokyoCabinet::hdb_setcache($$self[0], $rcnum);
241}
242
243
244sub setxmsiz {
245    my $self = shift;
246    my $xmsiz = shift;
247    if(scalar(@_) != 0){
248        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
249        return undef;
250    }
251    $xmsiz = -1 if(!defined($xmsiz));
252    return TokyoCabinet::hdb_setxmsiz($$self[0], $xmsiz);
253}
254
255
256sub setdfunit {
257    my $self = shift;
258    my $dfunit = shift;
259    if(scalar(@_) != 0){
260        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
261        return undef;
262    }
263    $dfunit = -1 if(!defined($dfunit));
264    return TokyoCabinet::hdb_setdfunit($$self[0], $dfunit);
265}
266
267
268sub open {
269    my $self = shift;
270    my $path = shift;
271    my $omode = shift;
272    if(scalar(@_) != 0 || !defined($path)){
273        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
274        return undef;
275    }
276    $omode = OREADER if(!defined($omode));
277    return TokyoCabinet::hdb_open($$self[0], $path, $omode);
278}
279
280
281sub close {
282    my $self = shift;
283    if(scalar(@_) != 0){
284        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
285        return undef;
286    }
287    return TokyoCabinet::hdb_close($$self[0]);
288}
289
290
291sub put {
292    my $self = shift;
293    my $key = shift;
294    my $value = shift;
295    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
296        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
297        return undef;
298    }
299    return TokyoCabinet::hdb_put($$self[0], $key, $value);
300}
301
302
303sub putkeep {
304    my $self = shift;
305    my $key = shift;
306    my $value = shift;
307    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
308        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
309        return undef;
310    }
311    return TokyoCabinet::hdb_putkeep($$self[0], $key, $value);
312}
313
314
315sub putcat {
316    my $self = shift;
317    my $key = shift;
318    my $value = shift;
319    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
320        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
321        return undef;
322    }
323    return TokyoCabinet::hdb_putcat($$self[0], $key, $value);
324}
325
326
327sub putasync {
328    my $self = shift;
329    my $key = shift;
330    my $value = shift;
331    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
332        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
333        return undef;
334    }
335    return TokyoCabinet::hdb_putasync($$self[0], $key, $value);
336}
337
338
339sub out {
340    my $self = shift;
341    my $key = shift;
342    if(scalar(@_) != 0 || !defined($key)){
343        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
344        return undef;
345    }
346    return TokyoCabinet::hdb_out($$self[0], $key);
347}
348
349
350sub get {
351    my $self = shift;
352    my $key = shift;
353    if(scalar(@_) != 0 || !defined($key)){
354        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
355        return undef;
356    }
357    return TokyoCabinet::hdb_get($$self[0], $key);
358}
359
360
361sub vsiz {
362    my $self = shift;
363    my $key = shift;
364    if(scalar(@_) != 0 || !defined($key)){
365        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
366        return undef;
367    }
368    return TokyoCabinet::hdb_vsiz($$self[0], $key);
369}
370
371
372sub iterinit {
373    my $self = shift;
374    if(scalar(@_) != 0){
375        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
376        return undef;
377    }
378    return TokyoCabinet::hdb_iterinit($$self[0]);
379}
380
381
382sub iternext {
383    my $self = shift;
384    if(scalar(@_) != 0){
385        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
386        return undef;
387    }
388    return TokyoCabinet::hdb_iternext($$self[0]);
389}
390
391
392sub fwmkeys {
393    my $self = shift;
394    my $prefix = shift;
395    my $max = shift;
396    if(scalar(@_) != 0 || !defined($prefix)){
397        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
398        return undef;
399    }
400    $max = -1 if(!defined($max));
401    return TokyoCabinet::hdb_fwmkeys($$self[0], $prefix, $max);
402}
403
404
405sub addint {
406    my $self = shift;
407    my $key = shift;
408    my $num = shift;
409    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
410        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
411        return undef;
412    }
413    return TokyoCabinet::hdb_addint($$self[0], $key, $num);
414}
415
416
417sub adddouble {
418    my $self = shift;
419    my $key = shift;
420    my $num = shift;
421    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
422        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
423        return undef;
424    }
425    return TokyoCabinet::hdb_adddouble($$self[0], $key, $num);
426}
427
428
429sub sync {
430    my $self = shift;
431    if(scalar(@_) != 0){
432        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
433        return undef;
434    }
435    return TokyoCabinet::hdb_sync($$self[0]);
436}
437
438
439sub optimize {
440    my $self = shift;
441    my $bnum = shift;
442    my $apow = shift;
443    my $fpow = shift;
444    my $opts = shift;
445    if(scalar(@_) != 0){
446        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
447        return undef;
448    }
449    $bnum = -1 if(!defined($bnum));
450    $apow = -1 if(!defined($apow));
451    $fpow = -1 if(!defined($fpow));
452    $opts = 0xff if(!defined($opts));
453    return TokyoCabinet::hdb_optimize($$self[0], $bnum, $apow, $fpow, $opts);
454}
455
456
457sub vanish {
458    my $self = shift;
459    if(scalar(@_) != 0){
460        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
461        return undef;
462    }
463    return TokyoCabinet::hdb_vanish($$self[0]);
464}
465
466
467sub copy {
468    my $self = shift;
469    my $path = shift;
470    if(scalar(@_) != 0 || !defined($path)){
471        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
472        return undef;
473    }
474    return TokyoCabinet::hdb_copy($$self[0], $path);
475}
476
477
478sub tranbegin {
479    my $self = shift;
480    if(scalar(@_) != 0){
481        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
482        return undef;
483    }
484    return TokyoCabinet::hdb_tranbegin($$self[0]);
485}
486
487
488sub trancommit {
489    my $self = shift;
490    if(scalar(@_) != 0){
491        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
492        return undef;
493    }
494    return TokyoCabinet::hdb_trancommit($$self[0]);
495}
496
497
498sub tranabort {
499    my $self = shift;
500    if(scalar(@_) != 0){
501        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
502        return undef;
503    }
504    return TokyoCabinet::hdb_tranabort($$self[0]);
505}
506
507
508sub path {
509    my $self = shift;
510    if(scalar(@_) != 0){
511        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
512        return undef;
513    }
514    return TokyoCabinet::hdb_path($$self[0]);
515}
516
517
518sub rnum {
519    my $self = shift;
520    if(scalar(@_) != 0){
521        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
522        return undef;
523    }
524    return TokyoCabinet::hdb_rnum($$self[0]);
525}
526
527
528sub fsiz {
529    my $self = shift;
530    if(scalar(@_) != 0){
531        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
532        return undef;
533    }
534    return TokyoCabinet::hdb_fsiz($$self[0]);
535}
536
537
538sub TIEHASH {
539    my $class = shift;
540    my $path = shift;
541    my $omode = shift;
542    my $bnum = shift;
543    my $apow = shift;
544    my $fpow = shift;
545    my $opts = shift;
546    my $rcnum = shift;
547    my $hdb = $class->new();
548    $hdb->tune($bnum, $apow, $fpow, $opts);
549    $hdb->setcache($rcnum);
550    return undef if(!$hdb->open($path, $omode));
551    return $hdb;
552}
553
554
555sub UNTIE {
556    my $self = shift;
557    return $self->close();
558}
559
560
561sub STORE {
562    my $self = shift;
563    my $key = shift;
564    my $value = shift;
565    return $self->put($key, $value);
566}
567
568
569sub DELETE {
570    my $self = shift;
571    my $key = shift;
572    return $self->out($key);
573}
574
575
576sub FETCH {
577    my $self = shift;
578    my $key = shift;
579    return $self->get($key);
580}
581
582
583sub EXISTS {
584    my $self = shift;
585    my $key = shift;
586    return $self->vsiz($key) >= 0;
587}
588
589
590sub FIRSTKEY {
591    my $self = shift;
592    $self->iterinit();
593    return $self->iternext();
594}
595
596
597sub NEXTKEY {
598    my $self = shift;
599    return $self->iternext();
600}
601
602
603sub CLEAR {
604    my $self = shift;
605    return $self->vanish();
606}
607
608
609
610#----------------------------------------------------------------
611# the B+ tree database API
612#----------------------------------------------------------------
613
614
615package TokyoCabinet::BDB;
616
617use strict;
618use warnings;
619use bytes;
620use Carp;
621use Encode;
622
623
624use constant {
625    ESUCCESS => 0,
626    ETHREAD => 1,
627    EINVALID => 2,
628    ENOFILE => 3,
629    ENOPERM => 4,
630    EMETA => 5,
631    ERHEAD => 6,
632    EOPEN => 7,
633    ECLOSE => 8,
634    ETRUNC => 9,
635    ESYNC => 10,
636    ESTAT => 11,
637    ESEEK => 12,
638    EREAD => 13,
639    EWRITE => 14,
640    EMMAP => 15,
641    ELOCK => 16,
642    EUNLINK => 17,
643    ERENAME => 18,
644    EMKDIR => 19,
645    ERMDIR => 20,
646    EKEEP => 21,
647    ENOREC => 22,
648    EMISC => 9999,
649};
650
651use constant {
652    CMPLEXICAL => "CMPLEXICAL",
653    CMPDECIMAL => "CMPDECIMAL",
654    CMPINT32 => "CMPINT32",
655    CMPINT64 => "CMPINT64",
656};
657
658use constant {
659    TLARGE => 1 << 0,
660    TDEFLATE => 1 << 1,
661    TBZIP => 1 << 2,
662    TTCBS => 1 << 3,
663};
664
665use constant {
666    OREADER => 1 << 0,
667    OWRITER => 1 << 1,
668    OCREAT => 1 << 2,
669    OTRUNC => 1 << 3,
670    ONOLCK => 1 << 4,
671    OLCKNB => 1 << 5,
672    OTSYNC => 1 << 6,
673};
674
675
676sub new {
677    my $class = shift;
678    if(scalar(@_) != 0){
679        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
680        return undef;
681    }
682    my $self = [0, 0];
683    $$self[0] = TokyoCabinet::bdb_new();
684    bless($self, $class);
685    return $self;
686}
687
688
689sub DESTROY {
690    my $self = shift;
691    return undef unless($$self[0]);
692    TokyoCabinet::bdb_del($$self[0]);
693    return undef;
694}
695
696
697sub errmsg {
698    my $self = shift;
699    my $ecode = shift;
700    if(scalar(@_) != 0){
701        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
702        return undef;
703    }
704    $ecode = $self->ecode() if(!defined($ecode) || $ecode < 0);
705    return TokyoCabinet::bdb_errmsg($ecode);
706}
707
708
709sub ecode {
710    my $self = shift;
711    if(scalar(@_) != 0){
712        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
713        return undef;
714    }
715    return TokyoCabinet::bdb_ecode($$self[0]);
716}
717
718
719sub setcmpfunc {
720    my $self = shift;
721    my $cmp = shift;
722    if(scalar(@_) != 0 || !defined($cmp)){
723        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
724        return undef;
725    }
726    if($cmp eq CMPLEXICAL){
727        return TokyoCabinet::bdb_setcmpfunc($$self[0], 0);
728    } elsif($cmp eq CMPDECIMAL){
729        return TokyoCabinet::bdb_setcmpfunc($$self[0], 1);
730    } elsif($cmp eq CMPINT32){
731        return TokyoCabinet::bdb_setcmpfunc($$self[0], 2);
732    } elsif($cmp eq CMPINT64){
733        return TokyoCabinet::bdb_setcmpfunc($$self[0], 3);
734    }
735    return TokyoCabinet::bdb_setcmpfuncex($$self[0], $cmp);
736}
737
738
739sub tune {
740    my $self = shift;
741    my $lmemb = shift;
742    my $nmemb = shift;
743    my $bnum = shift;
744    my $apow = shift;
745    my $fpow = shift;
746    my $opts = shift;
747    if(scalar(@_) != 0){
748        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
749        return undef;
750    }
751    $lmemb = -1 if(!defined($lmemb));
752    $nmemb = -1 if(!defined($nmemb));
753    $bnum = -1 if(!defined($bnum));
754    $apow = -1 if(!defined($apow));
755    $fpow = -1 if(!defined($fpow));
756    $opts = 0 if(!defined($opts));
757    return TokyoCabinet::bdb_tune($$self[0], $lmemb, $nmemb, $bnum, $apow, $fpow, $opts);
758}
759
760
761sub setcache {
762    my $self = shift;
763    my $lcnum = shift;
764    my $ncnum = shift;
765    if(scalar(@_) != 0){
766        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
767        return undef;
768    }
769    $lcnum = -1 if(!defined($lcnum));
770    $ncnum = -1 if(!defined($ncnum));
771    return TokyoCabinet::bdb_setcache($$self[0], $lcnum, $ncnum);
772}
773
774
775sub setxmsiz {
776    my $self = shift;
777    my $xmsiz = shift;
778    if(scalar(@_) != 0){
779        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
780        return undef;
781    }
782    $xmsiz = -1 if(!defined($xmsiz));
783    return TokyoCabinet::bdb_setxmsiz($$self[0], $xmsiz);
784}
785
786
787sub setdfunit {
788    my $self = shift;
789    my $dfunit = shift;
790    if(scalar(@_) != 0){
791        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
792        return undef;
793    }
794    $dfunit = -1 if(!defined($dfunit));
795    return TokyoCabinet::bdb_setdfunit($$self[0], $dfunit);
796}
797
798
799sub open {
800    my $self = shift;
801    my $path = shift;
802    my $omode = shift;
803    if(scalar(@_) != 0 || !defined($path)){
804        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
805        return undef;
806    }
807    $omode = OREADER if(!defined($omode));
808    return TokyoCabinet::bdb_open($$self[0], $path, $omode);
809}
810
811
812sub close {
813    my $self = shift;
814    if(scalar(@_) != 0){
815        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
816        return undef;
817    }
818    return TokyoCabinet::bdb_close($$self[0]);
819}
820
821
822sub put {
823    my $self = shift;
824    my $key = shift;
825    my $value = shift;
826    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
827        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
828        return undef;
829    }
830    return TokyoCabinet::bdb_put($$self[0], $key, $value);
831}
832
833
834sub putkeep {
835    my $self = shift;
836    my $key = shift;
837    my $value = shift;
838    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
839        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
840        return undef;
841    }
842    return TokyoCabinet::bdb_putkeep($$self[0], $key, $value);
843}
844
845
846sub putcat {
847    my $self = shift;
848    my $key = shift;
849    my $value = shift;
850    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
851        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
852        return undef;
853    }
854    return TokyoCabinet::bdb_putcat($$self[0], $key, $value);
855}
856
857
858sub putdup {
859    my $self = shift;
860    my $key = shift;
861    my $value = shift;
862    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
863        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
864        return undef;
865    }
866    return TokyoCabinet::bdb_putdup($$self[0], $key, $value);
867}
868
869
870sub putlist {
871    my $self = shift;
872    my $key = shift;
873    my $values = shift;
874    if(scalar(@_) != 0 || !defined($key) || !defined($values) || ref($values) ne "ARRAY"){
875        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
876        return undef;
877    }
878    return TokyoCabinet::bdb_putlist($$self[0], $key, $values);
879}
880
881
882sub out {
883    my $self = shift;
884    my $key = shift;
885    if(scalar(@_) != 0 || !defined($key)){
886        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
887        return undef;
888    }
889    return TokyoCabinet::bdb_out($$self[0], $key);
890}
891
892
893sub outlist {
894    my $self = shift;
895    my $key = shift;
896    if(scalar(@_) != 0 || !defined($key)){
897        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
898        return undef;
899    }
900    return TokyoCabinet::bdb_outlist($$self[0], $key);
901}
902
903
904sub get {
905    my $self = shift;
906    my $key = shift;
907    if(scalar(@_) != 0 || !defined($key)){
908        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
909        return undef;
910    }
911    return TokyoCabinet::bdb_get($$self[0], $key);
912}
913
914
915sub getlist {
916    my $self = shift;
917    my $key = shift;
918    if(scalar(@_) != 0 || !defined($key)){
919        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
920        return undef;
921    }
922    return TokyoCabinet::bdb_getlist($$self[0], $key);
923}
924
925
926sub vnum {
927    my $self = shift;
928    my $key = shift;
929    if(scalar(@_) != 0 || !defined($key)){
930        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
931        return undef;
932    }
933    return TokyoCabinet::bdb_vnum($$self[0], $key);
934}
935
936
937sub vsiz {
938    my $self = shift;
939    my $key = shift;
940    if(scalar(@_) != 0 || !defined($key)){
941        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
942        return undef;
943    }
944    return TokyoCabinet::bdb_vsiz($$self[0], $key);
945}
946
947
948sub range {
949    my $self = shift;
950    my $bkey = shift;
951    my $binc = shift;
952    my $ekey = shift;
953    my $einc = shift;
954    my $max = shift;
955    if(scalar(@_) != 0){
956        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
957        return undef;
958    }
959    $binc = 0 if(!defined($binc));
960    $einc = 0 if(!defined($einc));
961    $max = -1 if(!defined($max));
962    return TokyoCabinet::bdb_range($$self[0], $bkey, $binc, $ekey, $einc, $max);
963}
964
965
966sub fwmkeys {
967    my $self = shift;
968    my $prefix = shift;
969    my $max = shift;
970    if(scalar(@_) != 0 || !defined($prefix)){
971        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
972        return undef;
973    }
974    $max = -1 if(!defined($max));
975    return TokyoCabinet::bdb_fwmkeys($$self[0], $prefix, $max);
976}
977
978
979sub addint {
980    my $self = shift;
981    my $key = shift;
982    my $num = shift;
983    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
984        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
985        return undef;
986    }
987    return TokyoCabinet::bdb_addint($$self[0], $key, $num);
988}
989
990
991sub adddouble {
992    my $self = shift;
993    my $key = shift;
994    my $num = shift;
995    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
996        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
997        return undef;
998    }
999    return TokyoCabinet::bdb_adddouble($$self[0], $key, $num);
1000}
1001
1002
1003sub sync {
1004    my $self = shift;
1005    if(scalar(@_) != 0){
1006        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1007        return undef;
1008    }
1009    return TokyoCabinet::bdb_sync($$self[0]);
1010}
1011
1012
1013sub optimize {
1014    my $self = shift;
1015    my $lmemb = shift;
1016    my $nmemb = shift;
1017    my $bnum = shift;
1018    my $apow = shift;
1019    my $fpow = shift;
1020    my $opts = shift;
1021    if(scalar(@_) != 0){
1022        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1023        return undef;
1024    }
1025    $lmemb = -1 if(!defined($lmemb));
1026    $nmemb = -1 if(!defined($nmemb));
1027    $bnum = -1 if(!defined($bnum));
1028    $apow = -1 if(!defined($apow));
1029    $fpow = -1 if(!defined($fpow));
1030    $opts = 0xff if(!defined($opts));
1031    return TokyoCabinet::bdb_optimize($$self[0], $lmemb, $nmemb, $bnum, $apow, $fpow, $opts);
1032}
1033
1034
1035sub vanish {
1036    my $self = shift;
1037    if(scalar(@_) != 0){
1038        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1039        return undef;
1040    }
1041    return TokyoCabinet::bdb_vanish($$self[0]);
1042}
1043
1044
1045sub copy {
1046    my $self = shift;
1047    my $path = shift;
1048    if(scalar(@_) != 0 || !defined($path)){
1049        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1050        return undef;
1051    }
1052    return TokyoCabinet::bdb_copy($$self[0], $path);
1053}
1054
1055
1056sub tranbegin {
1057    my $self = shift;
1058    if(scalar(@_) != 0){
1059        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1060        return undef;
1061    }
1062    return TokyoCabinet::bdb_tranbegin($$self[0]);
1063}
1064
1065
1066sub trancommit {
1067    my $self = shift;
1068    if(scalar(@_) != 0){
1069        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1070        return undef;
1071    }
1072    return TokyoCabinet::bdb_trancommit($$self[0]);
1073}
1074
1075
1076sub tranabort {
1077    my $self = shift;
1078    if(scalar(@_) != 0){
1079        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1080        return undef;
1081    }
1082    return TokyoCabinet::bdb_tranabort($$self[0]);
1083}
1084
1085
1086sub path {
1087    my $self = shift;
1088    if(scalar(@_) != 0){
1089        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1090        return undef;
1091    }
1092    return TokyoCabinet::bdb_path($$self[0]);
1093}
1094
1095
1096sub rnum {
1097    my $self = shift;
1098    if(scalar(@_) != 0){
1099        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1100        return undef;
1101    }
1102    return TokyoCabinet::bdb_rnum($$self[0]);
1103}
1104
1105
1106sub fsiz {
1107    my $self = shift;
1108    if(scalar(@_) != 0){
1109        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1110        return undef;
1111    }
1112    return TokyoCabinet::bdb_fsiz($$self[0]);
1113}
1114
1115
1116sub TIEHASH {
1117    my $class = shift;
1118    my $path = shift;
1119    my $omode = shift;
1120    my $lmemb = shift;
1121    my $nmemb = shift;
1122    my $bnum = shift;
1123    my $apow = shift;
1124    my $fpow = shift;
1125    my $opts = shift;
1126    my $lcnum = shift;
1127    my $ncnum = shift;
1128    my $bdb = $class->new();
1129    $bdb->tune($lmemb, $nmemb, $bnum, $apow, $fpow, $opts);
1130    $bdb->setcache($lcnum, $ncnum);
1131    return undef if(!$bdb->open($path, $omode));
1132    $$bdb[1] = TokyoCabinet::BDBCUR->new($bdb);
1133    return $bdb;
1134}
1135
1136
1137sub UNTIE {
1138    my $self = shift;
1139    return $self->close();
1140}
1141
1142
1143sub STORE {
1144    my $self = shift;
1145    my $key = shift;
1146    my $value = shift;
1147    return $self->put($key, $value);
1148}
1149
1150
1151sub DELETE {
1152    my $self = shift;
1153    my $key = shift;
1154    return $self->out($key);
1155}
1156
1157
1158sub FETCH {
1159    my $self = shift;
1160    my $key = shift;
1161    return $self->get($key);
1162}
1163
1164
1165sub EXISTS {
1166    my $self = shift;
1167    my $key = shift;
1168    return $self->vsiz($key) >= 0;
1169}
1170
1171
1172sub FIRSTKEY {
1173    my $self = shift;
1174    my $cur = $$self[1];
1175    $cur->first();
1176    my $key = $cur->key();
1177    $cur->next();
1178    return $key;
1179}
1180
1181
1182sub NEXTKEY {
1183    my $self = shift;
1184    my $cur = $$self[1];
1185    my $key = $cur->key();
1186    $cur->next();
1187    return $key;
1188}
1189
1190
1191sub CLEAR {
1192    my $self = shift;
1193    return $self->vanish();
1194}
1195
1196
1197package TokyoCabinet::BDBCUR;
1198
1199use strict;
1200use warnings;
1201use bytes;
1202use Carp;
1203use Encode;
1204
1205
1206use constant {
1207    CPCURRENT => 0,
1208    CPBEFORE => 1,
1209    CPAFTER => 2,
1210};
1211
1212
1213sub new {
1214    my $class = shift;
1215    my $bdb = shift;
1216    if(scalar(@_) != 0 || !defined($bdb) || ref($bdb) ne "TokyoCabinet::BDB"){
1217        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1218        return undef;
1219    }
1220    my $self = [0];
1221    $$self[0] = TokyoCabinet::bdbcur_new($$bdb[0]);
1222    bless($self, $class);
1223    return $self;
1224}
1225
1226
1227sub DESTROY {
1228    my $self = shift;
1229    return undef unless($$self[0]);
1230    TokyoCabinet::bdbcur_del($$self[0]);
1231    return undef;
1232}
1233
1234
1235sub first {
1236    my $self = shift;
1237    if(scalar(@_) != 0){
1238        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1239        return undef;
1240    }
1241    return TokyoCabinet::bdbcur_first($$self[0]);
1242}
1243
1244
1245sub last {
1246    my $self = shift;
1247    if(scalar(@_) != 0){
1248        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1249        return undef;
1250    }
1251    return TokyoCabinet::bdbcur_last($$self[0]);
1252}
1253
1254
1255sub jump {
1256    my $self = shift;
1257    my $key = shift;
1258    if(scalar(@_) != 0 || !defined($key)){
1259        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1260        return undef;
1261    }
1262    return TokyoCabinet::bdbcur_jump($$self[0], $key);
1263}
1264
1265
1266sub prev {
1267    my $self = shift;
1268    if(scalar(@_) != 0){
1269        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1270        return undef;
1271    }
1272    return TokyoCabinet::bdbcur_prev($$self[0]);
1273}
1274
1275
1276sub next {
1277    my $self = shift;
1278    if(scalar(@_) != 0){
1279        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1280        return undef;
1281    }
1282    return TokyoCabinet::bdbcur_next($$self[0]);
1283}
1284
1285
1286sub put {
1287    my $self = shift;
1288    my $value = shift;
1289    my $cpmode = shift;
1290    if(scalar(@_) != 0 || !defined($value)){
1291        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1292        return undef;
1293    }
1294    $cpmode = CPCURRENT if(!defined($cpmode));
1295    return TokyoCabinet::bdbcur_put($$self[0], $value, $cpmode);
1296}
1297
1298
1299sub out {
1300    my $self = shift;
1301    if(scalar(@_) != 0){
1302        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1303        return undef;
1304    }
1305    return TokyoCabinet::bdbcur_out($$self[0]);
1306}
1307
1308
1309sub key {
1310    my $self = shift;
1311    if(scalar(@_) != 0){
1312        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1313        return undef;
1314    }
1315    return TokyoCabinet::bdbcur_key($$self[0]);
1316}
1317
1318
1319sub val {
1320    my $self = shift;
1321    if(scalar(@_) != 0){
1322        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1323        return undef;
1324    }
1325    return TokyoCabinet::bdbcur_val($$self[0]);
1326}
1327
1328
1329
1330#----------------------------------------------------------------
1331# the fixed-length database API
1332#----------------------------------------------------------------
1333
1334
1335package TokyoCabinet::FDB;
1336
1337use strict;
1338use warnings;
1339use bytes;
1340use Carp;
1341use Encode;
1342
1343
1344use constant {
1345    ESUCCESS => 0,
1346    ETHREAD => 1,
1347    EINVALID => 2,
1348    ENOFILE => 3,
1349    ENOPERM => 4,
1350    EMETA => 5,
1351    ERHEAD => 6,
1352    EOPEN => 7,
1353    ECLOSE => 8,
1354    ETRUNC => 9,
1355    ESYNC => 10,
1356    ESTAT => 11,
1357    ESEEK => 12,
1358    EREAD => 13,
1359    EWRITE => 14,
1360    EMMAP => 15,
1361    ELOCK => 16,
1362    EUNLINK => 17,
1363    ERENAME => 18,
1364    EMKDIR => 19,
1365    ERMDIR => 20,
1366    EKEEP => 21,
1367    ENOREC => 22,
1368    EMISC => 9999,
1369};
1370
1371use constant {
1372    OREADER => 1 << 0,
1373    OWRITER => 1 << 1,
1374    OCREAT => 1 << 2,
1375    OTRUNC => 1 << 3,
1376    ONOLCK => 1 << 4,
1377    OLCKNB => 1 << 5,
1378};
1379
1380
1381sub new {
1382    my $class = shift;
1383    if(scalar(@_) != 0){
1384        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1385        return undef;
1386    }
1387    my $self = [0];
1388    $$self[0] = TokyoCabinet::fdb_new();
1389    bless($self, $class);
1390    return $self;
1391}
1392
1393
1394sub DESTROY {
1395    my $self = shift;
1396    return undef unless($$self[0]);
1397    TokyoCabinet::fdb_del($$self[0]);
1398    return undef;
1399}
1400
1401
1402sub errmsg {
1403    my $self = shift;
1404    my $ecode = shift;
1405    if(scalar(@_) != 0){
1406        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1407        return undef;
1408    }
1409    $ecode = $self->ecode() if(!defined($ecode) || $ecode < 0);
1410    return TokyoCabinet::fdb_errmsg($ecode);
1411}
1412
1413
1414sub ecode {
1415    my $self = shift;
1416    if(scalar(@_) != 0){
1417        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1418        return undef;
1419    }
1420    return TokyoCabinet::fdb_ecode($$self[0]);
1421}
1422
1423
1424sub tune {
1425    my $self = shift;
1426    my $width = shift;
1427    my $limsiz = shift;
1428    if(scalar(@_) != 0){
1429        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1430        return undef;
1431    }
1432    $width = -1 if(!defined($width));
1433    $limsiz = -1 if(!defined($limsiz));
1434    return TokyoCabinet::fdb_tune($$self[0], $width, $limsiz);
1435}
1436
1437
1438sub open {
1439    my $self = shift;
1440    my $path = shift;
1441    my $omode = shift;
1442    if(scalar(@_) != 0 || !defined($path)){
1443        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1444        return undef;
1445    }
1446    $omode = OREADER if(!defined($omode));
1447    return TokyoCabinet::fdb_open($$self[0], $path, $omode);
1448}
1449
1450
1451sub close {
1452    my $self = shift;
1453    if(scalar(@_) != 0){
1454        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1455        return undef;
1456    }
1457    return TokyoCabinet::fdb_close($$self[0]);
1458}
1459
1460
1461sub put {
1462    my $self = shift;
1463    my $key = shift;
1464    my $value = shift;
1465    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
1466        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1467        return undef;
1468    }
1469    return TokyoCabinet::fdb_put($$self[0], $key, $value);
1470}
1471
1472
1473sub putkeep {
1474    my $self = shift;
1475    my $key = shift;
1476    my $value = shift;
1477    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
1478        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1479        return undef;
1480    }
1481    return TokyoCabinet::fdb_putkeep($$self[0], $key, $value);
1482}
1483
1484
1485sub putcat {
1486    my $self = shift;
1487    my $key = shift;
1488    my $value = shift;
1489    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
1490        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1491        return undef;
1492    }
1493    return TokyoCabinet::fdb_putcat($$self[0], $key, $value);
1494}
1495
1496
1497sub out {
1498    my $self = shift;
1499    my $key = shift;
1500    if(scalar(@_) != 0 || !defined($key)){
1501        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1502        return undef;
1503    }
1504    return TokyoCabinet::fdb_out($$self[0], $key);
1505}
1506
1507
1508sub get {
1509    my $self = shift;
1510    my $key = shift;
1511    if(scalar(@_) != 0 || !defined($key)){
1512        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1513        return undef;
1514    }
1515    return TokyoCabinet::fdb_get($$self[0], $key);
1516}
1517
1518
1519sub vsiz {
1520    my $self = shift;
1521    my $key = shift;
1522    if(scalar(@_) != 0 || !defined($key)){
1523        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1524        return undef;
1525    }
1526    return TokyoCabinet::fdb_vsiz($$self[0], $key);
1527}
1528
1529
1530sub iterinit {
1531    my $self = shift;
1532    if(scalar(@_) != 0){
1533        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1534        return undef;
1535    }
1536    return TokyoCabinet::fdb_iterinit($$self[0]);
1537}
1538
1539
1540sub iternext {
1541    my $self = shift;
1542    if(scalar(@_) != 0){
1543        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1544        return undef;
1545    }
1546    return TokyoCabinet::fdb_iternext($$self[0]);
1547}
1548
1549
1550sub range {
1551    my $self = shift;
1552    my $interval = shift;
1553    my $max = shift;
1554    if(scalar(@_) != 0 || !defined($interval)){
1555        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1556        return undef;
1557    }
1558    $max = -1 if(!defined($max));
1559    return TokyoCabinet::fdb_range($$self[0], $interval, $max);
1560}
1561
1562
1563sub addint {
1564    my $self = shift;
1565    my $key = shift;
1566    my $num = shift;
1567    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
1568        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1569        return undef;
1570    }
1571    return TokyoCabinet::fdb_addint($$self[0], $key, $num);
1572}
1573
1574
1575sub adddouble {
1576    my $self = shift;
1577    my $key = shift;
1578    my $num = shift;
1579    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
1580        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1581        return undef;
1582    }
1583    return TokyoCabinet::fdb_adddouble($$self[0], $key, $num);
1584}
1585
1586
1587sub sync {
1588    my $self = shift;
1589    if(scalar(@_) != 0){
1590        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1591        return undef;
1592    }
1593    return TokyoCabinet::fdb_sync($$self[0]);
1594}
1595
1596
1597sub optimize {
1598    my $self = shift;
1599    my $width = shift;
1600    my $limsiz = shift;
1601    if(scalar(@_) != 0){
1602        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1603        return undef;
1604    }
1605    $width = -1 if(!defined($width));
1606    $limsiz = -1 if(!defined($limsiz));
1607    return TokyoCabinet::fdb_optimize($$self[0], $width, $limsiz);
1608}
1609
1610
1611sub vanish {
1612    my $self = shift;
1613    if(scalar(@_) != 0){
1614        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1615        return undef;
1616    }
1617    return TokyoCabinet::fdb_vanish($$self[0]);
1618}
1619
1620
1621sub copy {
1622    my $self = shift;
1623    my $path = shift;
1624    if(scalar(@_) != 0 || !defined($path)){
1625        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1626        return undef;
1627    }
1628    return TokyoCabinet::fdb_copy($$self[0], $path);
1629}
1630
1631
1632sub tranbegin {
1633    my $self = shift;
1634    if(scalar(@_) != 0){
1635        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1636        return undef;
1637    }
1638    return TokyoCabinet::fdb_tranbegin($$self[0]);
1639}
1640
1641
1642sub trancommit {
1643    my $self = shift;
1644    if(scalar(@_) != 0){
1645        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1646        return undef;
1647    }
1648    return TokyoCabinet::fdb_trancommit($$self[0]);
1649}
1650
1651
1652sub tranabort {
1653    my $self = shift;
1654    if(scalar(@_) != 0){
1655        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1656        return undef;
1657    }
1658    return TokyoCabinet::fdb_tranabort($$self[0]);
1659}
1660
1661
1662sub path {
1663    my $self = shift;
1664    if(scalar(@_) != 0){
1665        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1666        return undef;
1667    }
1668    return TokyoCabinet::fdb_path($$self[0]);
1669}
1670
1671
1672sub rnum {
1673    my $self = shift;
1674    if(scalar(@_) != 0){
1675        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1676        return undef;
1677    }
1678    return TokyoCabinet::fdb_rnum($$self[0]);
1679}
1680
1681
1682sub fsiz {
1683    my $self = shift;
1684    if(scalar(@_) != 0){
1685        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1686        return undef;
1687    }
1688    return TokyoCabinet::fdb_fsiz($$self[0]);
1689}
1690
1691
1692sub TIEHASH {
1693    my $class = shift;
1694    my $path = shift;
1695    my $omode = shift;
1696    my $width = shift;
1697    my $limsiz = shift;
1698    my $fdb = $class->new();
1699    $fdb->tune($width, $limsiz);
1700    return undef if(!$fdb->open($path, $omode));
1701    return $fdb;
1702}
1703
1704
1705sub UNTIE {
1706    my $self = shift;
1707    return $self->close();
1708}
1709
1710
1711sub STORE {
1712    my $self = shift;
1713    my $key = shift;
1714    my $value = shift;
1715    return $self->put($key, $value);
1716}
1717
1718
1719sub DELETE {
1720    my $self = shift;
1721    my $key = shift;
1722    return $self->out($key);
1723}
1724
1725
1726sub FETCH {
1727    my $self = shift;
1728    my $key = shift;
1729    return $self->get($key);
1730}
1731
1732
1733sub EXISTS {
1734    my $self = shift;
1735    my $key = shift;
1736    return $self->vsiz($key) >= 0;
1737}
1738
1739
1740sub FIRSTKEY {
1741    my $self = shift;
1742    $self->iterinit();
1743    return $self->iternext();
1744}
1745
1746
1747sub NEXTKEY {
1748    my $self = shift;
1749    return $self->iternext();
1750}
1751
1752
1753sub CLEAR {
1754    my $self = shift;
1755    return $self->vanish();
1756}
1757
1758
1759
1760#----------------------------------------------------------------
1761# the table database API
1762#----------------------------------------------------------------
1763
1764
1765package TokyoCabinet::TDB;
1766
1767use strict;
1768use warnings;
1769use bytes;
1770use Carp;
1771use Encode;
1772
1773
1774use constant {
1775    ESUCCESS => 0,
1776    ETHREAD => 1,
1777    EINVALID => 2,
1778    ENOFILE => 3,
1779    ENOPERM => 4,
1780    EMETA => 5,
1781    ERHEAD => 6,
1782    EOPEN => 7,
1783    ECLOSE => 8,
1784    ETRUNC => 9,
1785    ESYNC => 10,
1786    ESTAT => 11,
1787    ESEEK => 12,
1788    EREAD => 13,
1789    EWRITE => 14,
1790    EMMAP => 15,
1791    ELOCK => 16,
1792    EUNLINK => 17,
1793    ERENAME => 18,
1794    EMKDIR => 19,
1795    ERMDIR => 20,
1796    EKEEP => 21,
1797    ENOREC => 22,
1798    EMISC => 9999,
1799};
1800
1801use constant {
1802    TLARGE => 1 << 0,
1803    TDEFLATE => 1 << 1,
1804    TBZIP => 1 << 2,
1805    TTCBS => 1 << 3,
1806};
1807
1808use constant {
1809    OREADER => 1 << 0,
1810    OWRITER => 1 << 1,
1811    OCREAT => 1 << 2,
1812    OTRUNC => 1 << 3,
1813    ONOLCK => 1 << 4,
1814    OLCKNB => 1 << 5,
1815    OTSYNC => 1 << 6,
1816};
1817
1818use constant {
1819  ITLEXICAL => 0,
1820  ITDECIMAL => 1,
1821  ITTOKEN => 2,
1822  ITQGRAM => 3,
1823  ITOPT => 9998,
1824  ITVOID => 9999,
1825  ITKEEP => 1 << 24,
1826};
1827
1828
1829sub new {
1830    my $class = shift;
1831    if(scalar(@_) != 0){
1832        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1833        return undef;
1834    }
1835    my $self = [0];
1836    $$self[0] = TokyoCabinet::tdb_new();
1837    bless($self, $class);
1838    return $self;
1839}
1840
1841
1842sub DESTROY {
1843    my $self = shift;
1844    return undef unless($$self[0]);
1845    TokyoCabinet::tdb_del($$self[0]);
1846    return undef;
1847}
1848
1849
1850sub errmsg {
1851    my $self = shift;
1852    my $ecode = shift;
1853    if(scalar(@_) != 0){
1854        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1855        return undef;
1856    }
1857    $ecode = $self->ecode() if(!defined($ecode) || $ecode < 0);
1858    return TokyoCabinet::tdb_errmsg($ecode);
1859}
1860
1861
1862sub ecode {
1863    my $self = shift;
1864    if(scalar(@_) != 0){
1865        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1866        return undef;
1867    }
1868    return TokyoCabinet::tdb_ecode($$self[0]);
1869}
1870
1871
1872sub tune {
1873    my $self = shift;
1874    my $bnum = shift;
1875    my $apow = shift;
1876    my $fpow = shift;
1877    my $opts = shift;
1878    if(scalar(@_) != 0){
1879        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1880        return undef;
1881    }
1882    $bnum = -1 if(!defined($bnum));
1883    $apow = -1 if(!defined($apow));
1884    $fpow = -1 if(!defined($fpow));
1885    $opts = 0 if(!defined($opts));
1886    return TokyoCabinet::tdb_tune($$self[0], $bnum, $apow, $fpow, $opts);
1887}
1888
1889
1890sub setcache {
1891    my $self = shift;
1892    my $rcnum = shift;
1893    my $lcnum = shift;
1894    my $ncnum = shift;
1895    if(scalar(@_) != 0){
1896        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1897        return undef;
1898    }
1899    $rcnum = -1 if(!defined($rcnum));
1900    $lcnum = -1 if(!defined($lcnum));
1901    $ncnum = -1 if(!defined($ncnum));
1902    return TokyoCabinet::tdb_setcache($$self[0], $rcnum, $lcnum, $ncnum);
1903}
1904
1905
1906sub setxmsiz {
1907    my $self = shift;
1908    my $xmsiz = shift;
1909    if(scalar(@_) != 0){
1910        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1911        return undef;
1912    }
1913    $xmsiz = -1 if(!defined($xmsiz));
1914    return TokyoCabinet::tdb_setxmsiz($$self[0], $xmsiz);
1915}
1916
1917
1918sub setdfunit {
1919    my $self = shift;
1920    my $dfunit = shift;
1921    if(scalar(@_) != 0){
1922        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1923        return undef;
1924    }
1925    $dfunit = -1 if(!defined($dfunit));
1926    return TokyoCabinet::tdb_setdfunit($$self[0], $dfunit);
1927}
1928
1929
1930sub open {
1931    my $self = shift;
1932    my $path = shift;
1933    my $omode = shift;
1934    if(scalar(@_) != 0 || !defined($path)){
1935        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1936        return undef;
1937    }
1938    $omode = OREADER if(!defined($omode));
1939    return TokyoCabinet::tdb_open($$self[0], $path, $omode);
1940}
1941
1942
1943sub close {
1944    my $self = shift;
1945    if(scalar(@_) != 0){
1946        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1947        return undef;
1948    }
1949    return TokyoCabinet::tdb_close($$self[0]);
1950}
1951
1952
1953sub put {
1954    my $self = shift;
1955    my $pkey = shift;
1956    my $cols = shift;
1957    if(scalar(@_) != 0 || !defined($pkey) || !defined($cols) || ref($cols) ne "HASH"){
1958        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1959        return undef;
1960    }
1961    return TokyoCabinet::tdb_put($$self[0], $pkey, $cols);
1962}
1963
1964
1965sub putkeep {
1966    my $self = shift;
1967    my $pkey = shift;
1968    my $cols = shift;
1969    if(scalar(@_) != 0 || !defined($pkey) || !defined($cols) || ref($cols) ne "HASH"){
1970        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1971        return undef;
1972    }
1973    return TokyoCabinet::tdb_putkeep($$self[0], $pkey, $cols);
1974}
1975
1976
1977sub putcat {
1978    my $self = shift;
1979    my $pkey = shift;
1980    my $cols = shift;
1981    if(scalar(@_) != 0 || !defined($pkey) || !defined($cols) || ref($cols) ne "HASH"){
1982        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1983        return undef;
1984    }
1985    return TokyoCabinet::tdb_putcat($$self[0], $pkey, $cols);
1986}
1987
1988
1989sub out {
1990    my $self = shift;
1991    my $pkey = shift;
1992    if(scalar(@_) != 0 || !defined($pkey)){
1993        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
1994        return undef;
1995    }
1996    return TokyoCabinet::tdb_out($$self[0], $pkey);
1997}
1998
1999
2000sub get {
2001    my $self = shift;
2002    my $pkey = shift;
2003    if(scalar(@_) != 0 || !defined($pkey)){
2004        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2005        return undef;
2006    }
2007    return TokyoCabinet::tdb_get($$self[0], $pkey);
2008}
2009
2010
2011sub vsiz {
2012    my $self = shift;
2013    my $pkey = shift;
2014    if(scalar(@_) != 0 || !defined($pkey)){
2015        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2016        return undef;
2017    }
2018    return TokyoCabinet::tdb_vsiz($$self[0], $pkey);
2019}
2020
2021
2022sub iterinit {
2023    my $self = shift;
2024    if(scalar(@_) != 0){
2025        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2026        return undef;
2027    }
2028    return TokyoCabinet::tdb_iterinit($$self[0]);
2029}
2030
2031
2032sub iternext {
2033    my $self = shift;
2034    if(scalar(@_) != 0){
2035        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2036        return undef;
2037    }
2038    return TokyoCabinet::tdb_iternext($$self[0]);
2039}
2040
2041
2042sub fwmkeys {
2043    my $self = shift;
2044    my $prefix = shift;
2045    my $max = shift;
2046    if(scalar(@_) != 0 || !defined($prefix)){
2047        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2048        return undef;
2049    }
2050    $max = -1 if(!defined($max));
2051    return TokyoCabinet::tdb_fwmkeys($$self[0], $prefix, $max);
2052}
2053
2054
2055sub addint {
2056    my $self = shift;
2057    my $pkey = shift;
2058    my $num = shift;
2059    if(scalar(@_) != 0 || !defined($pkey) || !defined($num)){
2060        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2061        return undef;
2062    }
2063    return TokyoCabinet::tdb_addint($$self[0], $pkey, $num);
2064}
2065
2066
2067sub adddouble {
2068    my $self = shift;
2069    my $pkey = shift;
2070    my $num = shift;
2071    if(scalar(@_) != 0 || !defined($pkey) || !defined($num)){
2072        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2073        return undef;
2074    }
2075    return TokyoCabinet::tdb_adddouble($$self[0], $pkey, $num);
2076}
2077
2078
2079sub sync {
2080    my $self = shift;
2081    if(scalar(@_) != 0){
2082        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2083        return undef;
2084    }
2085    return TokyoCabinet::tdb_sync($$self[0]);
2086}
2087
2088
2089sub optimize {
2090    my $self = shift;
2091    my $bnum = shift;
2092    my $apow = shift;
2093    my $fpow = shift;
2094    my $opts = shift;
2095    if(scalar(@_) != 0){
2096        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2097        return undef;
2098    }
2099    $bnum = -1 if(!defined($bnum));
2100    $apow = -1 if(!defined($apow));
2101    $fpow = -1 if(!defined($fpow));
2102    $opts = 0xff if(!defined($opts));
2103    return TokyoCabinet::tdb_optimize($$self[0], $bnum, $apow, $fpow, $opts);
2104}
2105
2106
2107sub vanish {
2108    my $self = shift;
2109    if(scalar(@_) != 0){
2110        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2111        return undef;
2112    }
2113    return TokyoCabinet::tdb_vanish($$self[0]);
2114}
2115
2116
2117sub copy {
2118    my $self = shift;
2119    my $path = shift;
2120    if(scalar(@_) != 0 || !defined($path)){
2121        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2122        return undef;
2123    }
2124    return TokyoCabinet::tdb_copy($$self[0], $path);
2125}
2126
2127
2128sub tranbegin {
2129    my $self = shift;
2130    if(scalar(@_) != 0){
2131        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2132        return undef;
2133    }
2134    return TokyoCabinet::tdb_tranbegin($$self[0]);
2135}
2136
2137
2138sub trancommit {
2139    my $self = shift;
2140    if(scalar(@_) != 0){
2141        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2142        return undef;
2143    }
2144    return TokyoCabinet::tdb_trancommit($$self[0]);
2145}
2146
2147
2148sub tranabort {
2149    my $self = shift;
2150    if(scalar(@_) != 0){
2151        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2152        return undef;
2153    }
2154    return TokyoCabinet::tdb_tranabort($$self[0]);
2155}
2156
2157
2158sub path {
2159    my $self = shift;
2160    if(scalar(@_) != 0){
2161        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2162        return undef;
2163    }
2164    return TokyoCabinet::tdb_path($$self[0]);
2165}
2166
2167
2168sub rnum {
2169    my $self = shift;
2170    if(scalar(@_) != 0){
2171        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2172        return undef;
2173    }
2174    return TokyoCabinet::tdb_rnum($$self[0]);
2175}
2176
2177
2178sub fsiz {
2179    my $self = shift;
2180    if(scalar(@_) != 0){
2181        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2182        return undef;
2183    }
2184    return TokyoCabinet::tdb_fsiz($$self[0]);
2185}
2186
2187
2188sub setindex {
2189    my $self = shift;
2190    my $name = shift;
2191    my $type = shift;
2192    if(scalar(@_) != 0 || !defined($name) || !defined($type)){
2193        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2194        return undef;
2195    }
2196    return TokyoCabinet::tdb_setindex($$self[0], $name, $type);
2197}
2198
2199
2200sub genuid {
2201    my $self = shift;
2202    if(scalar(@_) != 0){
2203        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2204        return undef;
2205    }
2206    return TokyoCabinet::tdb_genuid($$self[0]);
2207}
2208
2209
2210sub TIEHASH {
2211    my $class = shift;
2212    my $path = shift;
2213    my $omode = shift;
2214    my $bnum = shift;
2215    my $apow = shift;
2216    my $fpow = shift;
2217    my $opts = shift;
2218    my $rcnum = shift;
2219    my $lcnum = shift;
2220    my $ncnum = shift;
2221    my $tdb = $class->new();
2222    $tdb->tune($bnum, $apow, $fpow, $opts);
2223    $tdb->setcache($rcnum, $lcnum, $ncnum);
2224    return undef if(!$tdb->open($path, $omode));
2225    return $tdb;
2226}
2227
2228
2229sub UNTIE {
2230    my $self = shift;
2231    return $self->close();
2232}
2233
2234
2235sub STORE {
2236    my $self = shift;
2237    my $pkey = shift;
2238    my $value = shift;
2239    return $self->put($pkey, $value);
2240}
2241
2242
2243sub DELETE {
2244    my $self = shift;
2245    my $pkey = shift;
2246    return $self->out($pkey);
2247}
2248
2249
2250sub FETCH {
2251    my $self = shift;
2252    my $pkey = shift;
2253    return $self->get($pkey);
2254}
2255
2256
2257sub EXISTS {
2258    my $self = shift;
2259    my $pkey = shift;
2260    return $self->vsiz($pkey) >= 0;
2261}
2262
2263
2264sub FIRSTKEY {
2265    my $self = shift;
2266    $self->iterinit();
2267    return $self->iternext();
2268}
2269
2270
2271sub NEXTKEY {
2272    my $self = shift;
2273    return $self->iternext();
2274}
2275
2276
2277sub CLEAR {
2278    my $self = shift;
2279    return $self->vanish();
2280}
2281
2282
2283package TokyoCabinet::TDBQRY;
2284
2285use strict;
2286use warnings;
2287use bytes;
2288use Carp;
2289use Encode;
2290
2291
2292use constant {
2293  QCSTREQ => 0,
2294  QCSTRINC => 1,
2295  QCSTRBW => 2,
2296  QCSTREW => 3,
2297  QCSTRAND => 4,
2298  QCSTROR => 5,
2299  QCSTROREQ => 6,
2300  QCSTRRX => 7,
2301  QCNUMEQ => 8,
2302  QCNUMGT => 9,
2303  QCNUMGE => 10,
2304  QCNUMLT => 11,
2305  QCNUMLE => 12,
2306  QCNUMBT => 13,
2307  QCNUMOREQ => 14,
2308  QCFTSPH => 15,
2309  QCFTSAND => 16,
2310  QCFTSOR => 17,
2311  QCFTSEX => 18,
2312  QCNEGATE => 1 << 24,
2313  QCNOIDX => 1 << 25,
2314};
2315
2316use constant {
2317  QOSTRASC => 0,
2318  QOSTRDESC => 1,
2319  QONUMASC => 2,
2320  QONUMDESC => 3,
2321};
2322
2323use constant {
2324  QPPUT => 1 << 0,
2325  QPOUT => 1 << 1,
2326  QPSTOP => 1 << 24,
2327};
2328
2329use constant {
2330  KWMUTAB => 1 << 0,
2331  KWMUCTRL => 1 << 1,
2332  KWMUBRCT => 1 << 2,
2333  KWNOOVER => 1 << 24,
2334  KWPULEAD => 1 << 25,
2335};
2336
2337use constant {
2338  MSUNION => 0,
2339  MSISECT => 1,
2340  MSDIFF => 2,
2341};
2342
2343
2344sub new {
2345    my $class = shift;
2346    my $tdb = shift;
2347    if(scalar(@_) != 0 || !defined($tdb) || ref($tdb) ne "TokyoCabinet::TDB"){
2348        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2349        return undef;
2350    }
2351    my $self = [0];
2352    $$self[0] = TokyoCabinet::tdbqry_new($$tdb[0]);
2353    bless($self, $class);
2354    return $self;
2355}
2356
2357
2358sub DESTROY {
2359    my $self = shift;
2360    return undef unless($$self[0]);
2361    TokyoCabinet::tdbqry_del($$self[0]);
2362    return undef;
2363}
2364
2365
2366sub addcond {
2367    my $self = shift;
2368    my $name = shift;
2369    my $op = shift;
2370    my $expr = shift;
2371    if(scalar(@_) != 0 || !defined($name) || !defined($op) || !defined($expr)){
2372        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2373        return undef;
2374    }
2375    TokyoCabinet::tdbqry_addcond($$self[0], $name, $op, $expr);
2376    return undef;
2377}
2378
2379
2380sub setorder {
2381    my $self = shift;
2382    my $name = shift;
2383    my $type = shift;
2384    if(scalar(@_) != 0 || !defined($name)){
2385        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2386        return undef;
2387    }
2388    $type = $self->QOSTRASC if(!defined($type));
2389    TokyoCabinet::tdbqry_setorder($$self[0], $name, $type);
2390    return undef;
2391}
2392
2393
2394sub setlimit {
2395    my $self = shift;
2396    my $max = shift;
2397    my $skip = shift;
2398    if(scalar(@_) != 0){
2399        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2400        return undef;
2401    }
2402    $max = -1 if(!defined($max));
2403    $skip = -1 if(!defined($skip));
2404    TokyoCabinet::tdbqry_setlimit($$self[0], $max, $skip);
2405    return undef;
2406}
2407
2408
2409sub search {
2410    my $self = shift;
2411    if(scalar(@_) != 0){
2412        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2413        return undef;
2414    }
2415    return TokyoCabinet::tdbqry_search($$self[0]);
2416}
2417
2418
2419sub searchout {
2420    my $self = shift;
2421    if(scalar(@_) != 0){
2422        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2423        return undef;
2424    }
2425    return TokyoCabinet::tdbqry_searchout($$self[0]);
2426}
2427
2428
2429sub proc {
2430    my $self = shift;
2431    my $proc = shift;
2432    if(scalar(@_) != 0 || !defined($proc)){
2433        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2434        return undef;
2435    }
2436    return TokyoCabinet::tdbqry_proc($$self[0], $proc);
2437}
2438
2439
2440sub hint {
2441    my $self = shift;
2442    if(scalar(@_) != 0){
2443        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2444        return undef;
2445    }
2446    return TokyoCabinet::tdbqry_hint($$self[0]);
2447}
2448
2449
2450sub metasearch {
2451    my $self = shift;
2452    my $others = shift;
2453    my $type = shift;
2454    if(scalar(@_) != 0 || !defined($others) || ref($others) ne "ARRAY"){
2455        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2456        return undef;
2457    }
2458    $type = $self->MSUNION if(!defined($type));
2459    return TokyoCabinet::tdbqry_metasearch($$self[0], $others, $type);
2460}
2461
2462
2463sub kwic {
2464    my $self = shift;
2465    my $cols = shift;
2466    my $name = shift;
2467    my $width = shift;
2468    my $opts = shift;
2469    if(scalar(@_) != 0 || !defined($cols) || ref($cols) ne "HASH"){
2470        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2471        return undef;
2472    }
2473    $name = "[[undef]]" if(!defined($name));
2474    $opts = 0 if(!defined($opts));
2475    if(!defined($width) || $width < 0){
2476        $width = 1 << 30;
2477        $opts |= $self->KWNOOVER | $self->KWPULEAD;
2478    }
2479    return TokyoCabinet::tdbqry_kwic($$self[0], $cols, $name, $width, $opts);
2480}
2481
2482
2483sub setmax {
2484    return setlimit(@_);
2485}
2486
2487
2488
2489#----------------------------------------------------------------
2490# the abstract database API
2491#----------------------------------------------------------------
2492
2493
2494package TokyoCabinet::ADB;
2495
2496use strict;
2497use warnings;
2498use bytes;
2499use Carp;
2500use Encode;
2501
2502
2503sub new {
2504    my $class = shift;
2505    if(scalar(@_) != 0){
2506        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2507        return undef;
2508    }
2509    my $self = [0];
2510    $$self[0] = TokyoCabinet::adb_new();
2511    bless($self, $class);
2512    return $self;
2513}
2514
2515
2516sub DESTROY {
2517    my $self = shift;
2518    return undef unless($$self[0]);
2519    TokyoCabinet::adb_del($$self[0]);
2520    return undef;
2521}
2522
2523
2524sub open {
2525    my $self = shift;
2526    my $name = shift;
2527    if(scalar(@_) != 0 || !defined($name)){
2528        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2529        return undef;
2530    }
2531    return TokyoCabinet::adb_open($$self[0], $name);
2532}
2533
2534
2535sub close {
2536    my $self = shift;
2537    if(scalar(@_) != 0){
2538        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2539        return undef;
2540    }
2541    return TokyoCabinet::adb_close($$self[0]);
2542}
2543
2544
2545sub put {
2546    my $self = shift;
2547    my $key = shift;
2548    my $value = shift;
2549    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
2550        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2551        return undef;
2552    }
2553    return TokyoCabinet::adb_put($$self[0], $key, $value);
2554}
2555
2556
2557sub putkeep {
2558    my $self = shift;
2559    my $key = shift;
2560    my $value = shift;
2561    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
2562        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2563        return undef;
2564    }
2565    return TokyoCabinet::adb_putkeep($$self[0], $key, $value);
2566}
2567
2568
2569sub putcat {
2570    my $self = shift;
2571    my $key = shift;
2572    my $value = shift;
2573    if(scalar(@_) != 0 || !defined($key) || !defined($value)){
2574        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2575        return undef;
2576    }
2577    return TokyoCabinet::adb_putcat($$self[0], $key, $value);
2578}
2579
2580
2581sub out {
2582    my $self = shift;
2583    my $key = shift;
2584    if(scalar(@_) != 0 || !defined($key)){
2585        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2586        return undef;
2587    }
2588    return TokyoCabinet::adb_out($$self[0], $key);
2589}
2590
2591
2592sub get {
2593    my $self = shift;
2594    my $key = shift;
2595    if(scalar(@_) != 0 || !defined($key)){
2596        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2597        return undef;
2598    }
2599    return TokyoCabinet::adb_get($$self[0], $key);
2600}
2601
2602
2603sub vsiz {
2604    my $self = shift;
2605    my $key = shift;
2606    if(scalar(@_) != 0 || !defined($key)){
2607        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2608        return undef;
2609    }
2610    return TokyoCabinet::adb_vsiz($$self[0], $key);
2611}
2612
2613
2614sub iterinit {
2615    my $self = shift;
2616    if(scalar(@_) != 0){
2617        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2618        return undef;
2619    }
2620    return TokyoCabinet::adb_iterinit($$self[0]);
2621}
2622
2623
2624sub iternext {
2625    my $self = shift;
2626    if(scalar(@_) != 0){
2627        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2628        return undef;
2629    }
2630    return TokyoCabinet::adb_iternext($$self[0]);
2631}
2632
2633
2634sub fwmkeys {
2635    my $self = shift;
2636    my $prefix = shift;
2637    my $max = shift;
2638    if(scalar(@_) != 0 || !defined($prefix)){
2639        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2640        return undef;
2641    }
2642    $max = -1 if(!defined($max));
2643    return TokyoCabinet::adb_fwmkeys($$self[0], $prefix, $max);
2644}
2645
2646
2647sub addint {
2648    my $self = shift;
2649    my $key = shift;
2650    my $num = shift;
2651    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
2652        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2653        return undef;
2654    }
2655    return TokyoCabinet::adb_addint($$self[0], $key, $num);
2656}
2657
2658
2659sub adddouble {
2660    my $self = shift;
2661    my $key = shift;
2662    my $num = shift;
2663    if(scalar(@_) != 0 || !defined($key) || !defined($num)){
2664        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2665        return undef;
2666    }
2667    return TokyoCabinet::adb_adddouble($$self[0], $key, $num);
2668}
2669
2670
2671sub sync {
2672    my $self = shift;
2673    if(scalar(@_) != 0){
2674        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2675        return undef;
2676    }
2677    return TokyoCabinet::adb_sync($$self[0]);
2678}
2679
2680
2681sub optimize {
2682    my $self = shift;
2683    my $params = shift;
2684    if(scalar(@_) != 0){
2685        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2686        return undef;
2687    }
2688    $params = "" if(!defined($params));
2689    return TokyoCabinet::adb_optimize($$self[0], $params);
2690}
2691
2692
2693sub vanish {
2694    my $self = shift;
2695    if(scalar(@_) != 0){
2696        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2697        return undef;
2698    }
2699    return TokyoCabinet::adb_vanish($$self[0]);
2700}
2701
2702
2703sub copy {
2704    my $self = shift;
2705    my $path = shift;
2706    if(scalar(@_) != 0 || !defined($path)){
2707        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2708        return undef;
2709    }
2710    return TokyoCabinet::adb_copy($$self[0], $path);
2711}
2712
2713
2714sub tranbegin {
2715    my $self = shift;
2716    if(scalar(@_) != 0){
2717        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2718        return undef;
2719    }
2720    return TokyoCabinet::adb_tranbegin($$self[0]);
2721}
2722
2723
2724sub trancommit {
2725    my $self = shift;
2726    if(scalar(@_) != 0){
2727        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2728        return undef;
2729    }
2730    return TokyoCabinet::adb_trancommit($$self[0]);
2731}
2732
2733
2734sub tranabort {
2735    my $self = shift;
2736    if(scalar(@_) != 0){
2737        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2738        return undef;
2739    }
2740    return TokyoCabinet::adb_tranabort($$self[0]);
2741}
2742
2743
2744sub path {
2745    my $self = shift;
2746    if(scalar(@_) != 0){
2747        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2748        return undef;
2749    }
2750    return TokyoCabinet::adb_path($$self[0]);
2751}
2752
2753
2754sub rnum {
2755    my $self = shift;
2756    if(scalar(@_) != 0){
2757        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2758        return undef;
2759    }
2760    return TokyoCabinet::adb_rnum($$self[0]);
2761}
2762
2763
2764sub size {
2765    my $self = shift;
2766    if(scalar(@_) != 0){
2767        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2768        return undef;
2769    }
2770    return TokyoCabinet::adb_size($$self[0]);
2771}
2772
2773
2774sub misc {
2775    my $self = shift;
2776    my $name = shift;
2777    my $args = shift;
2778    if(scalar(@_) != 0 || !defined($name)){
2779        croak((caller(0))[3] . ": invalid parameter") if($TokyoCabinet::DEBUG);
2780        return undef;
2781    }
2782    $args = [] if(!defined($args) || ref($args) ne "ARRAY");
2783    return TokyoCabinet::adb_misc($$self[0], $name, $args);
2784}
2785
2786
2787sub TIEHASH {
2788    my $class = shift;
2789    my $name = shift;
2790    my $adb = $class->new();
2791    return undef if(!$adb->open($name));
2792    return $adb;
2793}
2794
2795
2796sub UNTIE {
2797    my $self = shift;
2798    return $self->close();
2799}
2800
2801
2802sub STORE {
2803    my $self = shift;
2804    my $key = shift;
2805    my $value = shift;
2806    return $self->put($key, $value);
2807}
2808
2809
2810sub DELETE {
2811    my $self = shift;
2812    my $key = shift;
2813    return $self->out($key);
2814}
2815
2816
2817sub FETCH {
2818    my $self = shift;
2819    my $key = shift;
2820    return $self->get($key);
2821}
2822
2823
2824sub EXISTS {
2825    my $self = shift;
2826    my $key = shift;
2827    return $self->vsiz($key) >= 0;
2828}
2829
2830
2831sub FIRSTKEY {
2832    my $self = shift;
2833    $self->iterinit();
2834    return $self->iternext();
2835}
2836
2837
2838sub NEXTKEY {
2839    my $self = shift;
2840    return $self->iternext();
2841}
2842
2843
2844sub CLEAR {
2845    my $self = shift;
2846    return $self->vanish();
2847}
2848
2849
2850
28511;
2852
2853
2854# END OF FILE
2855