fix up PrimaryKey and ForeignKey parsing
[dbsrgits/SQL-Translator-2.0-ish.git] / lib / SQL / Translator / Parser / DBI.pm
index a4f43b3..bad630c 100644 (file)
@@ -1,48 +1,44 @@
 package SQL::Translator::Parser::DBI;
+use namespace::autoclean;
 use Moose::Role;
 use MooseX::Types::Moose qw(Maybe Str);
 use DBI::Const::GetInfoType;
 use DBI::Const::GetInfo::ANSI;
 use DBI::Const::GetInfoReturn;
-use SQL::Translator::Object::Column;
-use SQL::Translator::Object::Index;
-use SQL::Translator::Object::Table;
-use SQL::Translator::Object::View;
+use aliased 'SQL::Translator::Object::Column';
+use aliased 'SQL::Translator::Object::ForeignKey';
+use aliased 'SQL::Translator::Object::PrimaryKey';
+use aliased 'SQL::Translator::Object::Table';
+use aliased 'SQL::Translator::Object::View';
 
 has 'quoter' => (
-  is => 'rw',
-  isa => Str,
-  requried => 1,
-  lazy => 1,
-  default => sub { shift->dbh->get_info(29) || q{"} }
+    is => 'rw',
+    isa => Str,
+    lazy => 1,
+    default => sub { shift->dbh->get_info(29) || q{"} }
 );
 
 has 'namesep' => (
-  is => 'rw',
-  isa => Str,
-  required => 1,
-  lazy => 1,
-  default => sub { shift->dbh->get_info(41) || '.' }
+    is => 'rw',
+    isa => Str,
+    lazy => 1,
+    default => sub { shift->dbh->get_info(41) || '.' }
 );
 
 has 'schema_name' => (
-  is => 'rw',
-  isa => Maybe[Str],
-  required => 1,
-  lazy => 1,
-  default => sub { undef }
+    is => 'rw',
+    isa => Maybe[Str],
+    lazy => 1,
+    default => undef
 );
 
 has 'catalog_name' => (
-  is => 'rw',
-  isa => Maybe[Str],
-  required => 1,
-  lazy => 1,
-  default => sub { undef }
+    is => 'rw',
+    isa => Maybe[Str],
+    lazy => 1,
+    default => undef
 );
 
-no Moose;
-
 sub _subclass {
     my $self = shift;
 
@@ -53,6 +49,15 @@ sub _subclass {
     $class->meta->apply($self);
 }
 
+sub _is_auto_increment { 0 }
+
+sub _column_default_value {
+    my $self = shift;
+    my $column_info = shift;
+
+    return $column_info->{COLUMN_DEF};
+}
+
 sub _add_tables {
     my $self = shift;
     my $schema = shift;
@@ -60,16 +65,19 @@ sub _add_tables {
     my $sth = $self->dbh->table_info($self->catalog_name, $self->schema_name, '%', 'TABLE,VIEW');
     while (my $table_info = $sth->fetchrow_hashref) {
         if ($table_info->{TABLE_TYPE} eq 'TABLE') {
-            my $table = SQL::Translator::Object::Table->new({ name => $table_info->{TABLE_NAME} });
+            my $table = Table->new({ name => $table_info->{TABLE_NAME} });
             $schema->add_table($table);
             $self->_add_columns($table);
             $self->_add_primary_key($table);
         }
         elsif ($table_info->{TABLE_TYPE} eq 'VIEW') {
             my $sql = $self->_get_view_sql($table_info->{TABLE_NAME});
-            $schema->add_view(SQL::Translator::Object::View->new({ name => $table_info->{TABLE_NAME}, sql => $sql }));
+            my $view = View->new({ name => $table_info->{TABLE_NAME}, sql => $sql });
+            $schema->add_view($view);
+            $self->_add_columns($view);
         }
     }
+    $self->_add_foreign_key($schema->get_table($_), $schema) for $schema->table_ids;
 }
 
 sub _add_columns {
@@ -77,14 +85,15 @@ sub _add_columns {
     my $table = shift;
 
     my $sth = $self->dbh->column_info($self->catalog_name, $self->schema_name, $table->name, '%');
-    while (my $col_info = $sth->fetchrow_hashref) {
-        my $column = SQL::Translator::Object::Column->new({ name => $col_info->{COLUMN_NAME},
-                                                            data_type => $col_info->{TYPE_NAME},
-                                                            size => $col_info->{COLUMN_SIZE},
-                                                            default_value => $col_info->{COLUMN_DEF},
-                                                            is_nullable => $col_info->{NULLABLE}, });
+    while (my $column_info = $sth->fetchrow_hashref) {
+        my $column = Column->new({ name => $column_info->{COLUMN_NAME},
+                                   data_type => $column_info->{DATA_TYPE},
+                                   size => $column_info->{COLUMN_SIZE},
+                                   default_value => $self->_column_default_value($column_info),
+                                   is_auto_increment => $self->_is_auto_increment($column_info),
+                                   is_nullable => $column_info->{NULLABLE},
+                                 });
         $table->add_column($column);
-
     }
 }
 
@@ -93,32 +102,38 @@ sub _add_primary_key {
     my $table = shift;
 
     my $pk_info = $self->dbh->primary_key_info($self->catalog_name, $self->schema_name, $table->name);
-#    use Data::Dumper;
     my ($pk_name, @pk_cols);
     while (my $pk_col = $pk_info->fetchrow_hashref) {
         $pk_name = $pk_col->{PK_NAME};
         push @pk_cols, $pk_col->{COLUMN_NAME};
-#        print Dumper($pk_col);
-=cut
-$VAR1 = {
-          'PK_NAME' => 'tester_pkey',
-          'pg_column' => 'tester_pkey',
-          'pg_table' => 'tester',
-          'COLUMN_NAME' => 'id',
-          'pg_tablespace_name' => undef,
-          'pg_tablespace_location' => undef,
-          'TABLE_CAT' => undef,
-          'TABLE_NAME' => 'tester',
-          'DATA_TYPE' => 'int4',
-          'pg_schema' => 'public',
-          'TABLE_SCHEM' => 'public',
-          'KEY_SEQ' => '1'
-        };
-=cut
     }
-    my $index = SQL::Translator::Object::Index->new({ name => $pk_name, type => 'PRIMARY_KEY' });
-    $index->add_column($table->get_column($_)) for @pk_cols;
-    $table->add_index($index);
+    my $pk = PrimaryKey->new({ name => $pk_name });
+    $pk->add_column($table->get_column($_)) for @pk_cols;
+    $table->add_index($pk);
+}
+
+sub _add_foreign_key {
+    my $self = shift;
+    my $table = shift;
+    my $schema = shift;
+
+    my $fk_info = $self->dbh->foreign_key_info($self->catalog_name, $self->schema_name, $table->name, $self->catalog_name, $self->schema_name, undef);
+    return unless $fk_info;
+
+    my $fk_data;
+    while (my $fk_col = $fk_info->fetchrow_hashref) {
+        my $fk_name = $fk_col->{FK_NAME}; 
+
+        push @{$fk_data->{$fk_name}{columns}}, $fk_col->{FK_COLUMN_NAME};
+        $fk_data->{$fk_name}{table} = $fk_col->{FK_TABLE_NAME};
+        $fk_data->{$fk_name}{uk} = $schema->get_table($fk_col->{UK_TABLE_NAME})->get_index($fk_col->{UK_NAME});
+    }
+
+    foreach my $fk_name (keys %$fk_data) {
+        my $fk = ForeignKey->new({ name => $fk_name, references => $fk_data->{$fk_name}{uk} });
+        $fk->add_column($schema->get_table($fk_data->{$fk_name}{table})->get_column($_)) for @{$fk_data->{$fk_name}{columns}};
+        $table->add_constraint($fk);
+    }
 }
 
 1;