Playing with constants.
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Schema / Field.pm
index 00b03cc..c31e075 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Schema::Field;
 
 # ----------------------------------------------------------------------
-# $Id: Field.pm,v 1.1 2003-05-01 04:25:00 kycl4rk Exp $
+# $Id: Field.pm,v 1.3 2003-05-05 04:32:39 kycl4rk Exp $
 # ----------------------------------------------------------------------
 # Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>
 #
@@ -44,6 +44,7 @@ C<SQL::Translator::Schema::Field> is the field object.
 
 use strict;
 use Class::Base;
+use SQL::Translator::Schema::Constants;
 
 use base 'Class::Base';
 use vars qw($VERSION $TABLE_COUNT $VIEW_COUNT);
@@ -64,7 +65,11 @@ Object constructor.
 =cut
 
     my ( $self, $config ) = @_;
-    $self->params( $config, qw[ name data_type size is_primary_key ] );
+
+    for my $arg ( qw[ name data_type size is_primary_key nullable table ] ) {
+        next unless defined $config->{ $arg };
+        $self->$arg( $config->{ $arg } ) or return;
+    }
     return $self;
 }
 
@@ -75,7 +80,7 @@ sub data_type {
 
 =head2 data_type
 
-Get or set the field's data_type.
+Get or set the field's data type.
 
   my $data_type = $field->data_type('integer');
 
@@ -87,13 +92,68 @@ Get or set the field's data_type.
 }
 
 # ----------------------------------------------------------------------
+sub default_value {
+
+=pod
+
+=head2 default_value
+
+Get or set the field's default value.  Will return undef if not defined
+and could return the empty string (it's a valid default value), so don't 
+assume an error like other methods.
+
+  my $default = $field->default_value('foo');
+
+=cut
+
+    my ( $self, $arg ) = @_;
+    $self->{'default_value'} = $arg if defined $arg;
+    return $self->{'default_value'};
+}
+
+# ----------------------------------------------------------------------
+sub is_auto_increment {
+
+=pod
+
+=head2 is_auto_increment
+
+Get or set the field's C<is_auto_increment> attribute.
+
+  my $is_pk = $field->is_auto_increment(1);
+
+=cut
+
+    my ( $self, $arg ) = @_;
+
+    if ( defined $arg ) {
+        $self->{'is_auto_increment'} = $arg ? 1 : 0;
+    }
+
+    unless ( defined $self->{'is_auto_increment'} ) {
+        if ( my $table = $self->table ) {
+            if ( my $schema = $table->schema ) {
+                if ( 
+                    $schema->database eq 'PostgreSQL' &&
+                    $self->data_type eq 'serial'
+                ) {
+                    $self->{'is_auto_increment'} = 1;
+                }
+            }
+        }
+    }
+
+    return $self->{'is_auto_increment'} || 0;
+}
+
+# ----------------------------------------------------------------------
 sub is_primary_key {
 
 =pod
 
 =head2 is_primary_key
 
-Get or set the field's is_primary_key attribute.
+Get or set the field's C<is_primary_key> attribute.
 
   my $is_pk = $field->is_primary_key(1);
 
@@ -105,6 +165,18 @@ Get or set the field's is_primary_key attribute.
         $self->{'is_primary_key'} = $arg ? 1 : 0;
     }
 
+    unless ( defined $self->{'is_primary_key'} ) {
+        if ( my $table = $self->table ) {
+            if ( my $pk = $table->primary_key ) {
+                my %fields = map { $_, 1 } $pk->fields;
+                $self->{'is_primary_key'} = $fields{ $self->name } || 0;
+            }
+            else {
+                $self->{'is_primary_key'} = 0;
+            }
+        }
+    }
+
     return $self->{'is_primary_key'} || 0;
 }
 
@@ -122,30 +194,80 @@ Get or set the field's name.
 =cut
 
     my $self = shift;
-    $self->{'name'} = shift if @_;
+
+    if ( my $arg = shift ) {
+        if ( my $table = $self->table ) {
+            return $self->error( qq[Can't use field name "$arg": table exists] )
+                if $table->get_field( $arg );
+        }
+
+        $self->{'name'} = $arg;
+    }
+
     return $self->{'name'} || '';
 }
 
 # ----------------------------------------------------------------------
-sub size {
+sub nullable {
 
 =pod
 
-=head2 size
+=head2 nullable
 
-Get or set the field's size.
+Get or set the whether the field can be null.  If not defined, then 
+returns "1" (assumes the field can be null).  The argument is evaluated
+by Perl for True or False, so the following are eqivalent:
 
-  my $size = $field->size('25');
+  $nullable = $field->nullable(0);
+  $nullable = $field->nullable('');
+  $nullable = $field->nullable('0');
 
 =cut
 
     my ( $self, $arg ) = @_;
 
-    if ( $arg =~ m/^\d+(?:\.\d+)?$/ ) {
-        $self->{'size'} = $arg;
+    if ( defined $arg ) {
+        $self->{'nullable'} = $arg ? 1 : 0;
     }
 
-    return $self->{'size'} || 0;
+    return defined $self->{'nullable'} ? $self->{'nullable'} : 1;
+}
+
+# ----------------------------------------------------------------------
+sub size {
+
+=pod
+
+=head2 size
+
+Get or set the field's size.  Accepts a string, array or arrayref of
+numbers and returns a string.
+
+  $field->size( 30 );
+  $field->size( [ 255 ] );
+  $size = $field->size( 10, 2 );
+  print $size; # prints "10,2"
+
+  $size = $field->size( '10, 2' );
+  print $size; # prints "10,2"
+
+=cut
+
+    my $self    = shift;
+    my $numbers = UNIVERSAL::isa( $_[0], 'ARRAY' ) 
+        ? shift : [ map { split /,/ } @_ ];
+
+    if ( @$numbers ) {
+        my @new;
+        for my $num ( @$numbers ) {
+            if ( defined $num && $num =~ m/^\d+(?:\.\d+)?$/ ) {
+                push @new, $num;
+            }
+        }
+        $self->{'size'} = \@new if @new; # only set if all OK
+    }
+
+    return join( ',', @{ $self->{'size'} || [0] } );
 }
 
 # ----------------------------------------------------------------------
@@ -162,7 +284,33 @@ Determine whether the field is valid or not.
 =cut
 
     my $self = shift;
-    return 1 if $self->name && $self->data_type;
+    return $self->error('No name')         unless $self->name;
+    return $self->error('No data type')    unless $self->data_type;
+    return $self->error('No table object') unless $self->table;
+    return 1;
+}
+
+# ----------------------------------------------------------------------
+sub table {
+
+=pod
+
+=head2 table
+
+Get or set the field's table object.
+
+  my $table = $field->table;
+
+=cut
+
+    my $self = shift;
+    if ( my $arg = shift ) {
+        return $self->error('Not a table object') unless
+            UNIVERSAL::isa( $arg, 'SQL::Translator::Schema::Table' );
+        $self->{'table'} = $arg;
+    }
+
+    return $self->{'table'};
 }
 
 1;