Alzabo

 view release on metacpan or  search on metacpan

lib/Alzabo/Runtime/Table.pm  view on Meta::CPAN


sub add_group
{
    my $self = shift;

    validate_pos( @_, ( { isa => 'Alzabo::Column' } ) x @_ );

    my @names = map { $_->name } @_;
    foreach my $col (@_)
    {
        params_exception "Column " . $col->name . " doesn't exist in $self->{name}"
            unless $self->has_column( $col->name );

        next if $col->is_primary_key;
        $self->{groups}{ $col->name } = \@names;
    }
}

sub group_by_column
{
    my $self = shift;
    my $col = shift;

    return exists $self->{groups}{$col} ? @{ $self->{groups}{$col} } : $col;
}

my $alias_num = '000000000';
sub alias
{
    my $self = shift;

    my $clone;
    %$clone = %$self;

    bless $clone, ref $self;

    $clone->{alias_name} = $self->name . ++$alias_num;
    $clone->{real_table} = $self;

    $clone->{columns} = Tie::IxHash->new( map { $_->name => $_ } $self->columns );

    # Force clone of primary key columns right away.
    $clone->column($_) foreach map { $_->name } $self->primary_key;

    return $clone;
}

#
# Since its unlikely that a user will end up needing clones of more
# than 1-2 columns each time an alias is used, we only make copies as
# needed.
#
sub column
{
    my $self = shift;

    # I'm an alias, make an alias column
    if ( $self->{alias_name} )
    {
        my $name = shift;
        my $col = $self->SUPER::column($name);

        # not previously cloned
        unless ( $col->table eq $self )
        {
            # replace our copy of this column with a clone
            $col = $col->alias_clone( table => $self );
            my $index = $self->{columns}->Indices($name);
            $self->{columns}->Replace( $index, $col, $name );

            Scalar::Util::weaken( $col->{table} );

            delete $self->{pk_array} if $col->is_primary_key;
        }

        return $col;
    }
    else
    {
        return $self->SUPER::column(@_);
    }
}

sub alias_name
{
    # intentionally don't call $_[0]->name for a noticeable
    # performance boost
    return $_[0]->{alias_name} || $_[0]->{name};
}

sub real_table
{
    return $_[0]->{real_table} || $_[0];
}

# This gets called a _lot_ so doing this sort of 'memoization' helps
sub primary_key
{
    my $self = shift;

    $self->{pk_array} ||= [ $self->SUPER::primary_key ];

    return ( wantarray ?
             @{ $self->{pk_array} } :
             $self->{pk_array}->[0]
           );
}

1;

__END__

=head1 NAME

Alzabo::Runtime::Table - Table objects

=head1 SYNOPSIS

  my $table = $schema->table('foo');

  my $row = $table->row_by_pk( pk => 1 );

  my $row_cursor =
      $table->rows_where
          ( where =>
            [ Alzabo::Column object, '=', 5 ] );

=head1 DESCRIPTION

This object is able to create rows, either by making objects based on
existing data or inserting new data to make new rows.

This object also implements a method of lazy column evaluation that
can be used to save memory and database wear and tear.  Please see the
L<LAZY COLUMN LOADING> section for details.

=head1 INHERITS FROM

C<Alzabo::Table>

=for pod_merge merged

=head1 METHODS

=head2 Methods that return an C<Alzabo::Runtime::Row> object

All of these methods accept the "no_cache" parameter, which will be
passed on to C<< Alzabo::Runtime::Row->new >>.

=head2 insert

Inserts the given values into the table.  If no value is given for a
primary key column and the column is
L<"sequenced"|Alzabo::Column/sequenced> then the primary key will be
auto-generated.

It takes the following parameters:

=over 4

=item * values => $hashref



( run in 1.794 second using v1.01-cache-2.11-cpan-4ef0a570458 )