From: Jess Robinson Date: Tue, 3 Oct 2006 19:01:12 +0000 (+0000) Subject: Fixed to actually insert using column names, thanks claco! X-Git-Tag: v0.08010~150^2~146 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=744076d877e640d1fa237e13854b156a9a1892d3 Fixed to actually insert using column names, thanks claco! --- diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index c9ba994..4df22c9 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -778,7 +778,12 @@ Pass this method a resultsource name, and an arrayref of arrayrefs. The arrayrefs should contain a list of column names, followed by one or many sets of matching data for the given columns. -Each set of data is inserted into the database using +In void context, C in L is used +to insert the data, as this is a fast method. However, insert_bulk currently +assumes that your datasets all contain the same type of values, using scalar +references in a column in one row, and not in another will probably not work. + +Otherwise, each set of data is inserted into the database using L, and a arrayref of the resulting row objects is returned. diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 3ede145..14a6236 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -847,9 +847,16 @@ sub insert { return $to_insert; } +## Still not quite perfect, and EXPERIMENTAL +## Currently it is assumed that all values passed will be "normal", i.e. not +## scalar refs, or at least, all the same type as the first set, the statement is +## only prepped once. sub insert_bulk { my ($self, $table, $cols, $data) = @_; - my ($sql, @bind) = $self->sql_maker->insert($table, @$data); + my %colvalues; + @colvalues{@$cols} = (0..$#$cols); + my ($sql, @bind) = $self->sql_maker->insert($table, \%colvalues); +# print STDERR "BIND".Dumper(\@bind); if ($self->debug) { my @debug_bind = map { defined $_ ? qq{'$_'} : q{'NULL'} } @bind; @@ -865,12 +872,23 @@ sub insert_bulk { # @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args my $rv; + ## This must be an arrayref, else nothing works! + my $tuple_status = []; +# use Data::Dumper; +# print STDERR Dumper($data); if ($sth) { my $time = time(); - $rv = eval { $sth->execute_array({ ArrayTupleFetch => sub { return shift @$data; }}) }; - - if ($@ || !$rv) { - $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr)); + $rv = eval { $sth->execute_array({ ArrayTupleFetch => sub { my $values = shift @$data; return if !$values; return [ @{$values}[@bind] ]}, + ArrayTupleStatus => $tuple_status }) }; +# print STDERR Dumper($tuple_status); +# print STDERR "RV: $rv\n"; + if ($@ || !defined $rv) { + my $errors = ''; + foreach my $tuple (@$tuple_status) + { + $errors .= "\n" . $tuple->[1] if(ref $tuple); + } + $self->throw_exception("Error executing '$sql': ".($@ || $errors)); } } else { $self->throw_exception("'$sql' did not generate a statement.");