- Both the ::ODBC and ::ADO dispatchers now warn if a rdbms-specific
driver is not found for this connection before falling back to
plain ::Storage::DBI
+ - populate() in void context now uses the multi-row INSERT
+ statement in MySQL. It will send 500 rows at one time. You can
+ change this behavior by setting ????
* Fixes
- Fix exiting via next warnings from ResultSource
return $self->SUPER::insert (@_);
}
+sub insert_bulk {
+ my ($self, $table, $data, $cols) = @_;
+
+ my $sql = sprintf(
+ 'INSERT INTO %s ( ', $self->_quote($table),
+ );
+ $sql .= join( ', ', map { $self->_quote($_) } @$cols );
+ $sql .= ' ) VALUES ';
+
+ my @bind;
+ my @sql;
+ foreach my $datum ( @$data ) {
+ push @sql, '('
+ . join( ', ', ('?') x @$datum )
+ . ')';
+ push @bind, map { [ dummy => $_ ] } @$datum;
+ }
+
+ return (
+ $sql . join(',', @sql),
+ @bind
+ );
+}
+
# Allow STRAIGHT_JOIN's
sub _generate_join_clause {
my ($self, $join_type) = @_;
}
}
+ return $self->_insert_bulk(
+ $source, $cols, \%colvalues, $data,
+ );
+}
+
+# Broken out so that it can be overridden in Storage/DBI/mysql.pm
+sub _insert_bulk {
+ my ($self, $source, $cols, $colvalues, $data) = @_;
+
my ($sql, $bind) = $self->_prep_for_execute (
- 'insert', undef, $source, [\%colvalues]
+ 'insert', undef, $source, [$colvalues]
);
if (! @$bind) {
# directly into the SQL. This obviosly can't be good for multi-inserts
$self->throw_exception('Cannot insert_bulk without support for placeholders')
- if first { ref $_ ne 'SCALAR' } values %colvalues;
+ if first { ref $_ ne 'SCALAR' } values %$colvalues;
}
# neither _execute_array, nor _execute_inserts_with_no_binds are
return shift->_per_row_update_delete (@_);
}
+sub _insert_bulk {
+ my ($self, $source, $cols, $colvalues, $data) = @_;
+
+ my $bind_attrs = $self->source_bind_attributes($source);
+
+ return $self->_execute(
+ 'insert_bulk' => [], $source, $bind_attrs, $data, $cols,
+ );
+}
+
1;
=head1 NAME
ok ($rs->find({ name => "Hardcore Forker $pid" }), 'Expected row created');
}
+# Verify that populate in void context uses INSERT INTO foo VALUES (), (), ()
+# instead of 3 distinct SQL statements as other databases may require.
+{
+ my $rsrc = $schema->resultset('Artist')->result_source;
+ my ($rv, $sth, @bind) = $schema->storage->insert_bulk(
+ $rsrc,
+ [qw/ artistid name rank charfield /],
+ [
+ [ 100, 'John', 200, 'Smith' ],
+ [ 101, 'Joan', 201, 'Snith' ],
+ ],
+ );
+
+ is_same_sql_bind(
+ $sth->{Statement},
+ \@bind,
+ q{INSERT INTO artist ( artistid, name, rank, charfield ) VALUES ( ?, ?, ?, ? ), ( ?, ?, ?, ? )},
+ [
+ map { [ dummy => $_ ] } (
+ 100, 'John', 200, 'Smith',
+ 101, 'Joan', 201, 'Snith',
+ ),
+ ],
+ );
+
+ is( $schema->resultset('Artist')->find( 100 )->name, 'John' );
+}
+
done_testing;