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 |