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 )