File Coverage

blib/lib/DiaColloDB/EnumFile/Tied.pm
Criterion Covered Total %
statement 24 96 25.0
branch 0 16 0.0
condition 0 13 0.0
subroutine 8 29 27.5
pod 0 4 0.0
total 32 158 20.2


line stmt bran cond sub pod time code
1             ## -*- Mode: CPerl -*-
2             ## File: DiaColloDB::EnumFile::Tied.pm
3             ## Author: Bryan Jurish <moocow@cpan.org>
4             ## Description: collocation db: file-based enums: tied interface
5              
6             package DiaColloDB::EnumFile::Tied;
7             1;
8              
9             package DiaColloDB::EnumFile;
10 1     1   8 use Carp;
  1         2  
  1         25  
11 1     1   136 use strict;
  1         3  
  1         335  
12              
13             ##==============================================================================
14             ## Global Wrappers
15              
16             ## $enum = $CLASS->tienew(%opts,class=>$enumFileClass)
17             ## $enum = $CLASS->tienew($enum)
18             ## + returns $enum if specified, otherwise a new EnumFile object for %opts
19             sub tienew {
20 0     0 0   my $that = shift;
21 0           my $enum;
22 0 0         if (@_==1) {
23 0           $enum = shift;
24             } else {
25 0           my %opts = @_;
26 0   0       my $class = $opts{class} || ref($that) || $that || __PACKAGE__;
27 0 0         $class = "DiaColloDB::$class" if (!UNIVERSAL::isa($class,'DiaColloDB::EnumFile'));
28 0           delete $opts{class};
29 0 0         $enum = $class->new(%opts)
30             or $that->logconfess("tienew(): could not create enum object of class '$class'");
31             }
32             #$enum->{shared} = 1; ##-- refs are shared, so we should be o.k. with auto-close
33 0           return $enum;
34             }
35              
36             ## (\@id2sym,\%sym2id) = $CLASS->tiepair(%opts)
37             ## (\@id2sym,\%sym2id) = $CLASS->tiepair($enum)
38             ## (\@id2sym,\%sym2id) = $OBJECT->tiepair()
39             ## + returns pair of tied objects suitable for simulating e.g. MUDL::Enum
40             ## + %opts: passed to $CLASS->tienew()
41             sub tiepair {
42 0     0 0   my $that = shift;
43 0 0         my $enum = ref($that) ? $that : $that->tienew(@_)
    0          
44             or $that->logconfess("tiepair(): could not create EnumFile object");
45              
46 0           my (@id2sym,%sym2id);
47 0           tie(@id2sym, $enum->tieArrayClass, $enum);
48 0           tie(%sym2id, $enum->tieHashClass, $enum);
49 0           return (\@id2sym,\%sym2id);
50             }
51              
52             ## $class = $CLASS_OR_OBJECT->tieArrayClass()
53             ## + returns class for tied arrays to be returned by tiepair() method
54             ## + default just returns "DiaColloDB::EnumFile::TiedArray"
55             sub tieArrayClass {
56 0     0 0   return "DiaColloDB::EnumFile::TiedArray";
57             }
58              
59             ## $class = $CLASS_OR_OBJECT->tieHashClass()
60             ## + returns class for tied arrays to be returned by tiepair() method
61             ## + default just returns "DiaColloDB::EnumFile::TiedHash"
62             sub tieHashClass {
63 0     0 0   return "DiaColloDB::EnumFile::TiedHash";
64             }
65              
66             ##==============================================================================
67             ## API: TiedArray
68              
69             package DiaColloDB::EnumFile::TiedArray;
70 1     1   495 use Tie::Array;
  1         1259  
  1         34  
71 1     1   8 use Carp;
  1         2  
  1         22  
72 1     1   107 use strict;
  1         3  
  1         359  
