1 package SQL::Translator::Schema::Field;
7 SQL::Translator::Schema::Field - SQL::Translator field object
11 use SQL::Translator::Schema::Field;
12 my $field = SQL::Translator::Schema::Field->new(
19 C<SQL::Translator::Schema::Field> is the field object.
26 use SQL::Translator::Schema::Constants;
27 use SQL::Translator::Utils 'parse_list_arg';
29 use base 'SQL::Translator::Schema::Object';
31 use vars qw($VERSION $TABLE_COUNT $VIEW_COUNT);
35 # Stringify to our name, being careful not to pass any args through so we don't
36 # accidentally set it to undef. We also have to tweak bool so the object is
37 # still true when it doesn't have a name (which shouldn't happen!).
39 '""' => sub { shift->name },
40 'bool' => sub { $_[0]->name || $_[0] },
44 use DBI qw(:sql_types);
46 # Mapping from string to sql contstant
48 integer => SQL_INTEGER,
51 smallint => SQL_SMALLINT,
52 bigint => 9999, # DBI doesn't export a constatn for this. Le suck
56 decimal => SQL_DECIMAL,
57 numeric => SQL_NUMERIC,
63 datetime => SQL_DATETIME,
64 timestamp => SQL_TIMESTAMP,
68 varchar => SQL_VARCHAR,
70 varbinary => SQL_VARBINARY,
73 text => SQL_LONGVARCHAR
76 # ----------------------------------------------------------------------
78 __PACKAGE__->_attributes( qw/
79 table name data_type size is_primary_key is_nullable
80 is_auto_increment default_value comments is_foreign_key
81 is_unique order sql_data_type
90 my $field = SQL::Translator::Schema::Field->new(
97 # ----------------------------------------------------------------------
104 Get or set the comments on a field. May be called several times to
105 set and it will accumulate the comments. Called in an array context,
106 returns each comment individually; called in a scalar context, returns
107 all the comments joined on newlines.
109 $field->comments('foo');
110 $field->comments('bar');
111 print join( ', ', $field->comments ); # prints "foo, bar"
118 $arg = $arg->[0] if ref $arg;
119 push @{ $self->{'comments'} }, $arg if $arg;
122 if ( @{ $self->{'comments'} || [] } ) {
124 ? @{ $self->{'comments'} || [] }
125 : join( "\n", @{ $self->{'comments'} || [] } );
128 return wantarray ? () : '';
133 # ----------------------------------------------------------------------
140 Get or set the field's data type.
142 my $data_type = $field->data_type('integer');
148 $self->{'data_type'} = $_[0];
149 $self->{'sql_data_type'} = $type_mapping{lc $_[0]} || SQL_UNKNOWN_TYPE unless exists $self->{sql_data_type};
151 return $self->{'data_type'} || '';
158 Constant from DBI package representing this data type. See L<DBI/DBI Constants>
164 $self->{sql_data_type} = shift if @_;
165 return $self->{sql_data_type} || 0;
169 # ----------------------------------------------------------------------
176 Get or set the field's default value. Will return undef if not defined
177 and could return the empty string (it's a valid default value), so don't
178 assume an error like other methods.
180 my $default = $field->default_value('foo');
185 $self->{'default_value'} = shift if @_;
186 return $self->{'default_value'};
189 # ----------------------------------------------------------------------
194 Get or set the field's "extra" attibutes (e.g., "ZEROFILL" for MySQL).
195 Accepts a hash(ref) of name/value pairs to store; returns a hash.
197 $field->extra( qualifier => 'ZEROFILL' );
198 my %extra = $field->extra;
203 # ----------------------------------------------------------------------
204 sub foreign_key_reference {
208 =head2 foreign_key_reference
210 Get or set the field's foreign key reference;
212 my $constraint = $field->foreign_key_reference( $constraint );
218 if ( my $arg = shift ) {
219 my $class = 'SQL::Translator::Schema::Constraint';
220 if ( UNIVERSAL::isa( $arg, $class ) ) {
222 'Foreign key reference for ', $self->name, 'already defined'
223 ) if $self->{'foreign_key_reference'};
225 $self->{'foreign_key_reference'} = $arg;
229 "Argument to foreign_key_reference is not an $class object"
234 return $self->{'foreign_key_reference'};
237 # ----------------------------------------------------------------------
238 sub is_auto_increment {
242 =head2 is_auto_increment
244 Get or set the field's C<is_auto_increment> attribute.
246 my $is_auto = $field->is_auto_increment(1);
250 my ( $self, $arg ) = @_;
252 if ( defined $arg ) {
253 $self->{'is_auto_increment'} = $arg ? 1 : 0;
256 unless ( defined $self->{'is_auto_increment'} ) {
257 if ( my $table = $self->table ) {
258 if ( my $schema = $table->schema ) {
260 $schema->database eq 'PostgreSQL' &&
261 $self->data_type eq 'serial'
263 $self->{'is_auto_increment'} = 1;
269 return $self->{'is_auto_increment'} || 0;
272 # ----------------------------------------------------------------------
277 =head2 is_foreign_key
279 Returns whether or not the field is a foreign key.
281 my $is_fk = $field->is_foreign_key;
285 my ( $self, $arg ) = @_;
287 unless ( defined $self->{'is_foreign_key'} ) {
288 if ( my $table = $self->table ) {
289 for my $c ( $table->get_constraints ) {
290 if ( $c->type eq FOREIGN_KEY ) {
291 my %fields = map { $_, 1 } $c->fields;
292 if ( $fields{ $self->name } ) {
293 $self->{'is_foreign_key'} = 1;
294 $self->foreign_key_reference( $c );
302 return $self->{'is_foreign_key'} || 0;
305 # ----------------------------------------------------------------------
312 Get or set whether the field can be null. If not defined, then
313 returns "1" (assumes the field can be null). The argument is evaluated
314 by Perl for True or False, so the following are eqivalent:
316 $is_nullable = $field->is_nullable(0);
317 $is_nullable = $field->is_nullable('');
318 $is_nullable = $field->is_nullable('0');
320 While this is technically a field constraint, it's probably easier to
321 represent this as an attribute of the field. In order keep things
322 consistent, any other constraint on the field (unique, primary, and
323 foreign keys; checks) are represented as table constraints.
327 my ( $self, $arg ) = @_;
329 if ( defined $arg ) {
330 $self->{'is_nullable'} = $arg ? 1 : 0;
334 defined $self->{'is_nullable'} &&
335 $self->{'is_nullable'} == 1 &&
336 $self->is_primary_key
338 $self->{'is_nullable'} = 0;
341 return defined $self->{'is_nullable'} ? $self->{'is_nullable'} : 1;
344 # ----------------------------------------------------------------------
349 =head2 is_primary_key
351 Get or set the field's C<is_primary_key> attribute. Does not create
352 a table constraint (should it?).
354 my $is_pk = $field->is_primary_key(1);
358 my ( $self, $arg ) = @_;
360 if ( defined $arg ) {
361 $self->{'is_primary_key'} = $arg ? 1 : 0;
364 unless ( defined $self->{'is_primary_key'} ) {
365 if ( my $table = $self->table ) {
366 if ( my $pk = $table->primary_key ) {
367 my %fields = map { $_, 1 } $pk->fields;
368 $self->{'is_primary_key'} = $fields{ $self->name } || 0;
371 $self->{'is_primary_key'} = 0;
376 return $self->{'is_primary_key'} || 0;
379 # ----------------------------------------------------------------------
386 Determine whether the field has a UNIQUE constraint or not.
388 my $is_unique = $field->is_unique;
394 unless ( defined $self->{'is_unique'} ) {
395 if ( my $table = $self->table ) {
396 for my $c ( $table->get_constraints ) {
397 if ( $c->type eq UNIQUE ) {
398 my %fields = map { $_, 1 } $c->fields;
399 if ( $fields{ $self->name } ) {
400 $self->{'is_unique'} = 1;
408 return $self->{'is_unique'} || 0;
411 # ----------------------------------------------------------------------
418 Determine whether the field is valid or not.
420 my $ok = $field->is_valid;
425 return $self->error('No name') unless $self->name;
426 return $self->error('No data type') unless $self->data_type;
427 return $self->error('No table object') unless $self->table;
431 # ----------------------------------------------------------------------
438 Get or set the field's name.
440 my $name = $field->name('foo');
442 The field object will also stringify to its name.
444 my $setter_name = "set_$field";
446 Errors ("No field name") if you try to set a blank name.
453 my $arg = shift || return $self->error( "No field name" );
454 if ( my $table = $self->table ) {
455 return $self->error( qq[Can't use field name "$arg": field exists] )
456 if $table->get_field( $arg );
459 $self->{'name'} = $arg;
462 return $self->{'name'} || '';
469 Read only method to return the fields name with its table name pre-pended.
475 return $self->table.".".$self->name;
478 # ----------------------------------------------------------------------
485 Get or set the field's order.
487 my $order = $field->order(3);
491 my ( $self, $arg ) = @_;
493 if ( defined $arg && $arg =~ /^\d+$/ ) {
494 $self->{'order'} = $arg;
497 return $self->{'order'} || 0;
500 # ----------------------------------------------------------------------
505 Shortcut to get the fields schema ($field->table->schema) or undef if it
508 my $schema = $field->schema;
513 if ( my $table = $self->table ) { return $table->schema || undef; }
517 # ----------------------------------------------------------------------
524 Get or set the field's size. Accepts a string, array or arrayref of
525 numbers and returns a string.
528 $field->size( [ 255 ] );
529 $size = $field->size( 10, 2 );
530 print $size; # prints "10,2"
532 $size = $field->size( '10, 2' );
533 print $size; # prints "10,2"
538 my $numbers = parse_list_arg( @_ );
542 for my $num ( @$numbers ) {
543 if ( defined $num && $num =~ m/^\d+(?:\.\d+)?$/ ) {
547 $self->{'size'} = \@new if @new; # only set if all OK
551 ? @{ $self->{'size'} || [0] }
552 : join( ',', @{ $self->{'size'} || [0] } )
556 # ----------------------------------------------------------------------
563 Get or set the field's table object. As the table object stringifies this can
564 also be used to get the table name.
566 my $table = $field->table;
567 print "Table name: $table";
572 if ( my $arg = shift ) {
573 return $self->error('Not a table object') unless
574 UNIVERSAL::isa( $arg, 'SQL::Translator::Schema::Table' );
575 $self->{'table'} = $arg;
578 return $self->{'table'};
585 Returns the field exactly as the parser found it
593 $self->{parsed_field} = $value;
594 return $value || $self;
596 return $self->{parsed_field} || $self;
599 # ----------------------------------------------------------------------
606 Determines if this field is the same as another
608 my $isIdentical = $field1->equals( $field2 );
614 my $case_insensitive = shift;
616 return 0 unless $self->SUPER::equals($other);
617 return 0 unless $case_insensitive ? uc($self->name) eq uc($other->name) : $self->name eq $other->name;
619 # Comparing types: use sql_data_type if both are not 0. Else use string data_type
620 if ($self->sql_data_type && $other->sql_data_type) {
621 return 0 unless $self->sql_data_type == $other->sql_data_type
623 return 0 unless lc($self->data_type) eq lc($other->data_type)
626 return 0 unless $self->size eq $other->size;
629 my $lhs = $self->default_value;
630 $lhs = \'NULL' unless defined $lhs;
631 my $lhs_is_ref = ! ! ref $lhs;
633 my $rhs = $other->default_value;
634 $rhs = \'NULL' unless defined $rhs;
635 my $rhs_is_ref = ! ! ref $rhs;
637 # If only one is a ref, fail. -- rjbs, 2008-12-02
638 return 0 if $lhs_is_ref xor $rhs_is_ref;
640 my $effective_lhs = $lhs_is_ref ? $$lhs : $lhs;
641 my $effective_rhs = $rhs_is_ref ? $$rhs : $rhs;
643 return 0 if $effective_lhs ne $effective_rhs;
646 return 0 unless $self->is_nullable eq $other->is_nullable;
647 # return 0 unless $self->is_unique eq $other->is_unique;
648 return 0 unless $self->is_primary_key eq $other->is_primary_key;
649 # return 0 unless $self->is_foreign_key eq $other->is_foreign_key;
650 return 0 unless $self->is_auto_increment eq $other->is_auto_increment;
651 # return 0 unless $self->comments eq $other->comments;
652 return 0 unless $self->_compare_objects(scalar $self->extra, scalar $other->extra);
656 # ----------------------------------------------------------------------
659 # Destroy cyclical references.
662 undef $self->{'table'};
663 undef $self->{'foreign_key_reference'};
668 # ----------------------------------------------------------------------
674 Ken Youens-Clark E<lt>kclark@cpan.orgE<gt>.