package Xmldoom::Schema::Table; use Xmldoom::Schema::Column; use Xmldoom::Schema::ForeignKey; use Xmldoom::Threads; use strict; sub new { my $class = shift; my $args = shift; my $parent; my $name; if ( ref($args) eq 'HASH' ) { $parent = $args->{parent}; $name = $args->{name}; } else { $parent = $args; $name = shift; } my $self = { parent => $parent, name => $name, columns => [ ], foreign_keys => [ ] }; bless $self, $class; return Xmldoom::Threads::make_shared($self, $args->{shared}); } sub DESTROY { my $self = shift; # we don't need no stinking weak references! $self->{parent} = undef; } sub get_schema { return shift->{parent}; } sub get_name { return shift->{name}; } sub get_columns { my $self = shift; my $args = shift; # deal with the simplest case if ( not defined $args ) { return $self->{columns}; } my $names; my $primary_key = 0; my $data_only = 0; if ( ref($args) eq 'ARRAY' ) { $names = $args; } elsif ( ref($args) eq 'HASH' ) { $primary_key = $args->{primary_key} if defined $args->{primary_key}; $data_only = $args->{data_only} if defined $args->{data_only}; } my @cols; foreach my $col ( @{$self->{columns}} ) { if ( defined $names ) { # only add those colums matched in the names list foreach my $name ( @$names ) { if ( $col->get_name() eq $name ) { push @cols, $col; last; } } } else { if ( $primary_key and $col->is_primary_key() ) { # only the primary key push @cols, $col; } elsif ( $data_only and not $col->is_primary_key() ) { # only the data push @cols, $col; } } } return \@cols; } sub get_column_names { my $self = shift; my $columns = $self->get_columns(@_); my @ret = map { $_->get_name() } @$columns; return \@ret; } sub get_column { my ($self, $name) = @_; my @cols = grep { $_->{name} eq $name } @{$self->{columns}}; if ( scalar @cols != 1 ) { return undef; } return $cols[0]; } sub get_primary_key { my $self = shift; my @columns; foreach my $col ( @{$self->{columns}} ) { if ( $col->{primary_key} ) { push @columns, $col; } } return \@columns; } sub get_column_type { my ($self, $name) = @_; my $column = $self->get_column($name); if ( defined $column ) { return $column->get_data_type(); } return undef; } sub get_foreign_keys { return shift->{foreign_keys}; } # TODO: this function operates like before but before it was broken! sub get_foreign_key { my ($self, $name) = @_; foreach my $key ( @{$self->get_foreign_keys()} ) { my $pair_name = $key->get_foreign_pair_name( $name ); if ( defined $pair_name ) { return { foreign_table => $key->get_reference_table_name(), local_column => $name, foreign_column => $pair_name }; } } return undef; } sub add_column { my $self; my @args; # sneak the parent argument in. if ( ref($_[1]) eq 'HASH' ) { $self = shift; @args = ( $_[1] ); $args[0]->{parent} = $self; } else { $self = $_[0]; @args = @_; } my $col = Xmldoom::Schema::Column->new(@_); if ( $self->get_column( $col->{name} ) ) { die "Table already has a column named \"$col->{name}\""; } push @{$self->{columns}}, $col; } sub add_foreign_key { my $self = shift; my $args = shift; if ( ref($args) eq 'HASH' ) { $args->{parent} = $self; } else { $args = { parent => $self, reference_table => $args, local_columns => shift, foreign_columns => shift }; } push @{$self->{foreign_keys}}, Xmldoom::Schema::ForeignKey->new($args); } 1;