File Coverage

blib/lib/Jifty/DBI/Column.pm
Criterion Covered Total %
statement 56 68 82.3
branch 26 36 72.2
condition 14 18 77.7
subroutine 13 17 76.4
pod 10 10 100.0
total 119 149 79.8


line stmt bran cond sub pod time code
1 30     30   118 use warnings;
  30         42  
  30         1000  
2 30     30   110 use strict;
  30         43  
  30         1540  
3              
4             package Jifty::DBI::Column;
5              
6             our $VERSION = '0.01';
7 30     30   114 use base qw/Class::Accessor::Fast Jifty::DBI::HasFilters/;
  30         45  
  30         3170  
8 30     30   10891 use UNIVERSAL::require;
  30         23801  
  30         231  
9 30     30   11493 use version;
  30         44168  
  30         136  
10              
11             my @attrs = qw/
12             name
13             type
14             default
15             readable writable
16             max_length
17             mandatory
18             virtual
19             computed
20             distinct
21             sort_order
22             refers_to by
23             alias_for_column
24             aliased_as
25             since till
26             indexed
27             _validator
28             _checked_for_validate_sub
29             record_class
30             attributes
31             case_sensitive
32             private
33             protected
34             encode_on_select
35             /;
36              
37             # these actually live in the attributes hash
38             my @handy_attrs = qw/
39             container
40             label hints render_as
41             display_length
42             documentation
43             valid_values
44             available_values
45             autocompleted
46             no_placeholder
47             /;
48              
49             # compat: this should probably never exist and be deprecated
50             our @ATTRS = (@attrs, @handy_attrs);
51              
52             __PACKAGE__->mk_accessors(@attrs);
53              
54             for my $attr (@handy_attrs) {
55 30     30   3079 no strict 'refs';
  30         39  
  30         18728  
56             *$attr = sub {
57 139     139   190 my $self = shift;
58 139 50       404 $self->attributes({}) unless $self->attributes;
59 139 100       1066 return $self->attributes->{$attr} unless @_;
60 7 50       18 $self->attributes->{$attr} = (@_ == 1 ? $_[0] : [@_]);
61             }
62             }
63              
64             =head1 NAME
65              
66             Jifty::DBI::Column - Encapsulates a single column in a Jifty::DBI::Record table
67              
68             =head1 DESCRIPTION
69              
70              
71             This class encapsulates a single column in a Jifty::DBI::Record table
72             description. It replaces the _accessible method in
73             L.
74              
75             It has the following accessors: C
76             refers_to readable writable length>.
77              
78             =cut
79              
80             =head2 new
81              
82             =cut
83              
84             sub new {
85 143     143 1 925 my ($class, $args) = @_;
86 143         659 my $self = $class->SUPER::new({});
87              
88             # run through accessors, push unknown keys into the attributes hash
89              
90             # XXX: we might want to construct the proper hash (lifting things
91             # not in @attrs into attributes and just pass the whole hash
92 143         1160 $self->attributes({});
93 143         974 for (keys %$args) {
94 271 100       1291 if ($self->can($_)) {
95 264         486 $self->$_($args->{$_});
96             } else {
97 7         13 $self->attributes->{$_} = $args->{$_};
98             }
99             }
100              
101 143         591 return $self;
102             }
103              
104             =head2 is_numeric
105              
106             Returns true if the column is of some numeric type, otherwise returns false.
107              
108             =cut
109              
110             sub is_numeric {
111 7     7 1 41 my $self = shift;
112 7 100       21 if ( $self->type =~ /INT|NUMERIC|DECIMAL|REAL|DOUBLE|FLOAT/i ) {
113 3         38 return 1;
114             }
115 4         56 return 0;
116             }
117              
118              
119              
120             =head2 is_string
121              
122             Returns true if this column is a text field
123              
124             =cut
125              
126              
127             sub is_string {
128 241     241 1 279 my $self = shift;
129 241 100       578 if ( $self->type =~ /CHAR|TEXT/i ){
130 84         909 return 1;
131             }
132 157         1542 return 0;
133             }
134              
135             =head2 is_boolean
136              
137             Returns true if this column is a boolean
138              
139             =cut
140              
141             sub is_boolean {
142 0     0 1 0 my $self = shift;
143 0 0       0 return 1 if grep { $_->isa('Jifty::DBI::Filter::Boolean') } $self->output_filters;
  0         0  
144 0 0       0 return 1 if $self->type =~ /BOOL/i;
145 0         0 return 0;
146             }
147              
148             =head2 serialize_metadata
149              
150             Returns a hash describing this column object with enough detail to
151             fully describe it in the database. Intentionally skips
152             C, all column attributes starting with C<_>, and all
153             column attributes which are undefined. The "known" attributes in the
154             C hash are flattened and returned as well. The list of
155             known attributes are:
156              
157             =over
158              
159             =item container
160              
161             =item label hints render_as
162              
163             =item display_length
164              
165             =item valid_values
166              
167             =item available_values
168              
169             =item autocompleted
170              
171             =item documentation
172              
173             =item no_placeholder
174              
175             Setting this to a true value causes L
176             to not use a placeholder when loading the column. This can allow the
177             database to come up with better query plans in some cases.
178              
179             =back
180              
181             =cut
182              
183             sub serialize_metadata {
184 1     1 1 843 my $self = shift;
185 1 100 100     3 return {map { $_ => $self->$_() } grep { $_ ne 'attributes' && $_ ne 'record_class' && $_ !~ /^_/ && defined $self->$_}
  6   100     19  
  36         260  
186             @ATTRS};
187             }
188              
189             =head2 serialize_metadata2
190              
191             Returns a hash describing this column object with enough detail to
192             fully describe it in the database. Intentionally skips C,
193             all column attributes starting with C<_>, and all column attributes
194             which are undefined.
195              
196             =cut
197              
198             sub serialize_metadata2 {
199 0     0 1 0 my $self = shift;
200 0 0 0     0 return {map { $_ => $self->$_() } grep { $_ ne 'record_class' && $_ !~ /^_/ && defined $self->$_} @attrs};
  0         0  
  0         0  
201             }
202              
203             =head2 validator
204              
205             Gets/sets the validator coderef for the column.
206              
207             =cut
208              
209             sub validator {
210 59     59 1 89 my $self = shift;
211              
212 59 50 66     285 if ( @_ ) {
    100          
213 0         0 $self->_validator( shift );
214             }
215             elsif ( not $self->_checked_for_validate_sub and not $self->_validator ) {
216 21 50       273 my $name = ( $self->aliased_as ? $self->aliased_as : $self->name );
217 21         213 my $can = $self->record_class->can( "validate_" . $name );
218              
219 21 100       296 $self->_validator( $can ) if $can;
220 21         67 $self->_checked_for_validate_sub( 1 );
221             }
222              
223 59         422 return $self->_validator;
224             }
225              
226             # Aliases for compatibility with searchbuilder code
227             *read = \&readable;
228             *write = \&writable;
229              
230             =head2 read
231              
232             DEPRECATED. Use C<< $column->readable >> instead.
233              
234             =head2 write
235              
236             DEPRECATED. Use C<< $column->writable >> instead.
237              
238             =head2 length
239              
240             DEPRECATED. Use C<< $column->max_length >> instead.
241              
242             =head2 until
243              
244             DEPRECATED. Use C<< $column->till >> instead.
245              
246             =cut
247              
248 0     0 1 0 sub length { Carp::croak('$column->length is no longer supported; use $column->max_length instead') }
249 0     0 1 0 sub until { Carp::croak('$column->until is no longer supported; use $column->till instead') }
250              
251             =head2 active
252              
253             Returns the a true value if the column method exists for the current application
254             version. The current application version is determined by checking the L of the column's L. This method returns a false value if the column is not yet been added or has been dropped.
255              
256             This method returns a false value under these circumstances:
257              
258             =over
259              
260             =item *
261              
262             Both the C trait and C method are defined and C is less than the version set on C.
263              
264             =item *
265              
266             Both the C trait and C method are defined and C is greater than or equal to the version set on C.
267              
268             =back
269              
270             Otherwise, this method returns true.
271              
272             =cut
273              
274             sub active {
275 448     448 1 1041 my $self = shift;
276              
277 448 100       728 return 1 unless $self->record_class->can('schema_version');
278 79 100       468 return 1 unless defined $self->record_class->schema_version;
279              
280 70         404 my $version = version->new($self->record_class->schema_version);
281              
282             # The application hasn't yet started using this column
283 70 100 100     566 return 0 if defined $self->since
284             and $version < version->new($self->since);
285              
286             # The application stopped using this column
287 67 100 100     350 return 0 if defined $self->till
288             and $version >= version->new($self->till);
289              
290             # The application currently uses this column
291 61         323 return 1;
292             }
293              
294             1;