File Coverage

blib/lib/Fey/Column.pm
Criterion Covered Total %
statement 58 58 100.0
branch 4 4 100.0
condition n/a
subroutine 20 20 100.0
pod 4 4 100.0
total 86 86 100.0


line stmt bran cond sub pod time code
1             package Fey::Column;
2              
3 26     26   42197 use strict;
  26         38  
  26         851  
4 26     26   145 use warnings;
  26         37  
  26         603  
5 26     26   12078 use namespace::autoclean;
  26         419847  
  26         143  
6              
7             our $VERSION = '0.43';
8              
9 26     26   1996 use Scalar::Util qw( blessed weaken );
  26         42  
  26         1725  
10              
11 26     26   11449 use Fey::Column::Alias;
  26         95  
  26         1411  
12 26     26   158 use Fey::Exceptions qw( param_error object_state_error );
  26         47  
  26         2007  
13 26     26   563 use Fey::Literal;
  26         53  
  26         558  
14 26     26   133 use Fey::Table;
  26         44  
  26         514  
15 26     26   131 use Fey::Table::Alias;
  26         49  
  26         627  
16 26         220 use Fey::Types qw(
17             Bool
18             DefaultValue
19             GenericTypeName
20             PosInteger
21             PosOrZeroInteger
22             Str
23 26     26   129 );
  26         45  
24              
25 26     26   322585 use Moose 2.1200;
  26         808  
  26         225  
26 26     26   157477 use MooseX::SemiAffordanceAccessor 0.03;
  26         797  
  26         197  
27 26     26   87656 use MooseX::StrictConstructor 0.13;
  26         656  
  26         186  
