File Coverage

blib/lib/Class/Persistent/StructTemplate.pm
Criterion Covered Total %
statement 19 160 11.8
branch 3 76 3.9
condition 0 21 0.0
subroutine 5 13 38.4
pod 0 8 0.0
total 27 278 9.7


line stmt bran cond sub pod time code
1             #
2             # Class::Persistent::StructTemplate - Persistent implementation of Class::StructTemplate. Uses a plugin to enable persistence through various interfaces.
3             # $Id$
4             #
5             # Copyright (C) 2000 by Heiko Wundram.
6             # All rights reserved.
7             #
8             # This program is free software; you can redistribute and/or modify it under the same terms as Perl itself.
9             #
10             # $Log$
11             #
12              
13             package Class::Persistent::StructTemplate;
14             $Class::Persistent::StructTemplate::VERSION = '0.01';
15              
16             require Exporter;
17             @Class::Persistent::StructTemplate::ISA = qw(Exporter Class::StructTemplate);
18             @Class::Persistent::StructTemplate::EXPORT = qw(attributes);
19              
20 1     1   882 use Class::StructTemplate qw();
  1         2  
  1         21  
21              
22 1     1   5 use Carp;
  1         2  
  1         60  
23              
24 1     1   1304 use Data::Dumper;
  1         11680  
  1         2041  
