File Coverage

blib/lib/Fey/Column.pm
Criterion Covered Total %
statement 14 16 87.5
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 20 22 90.9


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