Alzabo

 view release on metacpan or  search on metacpan

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

package Alzabo::Runtime::InsertHandle;

use strict;

use Alzabo::Exceptions ( abbr => [ qw( exception params_exception ) ] );
use Alzabo::Runtime;

use Params::Validate qw( :all );
Params::Validate::validation_options( on_fail => sub { params_exception join '', @_ } );

use constant NEW_SPEC => { table => { isa => 'Alzabo::Runtime::Table' },
                           sql   => { isa => 'Alzabo::SQLMaker' },
                           columns => { type => ARRAYREF },
                           values  => { type => HASHREF, default => {} },
                         };

sub new
{
    my $class = shift;

    my %p = validate( @_, NEW_SPEC );

    my $self = bless \%p, $class;

    $self->{handle} =
        $self->{table}->schema->driver->statement_no_execute( sql => $p{sql}->sql );

    return $self;
}

sub insert
{
    my $self = shift;

    my %p = @_;
    %p = validate( @_,
                   { ( map { $_ => { optional => 1 } } keys %p ),
                     values => { type => HASHREF, default => {} },
                   },
                 );

    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)
        {



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