Alzabo

 view release on metacpan or  search on metacpan

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

                 );

    my $vals = { %{ $self->{values} },
                 %{ $p{values} },
               };

    my $schema = $self->{table}->schema;
    my $driver = $schema->driver;

    my %ph = $self->{sql}->placeholders;
    my @val_order;
    while ( my ( $name, $i ) = each %ph )
    {
        $val_order[$i] = $name;
    }

    foreach my $name ( keys %$vals )
    {
        params_exception
            "Cannot provide a value for a column that was not specified ".
            "when the insert handle was created ($name)."
                unless exists $ph{$name};
    }

    my @pk = $self->{table}->primary_key;
    foreach my $pk (@pk)
    {
        unless ( exists $vals->{ $pk->name } )
        {
            if ( $pk->sequenced )
            {
                $vals->{ $pk->name } = $driver->next_sequence_number($pk);
            }
            else
            {
                params_exception
                    ( "No value provided for primary key (" .
                      $pk->name . ") and no sequence is available." );
            }
        }
    }

    foreach my $c ( @{ $self->{columns} } )
    {
        delete $vals->{ $c->name }
            if ! defined $vals->{ $c->name } && defined $c->default;
    }

    my @fk = $self->{table}->all_foreign_keys;

    my %id;

    $schema->begin_work if @fk;
    eval
    {
        foreach my $fk (@fk)
        {
            $fk->register_insert( map { $_->name => $vals->{ $_->name } } $fk->columns_from );
        }

        $self->{sql}->debug(\*STDERR) if Alzabo::Debug::SQL;
        print STDERR Devel::StackTrace->new if Alzabo::Debug::TRACE;

        $self->{handle}->execute_no_result
            ( map { exists $vals->{$_} ? $vals->{$_} : undef } @val_order );

        foreach my $pk (@pk)
        {
            $id{ $pk->name } = ( defined $vals->{ $pk->name } ?
                                 $vals->{ $pk->name } :
                                 $driver->get_last_id($self) );
        }

        # must come after call to ->get_last_id for MySQL because the
        # id will no longer be available after the transaction ends.
        $schema->commit if @fk;
    };
    if (my $e = $@)
    {
        eval { $schema->rollback };

        rethrow_exception $e;
    }

    return unless defined wantarray;

    return $self->{table}->row_by_pk( pk => \%id,
                                      no_cache => $self->{no_cache},
                                      %p,
                                    );
}

1;

__END__

=head1 NAME

Alzabo::Runtime::InsertHandle - A handle representing an insert

=head1 SYNOPSIS

 my $handle =
     $table->insert_handle
         ( columns => [ $table->columns( 'name', 'job' ) ] );

 my $faye_row =
     $handle->insert( values =>
                      { name => 'Faye',
                        job => 'HK Pop Chanteuse' } );

 my $guesch_row =
     $handle->insert( values =>
                      { name => 'Guesch',
                        job => 'French Chanteuse and Dancer' } );

=head1 DESCRIPTION

This object is analogous to a DBI statement handle, and can be used to
insert multiple rows into a table more efficiently than repeatedly
calling C<< Alzabo::Runtime::Table->insert() >>.



( run in 0.893 second using v1.01-cache-2.11-cpan-39bf76dae61 )