File Coverage

blib/lib/Paranoid/BerkeleyDB.pm
Criterion Covered Total %
statement 28 30 93.3
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 38 40 95.0


line stmt bran cond sub pod time code
1             # Paranoid::BerkeleyDB -- BerkeleyDB Wrapper
2             #
3             # (c) 2005 - 2015, Arthur Corliss
4             #
5             # $Id: lib/Paranoid/BerkeleyDB.pm, 2.01 2016/06/17 11:24:54 acorliss Exp $
6             #
7             # This software is licensed under the same terms as Perl, itself.
8             # Please see http://dev.perl.org/licenses/ for more information.
9             #
10             #####################################################################
11              
12             #####################################################################
13             #
14             # Dbironment definitions
15             #
16             #####################################################################
17              
18             package Paranoid::BerkeleyDB;
19              
20 1     1   14835 use strict;
  1         1  
  1         22  
21 1     1   3 use warnings;
  1         1  
  1         18  
22 1     1   3 use vars qw($VERSION);
  1         1  
  1         27  
23 1     1   3 use Fcntl qw(:DEFAULT :flock :mode :seek);
  1         1  
  1         449  
24 1     1   4 use Paranoid;
  1         1  
  1         33  
25 1     1   3 use Paranoid::Debug qw(:all);
  1         1  
  1         103  
26 1     1   419 use Paranoid::IO;
  1         9207  
  1         66  
27 1     1   376 use Paranoid::IO::Lockfile;
  1         813  
  1         50  
28 1     1   575 use Class::EHierarchy qw(:all);
  1         5012  
  1         117  
29 1     1   710 use BerkeleyDB;
  0            
  0            
