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.03 2017/02/06 02:49:24 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   15179 use strict;
  1         2  
  1         21  
21 1     1   3 use warnings;
  1         1  
  1         20  
22 1     1   3 use vars qw($VERSION);
  1         1  
  1         28  
23 1     1   3 use Fcntl qw(:DEFAULT :flock :mode :seek);
  1         1  
  1         360  
24 1     1   4 use Paranoid;
  1         1  
  1         32  
25 1     1   3 use Paranoid::Debug qw(:all);
  1         1  
  1         102  
26 1     1   426 use Paranoid::IO;
  1         10100  
  1         66  
27 1     1   374 use Paranoid::IO::Lockfile;
  1         804  
  1         48  
28 1     1   512 use Class::EHierarchy qw(:all);
  1         6128  
  1         113  
29 1     1   778 use BerkeleyDB;
  0            
  0            
30             use Paranoid::BerkeleyDB::Env;
31             use Paranoid::BerkeleyDB::Db;
32             use Carp;
33             use Cwd;
34              
35             ($VERSION) = ( q$Revision: 2.03 $ =~ /(\d+(?:\.\d+)+)/sm );
36              
37             use vars qw(@ISA @_properties);
38              
39             @ISA = qw(Class::EHierarchy);
40              
41             @_properties = ( [ CEH_RESTR | CEH_REF, 'cursor' ], );
42              
43             our $db46 = 0;
44              
45             #####################################################################
46             #
47             # module code follows
48             #
49             #####################################################################
50              
51             sub _initialize {
52              
53             # Purpose: Create the database object and env object (if needed)
54             # Returns: Boolean
55             # Usage: $rv = $obj->_initialize(%params);
56              
57             my $obj = shift;
58             my %params = @_;
59             my $rv = 0;
60             my ( $db, $env, $fpath );
61              
62             # Make sure minimal parameters are preset
63             pdebug( 'entering w/%s', PDLEVEL1, %params );
64             pIn();
65              
66             # Set db46 flag
67             $db46 = 1
68             if DB_VERSION_MAJOR > 4
69             or ( DB_VERSION_MAJOR == 4 and DB_VERSION_MINOR >= 6 );
70              
71             # Get the filename's path, in case Home is not set
72             ($fpath) = (
73             exists $params{Filename} ? ( $params{Filename} =~ m#^(.*)/#s )
74             : exists $params{Db} ? ( $params{Db}{'-Filename'} =~ m#^(.*)/#s )
75             : getcwd() );
76              
77             # Set up the environment
78             if ( exists $params{Env}
79             and defined $params{Env}
80             and ref $params{Env} eq 'HASH' ) {
81             $params{Env}{'-Home'} = $fpath
82             if !exists $params{Env}{Home}
83             and defined $fpath
84             and length $fpath;
85             $env = new Paranoid::BerkeleyDB::Env %{ $params{Env} };
86             } elsif ( exists $params{Env}
87             and defined $params{Env}
88             and $params{Env}->isa('Paranoid::BerkeleyDB::Env') ) {
89             $env = $params{Env};
90             } else {
91             $params{Home} = $fpath unless exists $params{Home};
92             $env = new Paranoid::BerkeleyDB::Env '-Home' => $params{Home};
93             }
94              
95             Paranoid::ERROR =
96             pdebug( 'failed to acquire a bdb environment', PDLEVEL1 )
97             unless defined $env;
98              
99             # Set up the database
100             if ( defined $env ) {
101             if ( exists $params{Filename} ) {
102             $db = new Paranoid::BerkeleyDB::Db
103             '-Filename' => $params{Filename},
104             '-Env' => $env;
105             } elsif ( exists $params{Db}
106             and defined $params{Db}
107             and ref $params{Db} eq 'HASH' ) {
108             $params{Db}{'-Env'} = $env;
109             $db = new Paranoid::BerkeleyDB::Db %{ $params{Db} };
110             }
111              
112             if ( defined $db ) {
113             $obj->adopt($env);
114             $env->alias('env');
115             $db->alias('db');
116             $rv = 1;
117             } else {
118             Paranoid::ERROR =
119             pdebug( 'failed to open the database', PDLEVEL1 );
120             }
121             }
122              
123             pOut();
124             pdebug( 'leaving w/rv: %s', PDLEVEL1, $rv );
125              
126             return $rv;
127             }
128              
129             sub _deconstruct {
130              
131             # Purpose: Object cleanup
132             # Returns: Boolean
133             # Usage: $rv = $obj->deconstruct;
134              
135             my $obj = shift;
136              
137             pdebug( 'entering', PDLEVEL1 );
138             pIn();
139              
140             $obj->set( 'cursor', undef ) if !$obj->isStale;
141              
142             pOut();
143             pdebug( 'leaving w/rv: 1', PDLEVEL1 );
144              
145             return 1;
146             }
147              
148             sub dbh {
149              
150             # Purpose: Performs PID check before returning dbh
151             # Returns: Db ref
152             # Usage: $dbh = $obj->dbh;
153              
154             my $obj = shift;
155             my ( $rv, @children );
156              
157             pdebug( 'entering', PDLEVEL3 );
158             pIn();
159              
160             if ( !$obj->isStale ) {
161             $rv = $obj->getByAlias('db')->dbh;
162             } else {
163             pdebug( 'dbh method called on stale object', PDLEVEL1 );
164             }
165              
166             pOut();
167             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
168              
169             return $rv;
170             }
171              
172             sub cds_lock {
173              
174             # Purpose: Simple wrapper to get a CDS lock
175             # Returns: CDS Lock
176             # Usage: $lock = $dbh->cds_lock;
177              
178             my $obj = shift;
179             my $dbh;
180              
181             $dbh = $obj->dbh if !$obj->isStale;
182              
183             return defined $dbh ? $dbh->cds_lock : undef;
184             }
185              
186             sub TIEHASH {
187             my @args = @_;
188              
189             shift @args;
190              
191             return new Paranoid::BerkeleyDB @args;
192             }
193              
194             sub FETCH {
195             my $obj = shift;
196             my $key = shift;
197             my ( $dbh, $val, $rv );
198              
199             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
200             pIn();
201              
202             if ( !$obj->isStale ) {
203             $dbh = $obj->dbh;
204             if ( !$dbh->db_get( $key, $val ) ) {
205             $rv = $val;
206             }
207             } else {
208             $@ = pdebug( 'FETCH called on a stale object', PDLEVEL1 );
209             carp $@;
210             }
211              
212             pOut();
213             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
214              
215             return $rv;
216             }
217              
218             sub STORE {
219             my $obj = shift;
220             my $key = shift;
221             my $val = shift;
222             my $rv;
223              
224             pdebug( 'entering w/(%s)(%s)', PDLEVEL3, $key, $val );
225             pIn();
226              
227             if ( !$obj->isStale ) {
228             $rv = !$obj->dbh->db_put( $key, $val );
229             } else {
230             $@ = pdebug( 'STORE called on a stale object', PDLEVEL1 );
231             carp $@;
232             }
233              
234             pOut();
235             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
236              
237             return $rv;
238             }
239              
240             sub EXISTS {
241             my $obj = shift;
242             my $key = shift;
243             my ( $dbh, $val, $rv );
244              
245             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
246             pIn();
247              
248             if ( !$obj->isStale ) {
249             $dbh = $obj->dbh;
250             $rv =
251             $db46
252             ? $dbh->db_exists($key) != DB_NOTFOUND
253             : $dbh->db_get( $key, $val ) == 0;
254             } else {
255             $@ = pdebug( 'EXISTS called on a stale object', PDLEVEL1 );
256             carp $@;
257             }
258              
259             pOut();
260             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
261              
262             return $rv;
263             }
264              
265             sub DELETE {
266             my $obj = shift;
267             my $key = shift;
268             my $rv;
269              
270             pdebug( 'entering w/(%s)', PDLEVEL3, $key );
271             pIn();
272              
273             if ( !$obj->isStale ) {
274             $rv = !$obj->dbh->db_del($key);
275             } else {
276             $@ = pdebug( 'DELETE called on a stale object', PDLEVEL1 );
277             carp $@;
278             }
279              
280             pOut();
281             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
282              
283             return $rv;
284             }
285              
286             sub CLEAR {
287             my $obj = shift;
288             my $rv = 0;
289             my ( $dbh, $lock );
290              
291             pdebug( 'entering', PDLEVEL3 );
292             pIn();
293              
294             if ( !$obj->isStale ) {
295             $dbh = $obj->dbh;
296             $lock = $dbh->cds_lock if $dbh->cds_enabled;
297             $dbh->truncate($rv);
298             $lock->cds_unlock if defined $lock;
299             } else {
300             $@ = pdebug( 'CLEAR called on a stale object', PDLEVEL1 );
301             carp $@;
302             }
303              
304             pOut();
305             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
306              
307             return $rv;
308             }
309              
310             sub FIRSTKEY {
311             my $obj = shift;
312             my ( $key, $val ) = ( '', '' );
313             my ( $cursor, %o );
314              
315             pdebug( 'entering', PDLEVEL3 );
316             pIn();
317              
318             if ( !$obj->isStale ) {
319             $cursor = $obj->dbh->db_cursor;
320              
321             if ( defined $cursor and $cursor->c_get( $key, $val, DB_NEXT ) == 0 )
322             {
323             %o = ( $key => $val );
324             $obj->set( 'cursor', $cursor );
325             }
326             } else {
327             $@ = pdebug( 'FIRSTKEY called on a stale object', PDLEVEL1 );
328             carp $@;
329             }
330              
331             pOut();
332             pdebug( 'leaving w/rv: %s', PDLEVEL3, %o );
333              
334             return each %o;
335             }
336              
337             sub NEXTKEY {
338             my $obj = shift;
339             my $cursor = $obj->get('cursor');
340             my ( $key, $val ) = ( '', '' );
341             my (%o);
342              
343             pdebug( 'entering', PDLEVEL3 );
344             pIn();
345              
346             if ( !$obj->isStale ) {
347             if ( defined $cursor ) {
348             if ( $cursor->c_get( $key, $val, DB_NEXT ) == 0 ) {
349             %o = ( $key => $val );
350             } else {
351             $obj->set( 'cursor', undef );
352             }
353             }
354             } else {
355             $@ = pdebug( 'NEXTKEY called on a stale object', PDLEVEL1 );
356             carp $@;
357             }
358              
359             pOut();
360             pdebug( 'leaving w/rv: %s', PDLEVEL3, %o );
361              
362             return each %o;
363             }
364              
365             sub SCALAR {
366             my $obj = shift;
367             my ( $key, $rv );
368              
369             pdebug( 'entering', PDLEVEL3 );
370             pIn();
371              
372             if ( !$obj->isStale ) {
373             if ( defined( $key = $obj->FIRSTKEY ) ) {
374             $rv = 1;
375             $obj->set( 'cursor', undef );
376             } else {
377             $rv = 0;
378             }
379             } else {
380             $@ = pdebug( 'SCALAR called on a stale object', PDLEVEL1 );
381             carp $@;
382             }
383              
384             pOut();
385             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
386              
387             return $rv;
388             }
389              
390             sub UNTIE {
391             my $obj = shift;
392             my $rv = 1;
393              
394             pdebug( 'entering', PDLEVEL3 );
395             pIn();
396              
397             if ( !$obj->isStale ) {
398             $obj->set( 'cursor', undef );
399             } else {
400             $@ = pdebug( 'UNTIE called on a stale object', PDLEVEL1 );
401             carp $@;
402             }
403              
404             pOut();
405             pdebug( 'leaving w/rv: %s', PDLEVEL3, $rv );
406              
407             return $rv;
408             }
409              
410             1;
411              
412             __END__