25              
26             sub attributes
27             {
28 1 50   1 0 6 my ($pkg) = ref $_[0] ? (${ shift() }) : caller();
  0         0  
29              
30 1 50       6 if( @_ < 2 )
31             {
32 0         0 confess "Need at least one attribute to assign to new class!";
33             }
34              
35 1         2 my $plugin = shift();
36 1         2 my $plugin_parms = shift();
37              
38 1     1   636 eval "use $plugin;";
  1         4  
  1         25  
  1         74  
39 1 50       6 confess "Couldn't load storage plugin $plugin (error: $@)!" if $@;
40 1 0       8 (${"${pkg}::_PLUGIN"} = new $plugin (@$plugin_parms)) or confess "Couldn't create storage plugin $plugin!";
  0            
41              
42 0 0         Class::StructTemplate::attributes(\$pkg,@_) or confess "Couldn't create class $pkg!";
43              
44 0           ${"${pkg}::_max_id"} = ${"${pkg}::_PLUGIN"}->get_max_id($pkg);
  0            
  0            
45              
46 0 0         _define_load($pkg) or confess "Couldn't create load-constructor for class $pkg!";
47              
48 0           return 1;
49             }
50              
51             sub _define_load
52             {
53 0 0   0     if( @_ != 1 )
54             {
55 0           confess "_define_load can only be called with one argument!";
56             }
57              
58 0           my ($pkg) = @_;
59              
60 0           my $accs = qq|
61             package $pkg;
62              
63             sub load
64             {
65             my (\$class,\$type) = \@_;
66             \$class = ref \$class ? ref \$class : \$class;
67             my (\@self);
68              
69             \@self = \$class->load_into(\$type);
70              
71             return \@self;
72             }|;
73              
74 0           eval $accs;
75              
76 0 0         croak $@ if $@;
77 0           return !$@;
78             }
79              
80             sub load_into
81             {
82 0 0   0 0   if( @_ != 2 )
83             {
84 0           confess "load_into can only be called with one arguments!";
85             }
86              
87 0           my ($class,$type) = @_;
88 0           my $done = 0;
89 0 0         my $pkg = ref $class ? ref $class : $class;
90 0           my $self;
91 0           my @ret_val = ();
92              
93 0 0         if( ref $class )
94             {
95 0           $done = ${"${pkg}::_PLUGIN"}->load($class,$pkg,$type);
  0            
96 0 0         if( $done != -1 )
97             {
98 0           $class->{"_created"} = 1;
99 0           $class->{"_changed"} = 0;
100             }
101              
102 0 0         return $done!=-1?$class:undef;
103             }
104             else
105             {
106 0   0       while( !$done && $done != -1 )
107             {
108 0           $self = new $pkg;
109 0           $done = ${"${pkg}::_PLUGIN"}->load($self,$pkg,$type);
  0            
110 0           $self->{"_created"} = 1;
111 0           $self->{"_changed"} = 0;
112              
113 0 0 0       if( !$done && $done != -1 )
114             {
115 0           $self->{"_created"} = 1;
116 0           $self->{"_changed"} = 0;
117 0           push @ret_val, $self;
118             }
119             }
120              
121 0           return @ret_val;
122             }
123             }
124              
125             sub save
126             {
127 0 0   0 0   if( @_ != 1 )
128             {
129 0           confess "save isn't called with any arguments!";
130             }
131              
132 0           my ($class) = @_;
133 0 0         ref $class or confess "Can only save an instance of class ".ref($class)."!";
134 0           my $pkg = ref $class;
135 0           my $done;
136              
137 0 0         if( !$class->{"_changed"} )
138             {
139 0           return 1;
140             }
141              
142 0 0         if( $class->{"_created"} )
143             {
144 0           $done = ${"${pkg}::_PLUGIN"}->save($class,$pkg);
  0            
145             }
146             else
147             {
148 0           $done = ${"${pkg}::_PLUGIN"}->store($class,$pkg);
  0            
149             }
150              
151 0 0         if( $done )
152             {
153 0           $class->{"_changed"} = 0;
154 0           $class->{"_created"} = 1;
155             }
156              
157 0           return $done;
158             }
159              
160             sub delete
161             {
162 0 0   0 0   if( @_ != 1 )
163             {
164 0           confess "delete isn't called with any arguments!";
165             }
166              
167 0           my ($class) = @_;
168 0 0         ref $class or confess "Can only delete an instance of class ".ref($class)."!";
169 0           my $pkg = ref $class;
170 0           my $done = 1;
171 0           my $is_a;
172              
173 0 0 0       if( $class->{"_changed"} || !$class->{"_created"} )
174             {
175 0           return 0;
176             }
177              
178 0           foreach $attrib (@${"${pkg}::_ATTRIBUTES"},"_id")
  0            
179             {
180 0           eval "\$is_a = \$class->{\$attrib}->isa('Class::Persistent::StructTemplate')";
181              
182 0 0 0       if( !$@ && $is_a )
183             {
184 0           $done &= $class->{$attrib}->delete;
185             }
186             }
187              
188 0 0         if( ${"${pkg}::_PLUGIN"}->calc_refs($class,$pkg) <= 1 )
  0            
189             {
190 0           ${"${pkg}::_PLUGIN"}->delete($class,$pkg);
  0            
191 0           $class->{"_created"} = 0;
192 0           $class->{"_changed"} = 1;
193             }
194              
195 0           ${"${pkg}::_PLUGIN"}->check_tables;
  0            
196              
197 0           return $done;
198             }
199              
200              
201             sub set_attributes_type
202             {
203 0 0   0 0   if( @_ != 3 )
204             {
205 0           confess "set_attributes_type can only be called with two arguments!";
206             }
207              
208 0           my ($class,$attribs,$types) = @_;
209 0 0         ref $class or confess "Can only set attributes to an instance of this class!";
210 0           my $pkg = ref $class;
211 0           my ($attrib);
212              
213 0           foreach $attrib (@${"${pkg}::_ATTRIBUTES"},"_id")
  0            
214             {
215 0 0         if( exists $attribs->{$attrib} )
    0          
216             {
217 0           $class->$attrib(restore_val($attribs->{$attrib},$types->{$attrib}));
218             }
219             elsif( !$class->{"_allset"} )
220             {
221 0           $class->$attrib(undef);
222             }
223             }
224              
225 0           $class->{"_allset"} = 1;
226              
227 0           return $class;
228             }
229              
230             sub get_attributes_type
231             {
232 0 0   0 0   if( @_ != 1 )
233             {
234 0           confess "get_attributes is never called with arguments!";
235             }
236              
237 0           my ($class) = @_;
238 0 0         ref $class or confess "Can only get attributes of an instance of this class!";
239 0           my $pkg = ref $class;
240 0           my ($attrib);
241 0           my ($ret_val1,$ret_val2) = ({},{});
242              
243 0           foreach $attrib (@${"${pkg}::_ATTRIBUTES"},"_id")
  0            
244             {
245 0           ($ret_val1->{$attrib},$ret_val2->{$attrib}) = store_val($class->{$attrib});
246             }
247              
248 0           return ($ret_val1,$ret_val2);
249             }
250              
251             sub restore_val
252             {
253 0 0   0 0   if( @_ != 2 )
254             {
255 0           confess "restore_val can only be called with two parameters!";
256             }
257              
258 0           my ($val,$type) = @_;
259 0           my ($id,$class);
260 0           my $ret_val;
261              
262 0 0 0       if( $type eq 'n' || $type eq 's' )
    0          
263             {
264 0           $ret_val = $val;
265             }
266             elsif( $type eq 'c' )
267             {
268 0           $val =~ /^(.*?)\|(.*)$/;
269 0           $id = $1;
270 0           $class = $2;
271              
272 0           eval "use $class;";
273 0 0         confess "Could not load class $class (error: $@)!" if $@;
274              
275 0           ($ret_val) = $class->load("_id = $id");
276             }
277             else
278             {
279 0           eval $val;
280             }
281              
282 0           return $ret_val;
283             }
284              
285             sub store_val
286             {
287 0 0   0 0   if( @_ != 1 )
288             {
289 0           confess "store_val can only be called with one parameter!";
290             }
291              
292 0           my ($val) = @_;
293 0           my ($ret_val1,$ret_val2);
294 0           my $is_a;
295              
296 0 0 0       if( ref $val )
    0          
297             {
298 0           eval "\$is_a = \$val->isa('Class::Persistent::StructTemplate');";
299 0 0 0       if( !$@ && $is_a )
300             {
301 0           $ret_val2 = 'c';
302 0           $ret_val1 = $val->_id()."|".ref($val);
303              
304 0           $val->save();
305             }
306             else
307             {
308 0           local $Data::Dumper::Purity = 1;
309 0           local $Data::Dumper::Useqq = 1;
310 0           local $Data::Dumper::Indent = 0;
311              
312 0           $ret_val2 = 'd';
313 0           $ret_val1 = Data::Dumper->Dump([$val],[qw(ret_val)]);
314             }
315             }
316             elsif( $val == 0 && $val ne '0' )
317             {
318 0           $ret_val2 = 's';
319 0           $ret_val1 = $val;
320             }
321             else
322             {
323 0           $ret_val2 = 'n';
324 0           $ret_val1 = $val;
325             }
326              
327 0           return ($ret_val1,$ret_val2);
328             }
329              
330             1;