30             use Paranoid::BerkeleyDB::Env;
31             use Paranoid::BerkeleyDB::Db;
32             use Carp;
33              
34             ($VERSION) = ( q$Revision: 2.01 $ =~ /(\d+(?:\.\d+)+)/sm );
35              
36             use vars qw(@ISA @_properties @_methods);
37              
38             @ISA = qw(Class::EHierarchy);
39              
40             @_properties = (
41             [ CEH_RESTR | CEH_SCALAR, 'filename' ],
42             [ CEH_RESTR | CEH_SCALAR, 'pid' ],
43             [ CEH_RESTR | CEH_REF, 'cursor' ],
44             [ CEH_PRIV | CEH_REF, 'dbh' ],
45             );
46             @_methods = ( [ CEH_PUB, 'dbh' ], );
47              
48             #####################################################################
49             #
50             # module code follows
51             #
52             #####################################################################
53              
54             sub _initialize {
55              
56             # Purpose: Create the database object and env object (if needed)
57             # Returns: Boolean
58             # Usage: $rv = $obj->_initialize(%params);
59              
60             my $obj = shift;
61             my %params = @_;
62             my $rv = 0;
63             my ( $db, $env, $fn );
64              
65             # Make sure minimal parameters are preset
66             pdebug( 'entering w/%s', PDLEVEL1, %params );
67             pIn();
68              
69             # Set up the environment
70             if ( exists $params{Home} ) {
71             $env = new Paranoid::BerkeleyDB::Env '-Home' => $params{Home};
72             } elsif ( exists $params{Env}
73             and defined $params{Env}
74             and ref $params{Env} eq 'HASH' ) {
75             $env = new Paranoid::BerkeleyDB::Env %{ $params{Env} };
76             } elsif ( exists $params{Env}
77             and defined $params{Env}
78             and $params{Env}->isa('Paranoid::BerkeleyDB::Env') ) {
79             $env = $params{Env};
80             }
81              
82             Paranoid::ERROR =
83             pdebug( 'failed to acquire a bdb environment', PDLEVEL1 )
84             unless defined $env;
85              
86             # Set up the database
87             if ( defined $env ) {
88             if ( exists $params{Filename} ) {
89             $fn = $params{Filename};
90             $db = new Paranoid::BerkeleyDB::Db
91             '-Filename' => $params{Filename},
92             '-Env' => $env;
93             } elsif ( exists $params{Db}
94             and defined $params{Db}
95             and ref $params{Db} eq 'HASH' ) {
96             $fn = $params{Db}{'-Filename'};
97             $params{Db}{'-Env'} = $env;
98             $db = new Paranoid::BerkeleyDB::Db %{ $params{Db} };
99             }
100              
101             if ( defined $db ) {
102             $obj->adopt($env);
103             $obj->property( 'pid', $$ );
104             $obj->property( 'filename', $fn );
105             $obj->property( 'dbh', $db->db );
106             $rv = 1;
107             } else {
108             Paranoid::ERROR =
109             pdebug( 'failed to open the database', PDLEVEL1 );
110             }
111             }
112              
113             pOut();
114             pdebug( 'leaving w/rv: %s', PDLEVEL1, $rv );
115              
116             return $rv;
117             }
118              
119             sub _deconstruct {
120              
121             # Purpose: Object cleanup
122             # Returns: Boolean
123             # Usage: $rv = $obj->deconstruct;
124              
125             my $obj = shift;
126              
127             pdebug( 'entering', PDLEVEL1 );
128             pIn();
129              
130             $obj->property( 'cursor', undef );
131             $obj->property( 'dbh', undef );
132              
133             pOut();
134             pdebug( 'leaving w/rv: 1', PDLEVEL1 );
135              
136             return 1;
137             }
138              
139             sub dbh {
140              
141             # Purpose: Performs PID check before returning dbh
142             # Returns: Db ref
143             # Usage: $dbh = $obj->dbh;
144              
145             my $obj = shift;
146             my $pid = $obj->property('pid');
147             my $fn = $obj->property('filename');
148             my ( $rv, @children );
149              
150             pdebug( 'entering', PDLEVEL3 );
151             pIn();
152              
153             if ( $$ == $pid ) {
154              
155             # Same process
156             $rv = $obj->property('dbh');
157              
158             } else {
159              
160             # :-) Nothing to see here, can't seem to get it to
161             # work like the old days...
162             croak 'attempted to access an open database in a forked process';
163              
164             # Purge current references
165             $obj->property( 'cursor', undef );
166             $obj->property( 'dbh', undef );
167              
168             # Get a list of children and find the same database
169             @children = ( $obj->children )[0]->children;
170             foreach (@children) {
171             if ( $fn = $_->property('filename') ) {
172             $obj->property( 'pid', $$ );
173             $obj->property( 'dbh', $_->db );
174             $rv = $_->db;
175             last;
176             }
177             }
178             }
179              
180             pOut();
181             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
182              
183             return $rv;
184             }
185              
186             sub cds_lock {
187              
188             # Purpose: Simple wrapper to get a CDS lock
189             # Returns: CDS Lock
190             # Usage: $lock = $dbh->cds_lock;
191              
192             my $obj = shift;
193             my $dbh = $obj->dbh;
194              
195             return $dbh->cds_lock;
196             }
197              
198             sub TIEHASH {
199             my @args = @_;
200              
201             shift @args;
202              
203             return new Paranoid::BerkeleyDB @args;
204             }
205              
206             sub FETCH {
207             my $obj = shift;
208             my $key = shift;
209             my $dbh = $obj->dbh;
210             my ( $val, $rv );
211              
212             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
213             pIn();
214              
215             if ( !$dbh->db_get( $key, $val ) ) {
216             $rv = $val;
217             }
218              
219             pOut();
220             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
221              
222             return $rv;
223             }
224              
225             sub STORE {
226             my $obj = shift;
227             my $key = shift;
228             my $val = shift;
229             my $dbh = $obj->dbh;
230             my $rv;
231              
232             pdebug( 'entering w/(%s)(%s)', PDLEVEL3, $key, $val );
233             pIn();
234              
235             $rv = !$dbh->db_put( $key, $val );
236              
237             pOut();
238             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
239              
240             return $rv;
241             }
242              
243             sub EXISTS {
244             my $obj = shift;
245             my $key = shift;
246             my $dbh = $obj->dbh;
247             my $rv;
248              
249             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
250             pIn();
251              
252             $rv = !$dbh->db_exists($key);
253              
254             pOut();
255             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
256              
257             return $rv;
258             }
259              
260             sub DELETE {
261             my $obj = shift;
262             my $key = shift;
263             my $dbh = $obj->dbh;
264             my $rv;
265              
266             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
267             pIn();
268              
269             $rv = !$dbh->db_del($key);
270              
271             pOut();
272             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
273              
274             return $rv;
275             }
276              
277             sub CLEAR {
278             my $obj = shift;
279             my $dbh = $obj->dbh;
280             my $rv = 0;
281             my $lock;
282              
283             pdebug( 'entering', PDLEVEL3 );
284             pIn();
285              
286             $lock = $dbh->cds_lock if $dbh->cds_enabled;
287             $dbh->truncate($rv);
288             $lock->cds_unlock if defined $lock;
289              
290             pOut();
291             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
292              
293             return $rv;
294             }
295              
296             sub FIRSTKEY {
297             my $obj = shift;
298             my $dbh = $obj->dbh;
299             my ( $key, $val ) = ( '', '' );
300             my ( $cursor, %o );
301              
302             pdebug( 'entering', PDLEVEL3 );
303             pIn();
304              
305             $cursor = $dbh->db_cursor;
306              
307             if ( defined $cursor and $cursor->c_get( $key, $val, DB_NEXT ) == 0 ) {
308             %o = ( $key => $val );
309             $obj->property( 'cursor', $cursor );
310             }
311              
312             pOut();
313             pdebug( 'leaving w/rv: %s', PDLEVEL3, %o );
314              
315             return each %o;
316             }
317              
318             sub NEXTKEY {
319             my $obj = shift;
320             my $cursor = $obj->property('cursor');
321             my ( $key, $val ) = ( '', '' );
322             my (%o);
323              
324             pdebug( 'entering', PDLEVEL3 );
325             pIn();
326              
327             if ( defined $cursor ) {
328             if ( $cursor->c_get( $key, $val, DB_NEXT ) == 0 ) {
329             %o = ( $key => $val );
330             } else {
331             $obj->property( 'cursor', undef );
332             }
333             }
334              
335             pOut();
336             pdebug( 'leaving w/rv: %s', PDLEVEL3, %o );
337              
338             return each %o;
339             }
340              
341             sub SCALAR {
342             my $obj = shift;
343             my ( $key, $rv );
344              
345             pdebug( 'entering', PDLEVEL3 );
346             pIn();
347              
348             if ( defined( $key = $obj->FIRSTKEY ) ) {
349             $rv = 1;
350             $obj->property( 'cursor', undef );
351             } else {
352             $rv = 0;
353             }
354              
355             pOut();
356             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
357              
358             return $rv;
359             }
360              
361             sub UNTIE {
362             my $obj = shift;
363             my $rv = 1;
364              
365             pdebug( 'entering', PDLEVEL3 );
366             pIn();
367              
368             $obj->property( 'cursor', undef );
369             $obj->property( 'dbh', undef );
370              
371             pOut();
372             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
373              
374             return $rv;
375             }
376              
377             1;
378              
379             __END__