File Coverage

blib/lib/Class/ReluctantORM/Base.pm
Criterion Covered Total %
statement 12 58 20.6
branch 0 24 0.0
condition 0 3 0.0
subroutine 4 10 40.0
pod 4 4 100.0
total 20 99 20.2


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Class::ReluctantORM::Base - Class building helper
4              
5             =head1 SYNOPSIS
6              
7             package Person;
8             use base 'Class::ReluctantORM::Base';
9              
10             __PACKAGE__->build_class(
11             fields => [ qw(person_id name birthdate) ],
12             ro_fields => [ qw(person_id) ],
13              
14             # See Class::ReluctantORM
15             );
16              
17             # Now you have...
18             package main;
19             my $p = Person->new(name => 'SuchAndSuch', birthdate => '2008-01-12');
20             print $p->name . " was born on " . $p->birthdate() . "\n";
21             $p->name('WhatsTheirFace');
22              
23             $p->person_id(123); # Kaboom, person_id is readonly
24              
25             =head1 DESCRIPTION
26              
27             Provides class-building facilities for Class::ReluctantORM, including
28             defining accessors and mutators.
29              
30             =head1 SEE ALSO
31              
32             Class::ReluctantORM, which leverages this class heavily.
33              
34             =head1 PUBLIC CLASS METHODS
35              
36             =cut
37              
38             package Class::ReluctantORM::Base;
39 1     1   8 use strict;
  1         2  
  1         42  
40 1     1   6 use Carp;
  1         1  
  1         74  
41 1     1   750 use Class::ReluctantORM::Exception;
  1         5  
  1         48  
42 1     1   10 use base 'Class::Accessor';
  1         2  
  1         1091  
43              
44             our $DEBUG = 0;
45              
46             =head2 $class->build_class(%args);
47              
48             Sets up $class to have the accessors and mutators given.
49              
50             Extra parameters are ignored.
51              
52             =over 4
53              
54             =item fields
55              
56             An array ref of field names, which will be used to create accessors,
57             and if not listed in ro_fields, also mutators.
58              
59             =item ro_fields
60              
61             An array ref of field names, which will be restricted to be read-only.
62              
63             =back
64              
65             =cut
66              
67             sub build_class {
68 0     0 1   my $class = shift;
69              
70 0           my $meta = $class->__metadata();
71              
72 0 0         if (@_ % 2) { Class::ReluctantORM::Exception::Param::ExpectedHash->croak(); }
  0            
73 0           my %args = @_;
74              
75 0           my $fields = $args{fields};
76 0 0         unless ($fields) { Class::ReluctantORM::Exception::Param::Missing->croak(param => 'fields'); }
  0            
77 0 0         unless (ref($fields) eq 'ARRAY') { Class::ReluctantORM::Exception::Param::ExpectedArrayRef->croak(param => 'fields'); }
  0            
78 0 0         unless (@$fields) { Class::ReluctantORM::Exception::Param::Empty->croak(param => 'fields'); }
  0            
79              
80 0           my %mutability_by_field = map { $_ => 1 } @$fields;
  0            
81 0 0         unless ( keys (%mutability_by_field) == @$fields) { Class::ReluctantORM::Exception::Param::Duplicate->croak(param => 'fields', value => join ' ', @$fields); }
  0            
82              
83 0 0         foreach my $f (@{$args{ro_fields} || []}) {
  0            
84 0 0         unless (exists $mutability_by_field{$f}) { Class::ReluctantORM::Exception::Param::Missing->croak(param => 'ro_fields', value => $f); }
  0            
85 0           $mutability_by_field{$f} = 0;
86             }
87              
88             # Create accessors
89 0           $class->mk_accessors(grep {$mutability_by_field{$_} == 1} keys %mutability_by_field);
  0            
90 0           $class->mk_ro_accessors(grep {$mutability_by_field{$_} == 0} keys %mutability_by_field);
  0            
91              
92 0           $meta->{fields} = $fields;
93             }
94              
95             # Allow passing a single hashref or a hash
96             sub new {
97 0     0 1   my $class = shift;
98              
99 0           my $hash_ref = {};
100 0 0         if (@_ == 1) {
    0          
101 0           $hash_ref = shift;
102 0 0         unless (ref($hash_ref) eq 'HASH') { Class::ReluctantORM::Exception::Param::ExpectedHashRef->croak(); }
  0            
103             } elsif (@_ % 2) {
104 0           Class::ReluctantORM::Exception::Param::ExpectedHash->croak();
105             } else {
106 0           $hash_ref = { @_ };
107             }
108              
109 0           return $class->SUPER::new($hash_ref);
110              
111             }
112              
113             # Override this so that we throw Class::ReluctantORM::Exceptions
114             sub make_ro_accessor {
115 0     0 1   my($class, $field) = @_;
116              
117             return sub {
118 0     0     my $self = shift;
119              
120 0 0         if (@_) {
121 0           Class::ReluctantORM::Exception::Call::NotMutator->croak(attribute => $field);
122             } else {
123 0           return $self->get($field);
124             }
125 0           };
126             }
127              
128              
129             =head2 @field_names = $class->field_names();
130              
131             Returns a list of the field names for the given class.
132              
133             =cut
134              
135             # Used to be protected
136 0     0 1   sub field_names { return shift->_field_names(); }
137              
138             sub _field_names {
139 0     0     my $inv = shift;
140 0   0       my $class = ref($inv) || $inv;
141 0 0         return @{$class->__metadata()->{fields} || []};
  0            
142             }
143              
144             =head1 AUTHOR
145              
146             Clinton Wolfe
147              
148             =cut
149              
150             1;