File Coverage

blib/lib/Pixie/Store.pm
Criterion Covered Total %
statement 36 72 50.0
branch 5 14 35.7
condition 2 2 100.0
subroutine 9 23 39.1
pod 4 18 22.2
total 56 129 43.4


line stmt bran cond sub pod time code
1             package Pixie::Store;
2              
3 16     16   85 use strict;
  16         27  
  16         1203  
4             our $VERSION="2.06";
5             my %typemap = ( memory => 'Pixie::Store::Memory',
6             bdb => 'Pixie::Store::BerkeleyDB',
7             dbi => 'Pixie::Store::DBI', );
8              
9 16     16   82 use Scalar::Util qw/weaken/;
  16         28  
  16         868  
10 16     16   86 use Carp;
  16         35  
  16         16936  
11              
12             #use overload
13             # '""' => 'as_string';
14              
15             sub as_string {
16 1     1 0 4 my $proto = shift;
17 1         3 my $str;
18 1 50       4 if (ref $proto) {
19 1         4 $str .= ref($proto);
20 1 50       8 $str .= ": $proto->{spec}" if $proto->{spec};
21             }
22             else {
23 0         0 $str .= $proto;
24             }
25 1         374 return $str;
26             }
27              
28             sub connect {
29 46     46 1 132 my $proto = shift;
30 46         69 my $spec = shift;
31 46         171 my($type, $path) = split(':', $spec, 2);
32              
33 46         108 $type = lc($type);
34 46 50       150 die "Invalid database spec" unless exists $typemap{$type};
35              
36 46         2993 eval "require " . $typemap{$type};
37 46 100       370 die $@ if $@;
38              
39 37         276 my $self = $typemap{$type}->connect($path,@_);
40 37         97 $self->{spec} = $spec;
41 37         179 return $self;
42             }
43              
44             sub object_graph_for {
45 0     0 0 0 my $self = shift;
46 0         0 my $pixie = shift;
47              
48 0         0 my $graph = $pixie->get_object_named('PIXIE::Node Graph');
49 0 0       0 unless ($graph) {
50 0         0 $graph = Pixie::ObjectGraph->new;
51 0         0 $pixie->bind_name('PIXIE::Node Graph' => $graph);
52             }
53 0         0 return $graph;
54             }
55              
56              
57             sub remove_from_store {
58 0     0 0 0 my $self = shift;
59 0         0 my($oid) = @_;
60              
61 0         0 $self->remove_from_rootset($oid)
62             ->_delete($oid);
63             }
64              
65             # Low level locking
66              
67             sub locked_set {
68 83     83 0 118 my $self = shift;
69 83   100     651 return $self->{locked_set} ||= {};
70             }
71              
72             sub lock_object_for {
73 0     0 0 0 my $self = shift;
74 0         0 my($oid, $locker) = @_;
75 0         0 $self->locked_set->{ $oid } = $locker->_oid;
76 0         0 return 1;
77             }
78              
79             sub unlock_object_for {
80 30     30 0 57 my $self = shift;
81 30         59 my $oid = shift;
82 30         108 delete $self->locked_set->{$oid};
83             }
84              
85             sub release_all_locks {
86 53     53 0 95 my $self = shift;
87 53         195 my $locked_set = $self->locked_set;
88 0         0 $self->unlock_object_for(@$_)
89 53         217 for map {[$_ => $locked_set->{$_}]}
90             keys %$locked_set;
91 53         1015 return $self;
92             }
93              
94             sub add_to_rootset {
95 0     0 0 0 my $self = shift;
96 0         0 my $thing = shift;
97 0 0       0 $self->_add_to_rootset($thing) unless $self->is_hidden($thing);
98             }
99              
100             sub is_hidden {
101 0     0 0 0 my $self = shift;
102 0         0 my $thing = shift;
103              
104 0         0 $thing->PIXIE::oid =~ /^
105             }
106              
107 0     0   0 sub _add_to_rootset { $_[0]->subclass_responsibility(@_) }
108              
109             sub remove_from_rootset {
110 0     0 0 0 $_[0]->subclass_responsibility($_[0]);
111             }
112              
113             sub rootset {
114 0     0 0 0 $_[0]->subclass_responsibility;
115             }
116              
117 0     0 1 0 sub lock { $_[0]->subclass_responsibility(@_) }
118 0     0 1 0 sub unlock { $_[0]->subclass_responsibility(@_) }
119 0     0 1 0 sub rollback { $_[0]->subclass_responsibility(@_) }
120              
121              
122             sub lock_for_GC {
123 0     0 0 0 my $self = shift;
124 0         0 $self->lock;
125             }
126              
127             sub unlock_after_GC {
128 0     0 0 0 my $self = shift;
129 0         0 $self->unlock;
130             }
131              
132             sub subclass_responsibility {
133 0     0 0 0 my $self = shift;
134 0         0 require Carp;
135 0         0 Carp::carp( (caller(1))[3], " not implemented for ", ref($self) );
136 0 0       0 return wantarray ? @_ : $_[-1];
137             }
138              
139             sub DESTROY {
140 33     33   63 my $self = shift;
141 33         138 $self->release_all_locks;
142             }
143              
144             1;
145              
146             __END__