28              
29             with 'Fey::Role::ColumnLike';
30              
31             with 'Fey::Role::MakesAliasObjects' => {
32             self_param => 'column',
33             alias_class => 'Fey::Column::Alias',
34             };
35              
36             has 'id' => (
37             is => 'ro',
38             lazy_build => 1,
39             init_arg => undef,
40             clearer => '_clear_id',
41             );
42              
43             has 'name' => (
44             is => 'ro',
45             isa => Str,
46             required => 1,
47             );
48              
49             has 'generic_type' => (
50             is => 'ro',
51             isa => GenericTypeName,
52             lazy_build => 1,
53             );
54              
55             has type => (
56             is => 'ro',
57             isa => Str,
58             required => 1,
59             );
60              
61             has length => (
62             is => 'ro',
63             isa => PosInteger,
64             required => 0
65             );
66              
67             # How to say that precision requires length as well?
68             has precision => (
69             is => 'ro',
70             isa => PosOrZeroInteger,
71             required => 0
72             );
73              
74             has is_auto_increment => (
75             is => 'ro',
76             isa => Bool,
77             default => 0,
78             );
79              
80             has is_nullable => (
81             is => 'ro',
82             isa => Bool,
83             default => 0,
84             );
85              
86             has default => (
87             is => 'ro',
88             isa => DefaultValue,
89             coerce => 1,
90             );
91              
92             has 'table' => (
93             is => 'rw',
94             does => 'Fey::Role::TableLike',
95             weak_ref => 1,
96             predicate => 'has_table',
97             writer => '_set_table',
98             clearer => '_clear_table',
99             );
100              
101             after '_set_table', '_clear_table' => sub { $_[0]->_clear_id() };
102              
103             with 'Fey::Role::Named';
104              
105             {
106             my @TypesRe = (
107             [ text => qr/(?:text|char(?:acter)?)\b/xism ],
108             [ blob => qr/blob\b|bytea\b/xism ],
109              
110             # The year type comes from MySQL
111             [ integer => qr/(?:int(?:eger)?\d*|year)\b/xism ],
112             [ float => qr/(?:float\d*|decimal|real|double|money|numeric)\b/xism ],
113              
114             # MySQL's timestamp is not always a datetime, it depends on
115             # the length of the column, but this is the best _guess_.
116             [ datetime => qr/datetime\b|^timestamp/xism ],
117             [ date => qr/date\b/xism ],
118             [ time => qr/^time|time\b/xism ],
119             [ boolean => qr/\bbool/xism ],
120             );
121              
122             sub _build_generic_type {
123 62     62   163 my $self = shift;
124 62         1479 my $type = $self->type();
125              
126 62         97 for my $p (@TypesRe) {
127 259 100       1082 return $p->[0] if $type =~ /$p->[1]/;
128             }
129              
130 9         46 return 'other';
131             }
132             }
133              
134             sub _clone {
135 10     10   900 my $self = shift;
136              
137 10         18 my %clone = %{$self};
  10         78  
138              
139 10         49 return bless \%clone, ref $self;
140             }
141              
142 1     1 1 5 sub is_alias { return 0 }
143              
144             sub sql {
145 211     211 1 295 my $self = shift;
146 211         238 my $dbh = shift;
147              
148 211         744 return $dbh->quote_identifier(
149             undef,
150             $self->_containing_table_name_or_alias(),
151             $self->name(),
152             );
153             }
154              
155 27     27 1 108 sub sql_with_alias { goto &sql }
156              
157 170     170 1 611 sub sql_or_alias { goto &sql }
158              
159             sub _build_id {
160 3     3   5 my $self = shift;
161              
162 3         61 my $table = $self->table();
163              
164 3 100       21 object_state_error
165             'The id attribute cannot be determined for a column object which has no table.'
166             unless $table;
167              
168 1         20 return $table->id() . q{.} . $self->name();
169             }
170              
171             __PACKAGE__->meta()->make_immutable();
172              
173             1;
174              
175             # ABSTRACT: Represents a column
176              
177             __END__
178              
179             =pod
180              
181             =head1 NAME
182              
183             Fey::Column - Represents a column
184              
185             =head1 VERSION
186              
187             version 0.43
188              
189             =head1 SYNOPSIS
190              
191             my $column = Fey::Column->new( name => 'user_id',
192             type => 'integer',
193             is_auto_increment => 1,
194             );
195              
196             =head1 DESCRIPTION
197              
198             This class represents a column in a table.
199              
200             =head1 METHODS
201              
202             This class provides the following methods:
203              
204             =head2 Fey::Column->new()
205              
206             This method constructs a new C<Fey::Column> object. It takes the
207             following parameters:
208              
209             =over 4
210              
211             =item * name - required
212              
213             The name of the column.
214              
215             =item * type - required
216              
217             The type of the column. This should be a string. Do not include
218             modifiers like length or precision.
219              
220             =item * generic_type - optional
221              
222             This should be one of the following types:
223              
224             =over 8
225              
226             =item * text
227              
228             =item * blob
229              
230             =item * integer
231              
232             =item * float
233              
234             =item * date
235              
236             =item * datetime
237              
238             =item * time
239              
240             =item * boolean
241              
242             =item * other
243              
244             =back
245              
246             This indicate a generic type for the column, which is intended to
247             allow for a common description of column types across different DBMS
248             platforms.
249              
250             If this parameter is not specified, then the constructor code will
251             attempt to determine a reasonable value, defaulting to "other" if
252             necessary.
253              
254             =item * length - optional
255              
256             The length of the column. This must be a positive integer.
257              
258             =item * precision - optional
259              
260             The precision of the column, for float-type columns. This must be an
261             integer >= 0.
262              
263             =item * is_auto_increment - defaults to 0
264              
265             This indicates whether or not the column is auto-incremented.
266              
267             =item * is_nullable - defaults to 0
268              
269             A boolean indicating whether the column is nullable.
270              
271             =item * default - optional
272              
273             This must be either a scalar (including undef) or a C<Fey::Literal>
274             object. If a scalar is provided, it is turned into a C<Fey::Literal>
275             object via C<< Fey::Literal->new_from_scalar() >>.
276              
277             =back
278              
279             =head2 $column->name()
280              
281             =head2 $column->type()
282              
283             =head2 $column->generic_type()
284              
285             =head2 $column->length()
286              
287             =head2 $column->precision()
288              
289             =head2 $column->is_auto_increment()
290              
291             =head2 $column->is_nullable()
292              
293             =head2 $column->default()
294              
295             Returns the specified attribute.
296              
297             =head2 $column->table()
298              
299             Returns the C<Fey::Table> object to which the column belongs, if any.
300              
301             =head2 $column->alias(%p)
302              
303             =head2 $column->alias($alias_name)
304              
305             This method returns a new C<Fey::Column::Alias> object based on the
306             column. Any parameters passed to this method will be passed through to
307             C<< Fey::Column::Alias->new() >>.
308              
309             As a shortcut, if you pass a single argument to this method, it will
310             be passed as the "alias_name" parameter to C<<
311             Fey::Table::Column->new() >>.
312              
313             =head2 $column->is_alias()
314              
315             Always returns false.
316              
317             =head2 $column->sql()
318              
319             =head2 $column->sql_with_alias()
320              
321             =head2 $column->sql_or_alias()
322              
323             Returns the appropriate SQL snippet for the column.
324              
325             =head2 $column->id()
326              
327             Returns a unique identifier for the column.
328              
329             =head1 ROLES
330              
331             This class does the L<Fey::Role::ColumnLike>, L<Fey::Role::MakesAliasObjects>,
332             and L<Fey::Role::Named> roles.
333              
334             =head1 BUGS
335              
336             See L<Fey> for details on how to report bugs.
337              
338             =head1 AUTHOR
339              
340             Dave Rolsky <autarch@urth.org>
341              
342             =head1 COPYRIGHT AND LICENSE
343              
344             This software is Copyright (c) 2011 - 2015 by Dave Rolsky.
345              
346             This is free software, licensed under:
347              
348             The Artistic License 2.0 (GPL Compatible)
349              
350             =cut