File Coverage

lib/Oryx/Value.pm
Criterion Covered Total %
statement 6 57 10.5
branch 0 18 0.0
condition n/a
subroutine 2 18 11.1
pod 11 11 100.0
total 19 104 18.2


line stmt bran cond sub pod time code
1             package Oryx::Value;
2              
3 15     15   80 use base qw(Class::Data::Inheritable);
  15         26  
  15         1174  
4              
5             use Module::Pluggable(
6 15         106 search_path => 'Oryx::Value',
7             sub_name => 'types',
8             require => 1,
9 15     15   14036 );
  15         258601  
10              
11             =head1 NAME
12              
13             Value - base class for value types for the Oryx object persistence tool
14              
15             =head1 SYNOPSIS
16              
17             # constructor - this is what you should do
18             tie $obj->{some_field}, 'Oryx::Value::SomeType', ($meta, $owner);
19            
20             # this is if you really must call these methods on the tied object
21             # although normally these are called by the tied object on $self
22             tied($obj->{some_field})->deflate($value);
23             tied($obj->{some_field})->inflate($value);
24             tied($obj->{some_field})->check($value);
25             tied($obj->{some_field})->check_required($value);
26             tied($obj->{some_field})->check_type($value);
27             tied($obj->{some_field})->check_size($value);
28             tied($obj->{some_field})->meta;
29             tied($obj->{some_field})->owner;
30              
31             =head1 DESCRIPTION
32              
33             This module is considered abstract and should be sublcassed to create the
34             actual Value types.
35              
36             The purpose of these Value types is to validate input and to prepare
37             field values for storage in the database via the C method and
38             to prepare the values for consumption after retrieval via the C
39             method.
40              
41             The tie constructor is passed the associated L instance which
42             can be accessed via C, along with the L instance to which
43             the Attribute - and therefore the value - belongs. The L instance
44             can be accessed with the C accessor.
45              
46             =head1 SUBCLASSING
47              
48             The C related methods: C, C and C, as well as
49             C should not be overridden when subclassing - they are documented here
50             for the sake of completeness.
51              
52             The C, C, C, and C methods are usually overloaded when subclassing.
53              
54             =head1 METHODS
55              
56             =over
57              
58             =item TIESCALAR( $meta, $owner )
59              
60             takes two arguments: C<$meta> and C<$owner> - C<$meta> is the L
61             instance with which this value is associated, and C<$owner> is the L
62             instance (or persistent object).
63              
64             This method should not be called directly, instead use
65              
66             my $attr_name = $attrib->name;
67             tie $object->{$attr_name}, 'Oryx::Value::String', $attrib, $object;
68            
69             =cut
70              
71             sub TIESCALAR {
72 0     0     my $class = shift;
73 0           my ($meta, $owner) = @_;
74 0           my $self = bless {
75             meta => $meta, # Oryx::Attribute instance
76             owner => $owner, # Oryx::Class instance
77             }, $class;
78              
79 0           $self->STORE($self->owner->{$self->meta->name});
80 0           return $self;
81             }
82              
83             =item FETCH
84              
85             automatically called by Perl when the field to which this Value is tied
86             is retrieved. You should not normally need to call this directly.
87              
88             =cut
89              
90             sub FETCH {
91 0     0     my $self = shift;
92 0 0         unless (defined $self->VALUE) {
93 0           my $value = $self->owner->{$self->meta->name};
94 0           $self->VALUE($self->inflate($value));
95             }
96 0           return $self->VALUE;
97             }
98              
99             =item STORE( $value )
100              
101             automatically called by Perl when the field to which this Value is tied
102             is set via assignment. You should not normally need to call this directly.
103              
104             =cut
105              
106             sub STORE {
107 0     0     my ($self, $value) = @_;
108 0 0         if ($self->check($value)) {
109 0           $self->VALUE($value);
110             } else {
111 0           $self->_croak('check failed ['.$value.'] MESSAGE: '.$self->errstr);
112             }
113             }
114              
115             =item VALUE
116              
117             mutator to the internal raw value held in this tied object instance
118              
119             =cut
120              
121             sub VALUE {
122 0     0 1   my $self = shift;
123 0 0         $self->{VALUE} = shift if @_;
124 0           return $self->{VALUE};
125             }
126              
127             =item deflate( $value )
128              
129             hook to modify the value before it is stored in the db. C<$value> is the
130             raw value associated with the attribute as it is in the live object. This
131             is not neccessarily the same as its representation in the database. Take
132             L for example. Complex serializes its value using
133             L before it saves it to the database. C does the serialization
134             in this case. It is passed the value in the live object which could be
135             a hash ref or array ref (or anything else that could be serialized using
136             YAML) and returns the serialized YAML string representation of that value.
137              
138             =cut
139              
140             sub deflate {
141 0     0 1   my ($self, $value) = @_;
142 0           return $value
143             }
144              
145             =item inflate( $value )
146              
147             hook to modify the value as it is loaded from the db. This is the complement
148             to C in that it takes the value loaded from the database and cooks
149             it before it is associated with the attribute of the live C object.
150              
151             In the case of L C<$value> is a YAML string which is
152             deserialized using YAML and the result returned.
153              
154             =cut
155              
156             sub inflate {
157 0     0 1   my ($self, $value) = @_;
158 0           return $value;
159             }
160              
161             =item check( $value )
162              
163             hook for checking the value before it is set. You should consider carefully
164             if you need to override this method as this one calls the other C
165             methods and sets C<< $self->errstr >> if any of them fail.
166              
167             =cut
168              
169             sub check {
170 0     0 1   my ($self, $value) = @_;
171 0 0         unless ($self->check_required($value)) {
172 0           $self->errstr('value required');
173 0           return 0;
174             }
175 0 0         if (defined $value) {
176 0 0         unless ($self->check_type($value)) {
177 0           $self->errstr('type mismatch');
178 0           return 0;
179             }
180 0 0         unless ($self->check_size($value)) {
181 0           $self->errstr('size mismatch');
182 0           return 0;
183             }
184             }
185 0           return 1;
186             }
187              
188             =item check_type( $value )
189              
190             hook for doing type checking on the passed C<$value>. Should return
191             1 if successful and 0 if not.
192              
193             =cut
194              
195             sub check_type {
196 0     0 1   my ($self, $value) = @_;
197 0           return 1;
198             }
199              
200             =item check_size( $value )
201              
202             hook for doing size checking on the passed C<$value>. Should return
203             1 if successful and 0 if not.
204              
205             =cut
206              
207             sub check_size {
208 0     0 1   my ($self, $value) = @_;
209 0           return 1;
210             }
211              
212             =item check_required( $value )
213              
214             hook for checking if the passed C<$value> is required. Should return
215             1 if the value is required and defined and 0 if required and not defined.
216             If the value is not required, return 1.
217              
218             =cut
219              
220             sub check_required {
221 0     0 1   my ($self, $value) = @_;
222 0 0         if ($self->meta->required) {
223 0           return defined $value;
224             } else {
225 0           return 1;
226             }
227             }
228              
229             =item errstr
230              
231             returns the error string if input checks failed.
232              
233             =cut
234              
235             sub errstr {
236 0     0 1   my $self = shift;
237 0 0         $self->{errstr} = shift if @_;
238 0           return $self->{errstr};
239             }
240              
241             =item meta
242              
243             simple accessor to meta data for this value type, in this case,
244             a reference to the L with which this Value instance
245             is associated.
246              
247             =cut
248              
249 0     0 1   sub meta { $_[0]->{meta} }
250              
251             =item owner
252              
253             returns the L which owns the L instance
254             with which this Value instance is associated.
255              
256             =cut
257              
258 0     0 1   sub owner { $_[0]->{owner} }
259              
260             =item primitive
261              
262             Returns a string representing the underlying primitive type. This is used by the storage driver to determine how to pick the data type to use to store the value. The possible values include:
263              
264             =over
265              
266             =item Integer
267              
268             =item String
269              
270             =item Text
271              
272             =item Binary
273              
274             =item Float
275              
276             =item Boolean
277              
278             =item DateTime
279              
280             =back
281              
282             There is an additional internal type called "Oid", but it should not be used.
283              
284             =cut
285              
286 0     0 1   sub primitive { $_[0]->_croak('abstract') }
287              
288             sub _croak {
289 0     0     my ($self, $msg) = @_;
290 0           $self->{owner}->_croak("<".$self->{meta}->name."> $msg");
291             }
292              
293             sub _carp {
294 0     0     my ($self, $msg) = @_;
295 0           $self->{owner}->_carp("<".$self->{meta}->name."> $msg");
296             }
297              
298             1;
299              
300             =back
301              
302             =head1 AUTHOR
303              
304             Copyright (C) 2005 Richard Hundt
305              
306             =head1 LICENCE
307              
308             This library is free software and may be used under the same terms as Perl itself.
309              
310             =cut