Changed constant to a hash to avoid silly Perl errors about it being
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Schema / Field.pm
CommitLineData
3c5de62a 1package SQL::Translator::Schema::Field;
2
3# ----------------------------------------------------------------------
9966eebc 4# $Id: Field.pm,v 1.6 2003-06-06 00:09:25 kycl4rk Exp $
3c5de62a 5# ----------------------------------------------------------------------
6# Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20# 02111-1307 USA
21# -------------------------------------------------------------------
22
23=pod
24
25=head1 NAME
26
27SQL::Translator::Schema::Field - SQL::Translator field object
28
29=head1 SYNOPSIS
30
31 use SQL::Translator::Schema::Field;
32 my $field = SQL::Translator::Schema::Field->new(
33 name => 'foo',
34 sql => 'select * from foo',
35 );
36
37=head1 DESCRIPTION
38
39C<SQL::Translator::Schema::Field> is the field object.
40
41=head1 METHODS
42
43=cut
44
45use strict;
46use Class::Base;
43b9dc7a 47use SQL::Translator::Schema::Constants;
ec2ab48d 48use SQL::Translator::Utils 'parse_list_arg';
3c5de62a 49
50use base 'Class::Base';
51use vars qw($VERSION $TABLE_COUNT $VIEW_COUNT);
52
53$VERSION = 1.00;
54
55# ----------------------------------------------------------------------
56sub init {
57
58=pod
59
60=head2 new
61
62Object constructor.
63
64 my $schema = SQL::Translator::Schema::Field->new;
65
66=cut
67
68 my ( $self, $config ) = @_;
43b9dc7a 69
ec2ab48d 70 for my $arg (
71 qw[
72 table name data_type size is_primary_key is_nullable
9966eebc 73 is_auto_increment default_value
ec2ab48d 74 ]
75 ) {
43b9dc7a 76 next unless defined $config->{ $arg };
c941e9bf 77 defined $self->$arg( $config->{ $arg } ) or return;
43b9dc7a 78 }
c941e9bf 79
3c5de62a 80 return $self;
81}
82
83# ----------------------------------------------------------------------
84sub data_type {
85
86=pod
87
88=head2 data_type
89
43b9dc7a 90Get or set the field's data type.
3c5de62a 91
92 my $data_type = $field->data_type('integer');
93
94=cut
95
96 my $self = shift;
97 $self->{'data_type'} = shift if @_;
98 return $self->{'data_type'} || '';
99}
100
101# ----------------------------------------------------------------------
43b9dc7a 102sub default_value {
103
104=pod
105
106=head2 default_value
107
108Get or set the field's default value. Will return undef if not defined
109and could return the empty string (it's a valid default value), so don't
110assume an error like other methods.
111
112 my $default = $field->default_value('foo');
113
114=cut
115
116 my ( $self, $arg ) = @_;
117 $self->{'default_value'} = $arg if defined $arg;
118 return $self->{'default_value'};
119}
120
121# ----------------------------------------------------------------------
9966eebc 122sub extra {
123
124=pod
125
126=head2 extra
127
128Get or set the field's "extra" attibutes (e.g., "ZEROFILL" for MySQL).
129Accepts a hash(ref) of name/value pairs to store; returns a hash.
130
131 $field->extra( qualifier => 'ZEROFILL' );
132 my %extra = $field->extra;
133
134=cut
135
136 my $self = shift;
137 my $args = ref $_[0] eq 'HASH' ? shift : { @_ };
138
139 while ( my ( $key, $value ) = each %$args ) {
140 $self->{'extra'}{ $key } = $value;
141 }
142
143 return %{ $self->{'extra'} || {} };
144}
145
146# ----------------------------------------------------------------------
147sub foreign_key_reference {
148
149=pod
150
151=head2 foreign_key_reference
152
153Get or set the field's foreign key reference;
154
155 my $constraint = $field->foreign_key_reference( $constraint );
156
157=cut
158
159 my $self = shift;
160
161 if ( my $arg = shift ) {
162 my $class = 'SQL::Translator::Schema::Constraint';
163 if ( UNIVERSAL::isa( $arg, $class ) ) {
164 return $self->error(
165 'Foreign key reference for ', $self->name, 'already defined'
166 ) if $self->{'foreign_key_reference'};
167
168 $self->{'foreign_key_reference'} = $arg;
169 }
170 else {
171 return $self->error(
172 "Argument to foreign_key_reference is not an $class object"
173 );
174 }
175 }
176
177 return $self->{'foreign_key_reference'};
178}
179
180# ----------------------------------------------------------------------
43b9dc7a 181sub is_auto_increment {
182
183=pod
184
185=head2 is_auto_increment
186
187Get or set the field's C<is_auto_increment> attribute.
188
189 my $is_pk = $field->is_auto_increment(1);
190
191=cut
192
193 my ( $self, $arg ) = @_;
194
195 if ( defined $arg ) {
196 $self->{'is_auto_increment'} = $arg ? 1 : 0;
197 }
198
199 unless ( defined $self->{'is_auto_increment'} ) {
200 if ( my $table = $self->table ) {
201 if ( my $schema = $table->schema ) {
202 if (
203 $schema->database eq 'PostgreSQL' &&
204 $self->data_type eq 'serial'
205 ) {
206 $self->{'is_auto_increment'} = 1;
207 }
208 }
209 }
210 }
211
212 return $self->{'is_auto_increment'} || 0;
213}
214
215# ----------------------------------------------------------------------
9966eebc 216sub is_foreign_key {
217
218=pod
219
220=head2 is_foreign_key
221
222Returns whether or not the field is a foreign key.
223
224 my $is_fk = $field->is_foreign_key;
225
226=cut
227
228 my ( $self, $arg ) = @_;
229
230 unless ( defined $self->{'is_foreign_key'} ) {
231 if ( my $table = $self->table ) {
232 for my $c ( $table->get_constraints ) {
233 if ( $c->type eq FOREIGN_KEY ) {
234 my %fields = map { $_, 1 } $c->fields;
235 if ( $fields{ $self->name } ) {
236 $self->{'is_foreign_key'} = 1;
237 $self->foreign_key_reference( $c );
238 last;
239 }
240 }
241 }
242 }
243 }
244
245 return $self->{'is_foreign_key'} || 0;
246}
247
248
249# ----------------------------------------------------------------------
ec2ab48d 250sub is_nullable {
251
252=pod
253
254=head2 is_nullable
255
256Get or set the whether the field can be null. If not defined, then
257returns "1" (assumes the field can be null). The argument is evaluated
258by Perl for True or False, so the following are eqivalent:
259
260 $is_nullable = $field->is_nullable(0);
261 $is_nullable = $field->is_nullable('');
262 $is_nullable = $field->is_nullable('0');
263
264While this is technically a field constraint, it's probably easier to
265represent this as an attribute of the field. In order keep things
266consistent, any other constraint on the field (unique, primary, and
267foreign keys; checks) are represented as table constraints.
268
269=cut
270
271 my ( $self, $arg ) = @_;
272
273 if ( defined $arg ) {
274 $self->{'is_nullable'} = $arg ? 1 : 0;
275 }
276
277 return defined $self->{'is_nullable'} ? $self->{'is_nullable'} : 1;
278}
279
280# ----------------------------------------------------------------------
3c5de62a 281sub is_primary_key {
282
283=pod
284
285=head2 is_primary_key
286
ec2ab48d 287Get or set the field's C<is_primary_key> attribute. Does not create
288a table constraint (should it?).
3c5de62a 289
290 my $is_pk = $field->is_primary_key(1);
291
292=cut
293
294 my ( $self, $arg ) = @_;
295
296 if ( defined $arg ) {
297 $self->{'is_primary_key'} = $arg ? 1 : 0;
298 }
299
43b9dc7a 300 unless ( defined $self->{'is_primary_key'} ) {
301 if ( my $table = $self->table ) {
302 if ( my $pk = $table->primary_key ) {
303 my %fields = map { $_, 1 } $pk->fields;
304 $self->{'is_primary_key'} = $fields{ $self->name } || 0;
305 }
306 else {
307 $self->{'is_primary_key'} = 0;
308 }
309 }
310 }
311
3c5de62a 312 return $self->{'is_primary_key'} || 0;
313}
314
315# ----------------------------------------------------------------------
ec2ab48d 316sub is_valid {
317
318=pod
319
320=head2 is_valid
321
322Determine whether the field is valid or not.
323
324 my $ok = $field->is_valid;
325
326=cut
327
328 my $self = shift;
329 return $self->error('No name') unless $self->name;
330 return $self->error('No data type') unless $self->data_type;
331 return $self->error('No table object') unless $self->table;
332 return 1;
333}
334
335# ----------------------------------------------------------------------
3c5de62a 336sub name {
337
338=pod
339
340=head2 name
341
342Get or set the field's name.
343
344 my $name = $field->name('foo');
345
346=cut
347
348 my $self = shift;
43b9dc7a 349
350 if ( my $arg = shift ) {
351 if ( my $table = $self->table ) {
352 return $self->error( qq[Can't use field name "$arg": table exists] )
353 if $table->get_field( $arg );
354 }
355
356 $self->{'name'} = $arg;
357 }
358
3c5de62a 359 return $self->{'name'} || '';
360}
361
362# ----------------------------------------------------------------------
ec2ab48d 363sub order {
3c5de62a 364
365=pod
366
ec2ab48d 367=head2 order
3c5de62a 368
ec2ab48d 369Get or set the field's order.
3c5de62a 370
ec2ab48d 371 my $order = $field->order(3);
3c5de62a 372
373=cut
374
375 my ( $self, $arg ) = @_;
376
ec2ab48d 377 if ( defined $arg && $arg =~ /^\d+$/ ) {
378 $self->{'order'} = $arg;
3c5de62a 379 }
380
ec2ab48d 381 return $self->{'order'} || 0;
43b9dc7a 382}
383
384# ----------------------------------------------------------------------
385sub size {
386
387=pod
388
389=head2 size
390
391Get or set the field's size. Accepts a string, array or arrayref of
392numbers and returns a string.
393
394 $field->size( 30 );
395 $field->size( [ 255 ] );
396 $size = $field->size( 10, 2 );
397 print $size; # prints "10,2"
398
399 $size = $field->size( '10, 2' );
400 print $size; # prints "10,2"
401
402=cut
403
404 my $self = shift;
ec2ab48d 405 my $numbers = parse_list_arg( @_ );
43b9dc7a 406
407 if ( @$numbers ) {
408 my @new;
409 for my $num ( @$numbers ) {
410 if ( defined $num && $num =~ m/^\d+(?:\.\d+)?$/ ) {
411 push @new, $num;
412 }
413 }
414 $self->{'size'} = \@new if @new; # only set if all OK
415 }
416
ec2ab48d 417 return wantarray
418 ? @{ $self->{'size'} }
419 : join( ',', @{ $self->{'size'} || [0] } )
420 ;
43b9dc7a 421}
422
423# ----------------------------------------------------------------------
424sub table {
425
426=pod
427
428=head2 table
429
430Get or set the field's table object.
431
432 my $table = $field->table;
433
434=cut
435
436 my $self = shift;
437 if ( my $arg = shift ) {
438 return $self->error('Not a table object') unless
439 UNIVERSAL::isa( $arg, 'SQL::Translator::Schema::Table' );
440 $self->{'table'} = $arg;
441 }
442
443 return $self->{'table'};
3c5de62a 444}
445
ec2ab48d 446# ----------------------------------------------------------------------
447sub DESTROY {
9966eebc 448#
449# Destroy cyclical references.
450#
ec2ab48d 451 my $self = shift;
9966eebc 452 undef $self->{'table'};
453 undef $self->{'foreign_key_reference'};
ec2ab48d 454}
455
3c5de62a 4561;
457
458# ----------------------------------------------------------------------
459
460=pod
461
462=head1 AUTHOR
463
464Ken Y. Clark E<lt>kclark@cpan.orgE<gt>
465
466=cut