73             our @ISA = qw(Tie::Array);
74              
75             ##--------------------------------------------------------------
76             ## API: TiedArray: mandatory methods
77              
78             ## $tied = tie(@array, $tieClass, $enum)
79             ## $tied = tie(@array, $tieClass, %opts)
80             ## $tied = TIEARRAY($class, $tieClass, %opts, class=>$enumFileClass)
81             ## $tied = TIEARRAY($class, $tieClass, $enum)
82             ## + %opts as for DiaColloDB::EnumFile::tienew()
83             ## + returns $tied = \$enum
84             sub TIEARRAY {
85 0     0     my $that = shift;
86 0           my $enum = DiaColloDB::EnumFile->tienew(@_);
87 0   0       return bless \$enum, ref($that)||$that;
88             }
89              
90              
91             ## $val = $tied->FETCH($index)
92             sub FETCH {
93 0     0     return ${$_[0]}->i2s($_[1]);
  0            
94             }
95              
96             ## $count = $tied->FETCHSIZE()
97             ## + like scalar(@array)
98             sub FETCHSIZE {
99 0     0     return ${$_[0]}->size();
  0            
100             }
101              
102             ## $val = $tied->STORE($index,$val)
103             sub STORE {
104 0     0     ${$_[0]}->{dirty} = 1;
  0            
105 0 0         ${$_[0]}->setsize($_[1]+1) if ($_[1] >= ${$_[0]}->size);
  0            
  0            
106 0           return ${$_[0]}->{i2s}[$_[1]] = $_[2];
  0            
107             }
108              
109             ## $count = $tied->STORESIZE($count)
110             ## + not quite safe
111             sub STORESIZE {
112 0     0     ${$_[0]}->{dirty} = 1;
  0            
113 0           return ${$_[0]}->setsize($_[1]);
  0            
114             }
115              
116             ## $bool = $tied->EXISTS($index)
117             sub EXISTS {
118 0     0     return $_[1] < ${$_[0]}->size();
  0            
119             }
120              
121             ## undef = $tied->DELETE($index)
122             ## + not properly supported; just deletes from in-memory cache
123             sub DELETE {
124 0     0     return delete ${$_[0]}->{i2s}[$_[1]];
  0            
125             }
126              
127             ##--------------------------------------------------------------
128             ## API: TiedArray: optional methods
129              
130             ## undef = $tied->CLEAR()
131             sub CLEAR {
132 0     0     ${$_[0]}->fromArray([]);
  0            
133             }
134              
135             #sub PUSH { ... }
136             #sub POP { ... }
137             #sub SHIFT { ... }
138             #sub UNSHIFT { ... }
139             #sub SPLICE { ... }
140             #sub EXTEND { ... }
141             #sub DESTROY { ... }
142              
143              
144             ##==============================================================================
145             ## API: TiedHash
146              
147             package DiaColloDB::EnumFile::TiedHash;
148 1     1   9 use Tie::Hash;
  1         2  
  1         40  
149 1     1   6 use Carp;
  1         2  
  1         21  
150 1     1   116 use strict;
  1         2  
  1         485  
151             our @ISA = qw(Tie::Hash);
152              
153             ##--------------------------------------------------------------
154             ## API: TiedHash: mandatory methods
155              
156             ## $tied = tie(%hash, $tieClass, $enum)
157             ## $tied = tie(%hash, $tieClass, %opts)
158             ## $tied = TIEHASH($class, $tieClass, %opts, class=>$enumFileClass)
159             ## $tied = TIEHASH($class, $tieClass, $enum)
160             ## + %opts as for DiaColloDB::EnumFile::tienew()
161             ## + returned $tied = \$enum
162             sub TIEHASH {
163 0     0     my $that = shift;
164 0           my $enum = DiaColloDB::EnumFile->tienew(@_);
165 0   0       return bless \$enum, ref($that)||$that;
166             }
167              
168             ##--------------------------------------------------------------
169             ## API: TiedArray: optional methods
170              
171             ## $val = $tied->STORE($key, $value)
172             sub STORE {
173 0     0     ${$_[0]}->{dirty} = 1;
  0            
174 0 0         ${$_[0]}->setsize($_[2]+1) if ($_[2] >= ${$_[0]}->size);
  0            
  0            
175 0           return ${$_[0]}->{s2i}{$_[1]} = $_[2];
  0            
176             }
177              
178             ## $val = $tied->FETCH($key)
179             sub FETCH {
180 0     0     return ${$_[0]}->s2i($_[1]);
  0            
181             }
182              
183             ## $key = $tied->FIRSTKEY()
184             sub FIRSTKEY {
185 0   0 0     return ${$_[0]}->i2s(0) // '';
  0            
186             }
187              
188             ## $key = $tied->NEXTKEY($lastkey)
189             ## + only works for enums without index-gaps
190             sub NEXTKEY {
191 0     0     my $i = ${$_[0]}->s2i($_[1]);
  0            
192 0 0 0       return undef if (!defined($i) || ++$i >= ${$_[0]}->size);
  0            
193 0           return ${$_[0]}->i2s($i);
  0            
194             }
195              
196             ## $bool = $tied->EXISTS($key)
197             sub EXISTS {
198 0     0     return ${$_[0]}->s2i($_[1]);
  0            
199             }
200              
201             ## undef = $tied->DELETE($key)
202             ## + not properly supported; just deletes from in-memory cache
203             sub DELETE {
204 0     0     ${$_[0]}->{dirty} = 1;
  0            
205 0           delete ${$_[0]}->{s2i}{$_[1]};
  0            
206             }
207              
208             ## undef = $tied->CLEAR()
209             sub CLEAR {
210 0     0     ${$_[0]}->fromArray([]);
  0            
211             }
212              
213             ## $scalar = $tied->SCALAR()
214             ## + returns key count
215             sub SCALAR {
216 0     0     return ${$_[0]}->size();
  0            
217             }
218              
219              
220             ##==============================================================================
221             ## Footer
222             1;
223              
224             __END__