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; |