File Coverage

blib/lib/Pixie/Store/BerkeleyDB.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Pixie::Store::BerkeleyDB;
2              
3 6     6   33 use Storable qw/nfreeze thaw/;
  6         12  
  6         388  
4 6     6   2640 use BerkeleyDB;
  0            
  0            
5             use File::Spec;
6              
7             our $VERSION="2.06";
8              
9             use base qw/Pixie::Store/;
10              
11             sub new {
12             my $proto = shift;
13             my $self = bless { db => undef }, $proto;
14             $self->init;
15             return $self;
16             }
17              
18             sub init { $_[0] }
19              
20             sub connect {
21             my $self = shift;
22             my($vol, $dir, $file) = File::Spec->splitpath( shift );
23             $dir ||= File::Spec->curdir;
24              
25             $self = $self->new unless ref $self;
26              
27             $self->db(BerkeleyDB::Hash->new
28             (
29             -Env =>
30             BerkeleyDB::Env->new( -Home => File::Spec->catpath($vol, $dir, ''),
31             -Flags => (DB_CREATE | DB_INIT_LOCK |
32             DB_INIT_MPOOL |
33             DB_INIT_TXN | DB_RECOVER), ),
34             -Filename => $file,
35             -Flags => DB_CREATE, ));
36             return $self;
37             }
38              
39             sub db {
40             my $self = shift;
41              
42             if (@_) {
43             my $db = shift;
44             die "Pixie::Store::BerkeleyDB::db must be an instance of BerkeleyDB::Common"
45             unless defined($db) && $db->isa('BerkeleyDB::Common');
46             $self->{db} = $db;
47             return $self;
48             }
49             else {
50             return $self->{db} ||= $self->make_in_memory_db;
51             }
52             }
53              
54             sub make_in_memory_db {
55             my $self = shift;
56             BerkeleyDB::Hash->new( -Flags => DB_CREATE, );
57             }
58              
59             sub store_at {
60             my $self = shift;
61             my($oid, $obj) = @_;
62              
63             $self->db->db_put($oid, nfreeze($obj));
64             return ($oid, $obj);
65             }
66              
67             sub get_object_at {
68             my $self = shift;
69             my($oid) = @_;
70             my($val);
71              
72             $self->db->db_get($oid,$val);
73              
74             return thaw $val;
75             }
76              
77             sub _delete {
78             my $self = shift;
79             my($oid) = @_;
80             my $val;
81             my $db = $self->db;
82             my $ret = $db->db_get($oid, $val) == 0;
83             $db->db_del($oid);
84             return $ret;
85             }
86              
87             sub clear {
88             my $self = shift;
89             $self->lock;
90             my $cursor = $self->db->db_cursor;
91             my($k,$v) = ('','');
92             while ($cursor->c_get($k,$v, DB_NEXT) != DB_NOTFOUND) {
93             $cursor->c_del
94             }
95             $cursor->c_close;
96             $self->unlock;
97             }
98              
99             sub lock { $_[0] }
100             sub unlock { $_[0] }
101             sub rollback { $_[0] }
102              
103             sub rootset {
104             my $self = shift;
105             my @set = $self->_rootset_hash->keys;
106             return @set;
107             }
108              
109             sub _rootset_hash {
110             my $self = shift;
111             my $set = shift;
112             unless ($set = $self->get_object_at('')) {
113             $set = Pixie::BDB::Rootset->new;
114             }
115             return $set;
116             }
117              
118             sub db_keys {
119             my $self = shift;
120             my @keys;
121             my $cursor = $self->db->db_cursor;
122             my($k,$v) = ('','');
123             push @keys, $k while $cursor->c_get($k,$v, DB_NEXT) == 0;
124             return @keys;
125             }
126              
127             sub working_set_for {
128             my $self = shift;
129             my $pixie = shift;
130             my %set = map { $_ => undef } grep !/^db_keys;
131             delete $set{$self->object_graph_for($pixie)->PIXIE::oid};
132             wantarray ? keys %set : [keys %set];
133             }
134              
135             sub _add_to_rootset {
136             my $self = shift;
137             my $oid = shift->PIXIE::oid;
138             my $set = $self->_rootset_hash;
139             $set->{$oid} = 1;
140             $self->store_at('' => $set);
141             return $self;
142             }
143              
144             sub remove_from_rootset {
145             my $self = shift;
146             my $oid = shift;
147             my $set = $self->_rootset_hash;
148             delete $set->{$oid};
149             $self->store_at('' => $set);
150             return $self;
151             }
152              
153              
154             package Pixie::BDB::Rootset;
155              
156             sub new { bless {}, $_[0] }
157             sub keys { keys %{$_[0]} }
158              
159             1;