Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/Table.pm view on Meta::CPAN
package Alzabo::Table;
use strict;
use vars qw($VERSION);
use Alzabo;
use Params::Validate qw( :all );
Params::Validate::validation_options( on_fail => sub { Alzabo::Exception::Params->throw( error => join '', @_ ) } );
use Tie::IxHash;
$VERSION = 2.0;
1;
sub schema
{
my $self = shift;
return $self->{schema};
}
sub name
{
my $self = shift;
return $self->{name};
}
use constant HAS_COLUMN_SPEC => { type => SCALAR };
sub has_column
{
my $self = shift;
validate_pos( @_, HAS_COLUMN_SPEC );
return $self->{columns}->FETCH(shift);
}
sub column
{
my $self = shift;
my $name = shift;
if ( my $col = $self->{columns}->FETCH($name) )
{
return $col;
}
else
{
Alzabo::Exception::Params->throw
( error => "Column $name doesn't exist in $self->{name}" );
}
}
sub columns
{
my $self = shift;
return $self->column(@_) if @_ ==1 ;
return map { $self->column($_) } @_ if @_ > 1;
return $self->{columns}->Values;
}
sub primary_key
{
my $self = shift;
return unless @{ $self->{pk} };
return ( wantarray ?
$self->{columns}->Values( @{ $self->{pk} } ) :
$self->{columns}->Values( $self->{pk}[0] )
);
}
sub primary_key_size
{
my $self = shift;
return scalar @{ $self->{pk} };
}
use constant COLUMN_IS_PRIMARY_KEY_SPEC => { isa => 'Alzabo::Column' };
sub column_is_primary_key
{
my $self = shift;
validate_pos( @_, COLUMN_IS_PRIMARY_KEY_SPEC );
my $name = shift->name;
Alzabo::Exception::Params->throw( error => "Column $name doesn't exist in $self->{name}" )
unless $self->{columns}->EXISTS($name);
my $idx = $self->{columns}->Indices($name);
return 1 if grep { $idx == $_ } @{ $self->{pk} };
return 0;
}
sub attributes
{
return keys %{ $_[0]->{attributes} };
}
use constant HAS_ATTRIBUTE_SPEC => { attribute => { type => SCALAR },
case_sensitive => { type => SCALAR,
default => 0 },
};
sub has_attribute
{
my $self = shift;
my %p = validate( @_, HAS_ATTRIBUTE_SPEC );
if ( $p{case_sensitive} )
{
return exists $self->{attributes}{ $p{attribute} };
}
else
{
return 1 if grep { lc $p{attribute} eq lc $_ } keys %{ $self->{attributes} };
}
}
use constant FOREIGN_KEYS_SPEC => { column => { isa => 'Alzabo::Column' },
table => { isa => 'Alzabo::Table' },
};
sub foreign_keys
{
my $self = shift;
validate( @_, FOREIGN_KEYS_SPEC );
my %p = @_;
my $c_name = $p{column}->name;
my $t_name = $p{table}->name;
Alzabo::Exception::Params->throw( error => "Column $c_name doesn't exist in $self->{name}" )
unless $self->{columns}->EXISTS($c_name);
Alzabo::Exception::Params->throw( error => "No foreign keys to $t_name exist in $self->{name}" )
unless exists $self->{fk}{$t_name};
Alzabo::Exception::Params->throw( error => "Column $c_name is not a foreign key to $t_name in $self->{name}" )
unless exists $self->{fk}{$t_name}{$c_name};
return wantarray ? @{ $self->{fk}{$t_name}{$c_name} } : $self->{fk}{$t_name}{$c_name}[0];
}
use constant FOREIGN_KEYS_BY_TABLE_SPEC => { isa => 'Alzabo::Table' };
sub foreign_keys_by_table
{
my $self = shift;
validate_pos( @_, FOREIGN_KEYS_BY_TABLE_SPEC );
my $name = shift->name;
my $fk = $self->{fk};
my %fk;
if ( exists $fk->{$name} )
{
foreach my $c ( keys %{ $fk->{$name} } )
{
return $fk->{$name}{$c}[0] unless wantarray;
$fk{$_} = $_ for @{ $fk->{$name}{$c} };
}
}
return values %fk;
}
use constant FOREIGN_KEYS_BY_COLUMN_SPEC => { isa => 'Alzabo::Column' };
sub foreign_keys_by_column
{
my $self = shift;
my ($col) = validate_pos( @_, FOREIGN_KEYS_BY_COLUMN_SPEC );
Alzabo::Exception::Params->throw( error => "Column " . $col->name . " doesn't exist in $self->{name}" )
unless $self->{columns}->EXISTS( $col->name );
my $fk = $self->{fk};
my %fk;
foreach my $t (keys %$fk)
{
if ( exists $fk->{$t}{ $col->name } )
{
return $fk->{$t}{ $col->name }[0] unless wantarray;
$fk{$_} = $_ for @{ $fk->{$t}{ $col->name } };
}
}
return values %fk;
}
sub all_foreign_keys
{
my $self = shift;
my %seen;
my @fk;
my $fk = $self->{fk};
foreach my $t (keys %$fk)
{
foreach my $c ( keys %{ $fk->{$t} } )
{
foreach my $key ( @{ $fk->{$t}{$c} } )
{
next if $seen{$key};
push @fk, $key;
$seen{$key} = 1;
}
}
}
return wantarray ? @fk : $fk[0];
}
sub index
{
my $self = shift;
validate_pos( @_, { type => SCALAR } );
my $id = shift;
Alzabo::Exception::Params->throw( error => "Index $id doesn't exist in $self->{name}" )
unless $self->{indexes}->EXISTS($id);
return $self->{indexes}->FETCH($id);
}
sub has_index
{
my $self = shift;
validate_pos( @_, { type => SCALAR } );
my $id = shift;
return $self->{indexes}->EXISTS($id);
}
sub indexes
{
my $self = shift;
return $self->{indexes}->Values;
}
sub comment { $_[0]->{comment} }
__END__
=head1 NAME
Alzabo::Table - Table objects
=head1 SYNOPSIS
use Alzabo::Table;
my $t = $schema->table('foo');
foreach $pk ($t->primary_keys)
{
print $pk->name;
}
=head1 DESCRIPTION
Objects in this class represent tables. They contain foreign key,
index, and column objects.
=head1 METHODS
=head2 schema
Returns the L<C<Alzabo::Schema>|Alzabo::Schema> object to which this
table belongs.
=head2 name
Returns the name of the table.
=head2 column ($name)
Returns the L<C<Alzabo::Column>|Alzabo::Column> object that matches
the name given.
An L<C<Alzabo::Exception::Params>|Alzabo::Exceptions> exception is
throws if the table does not contain the column.
=head2 columns (@optional_list_of_column_names)
If no arguments are given, returns a list of all
L<C<Alzabo::Column>|Alzabo::Column> objects in the schema, or in a
scalar context the number of such tables. If one or more arguments
( run in 0.495 second using v1.01-cache-2.11-cpan-39bf76dae61 )