From: Rafael Kitover Date: Wed, 9 Sep 2009 10:27:02 +0000 (+0000) Subject: Merge 'trunk' into 'sybase' X-Git-Tag: v0.08112~14^2~20 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f1d27127f48c2aacec9ce99a1d4daa90e81b4531;hp=bda35a4c8068f8e2e263ee09c581905297dd6974;p=dbsrgits%2FDBIx-Class.git Merge 'trunk' into 'sybase' r20554@hlagh (orig r7595): wreis | 2009-09-07 09:31:38 -0400 improved warn for Storable hooks in ResultSourceHandle r20558@hlagh (orig r7597): ribasushi | 2009-09-07 10:26:59 -0400 Whoops - last_insert_id allows for multiple autoinc columns - support it in pg r20560@hlagh (orig r7598): ribasushi | 2009-09-07 10:46:14 -0400 Prune duplicate constraints from the find() condition r20578@hlagh (orig r7603): frew | 2009-09-08 14:13:29 -0400 Turn IDENTITY_INSERT back off after inserts --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 6421875..0e75f35 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -570,12 +570,16 @@ sub _unique_queries { my $where = $self->_collapse_cond($self->{attrs}{where} || {}); my $num_where = scalar keys %$where; - my @unique_queries; + my (@unique_queries, %seen_column_combinations); foreach my $name (@constraint_names) { - my @unique_cols = $self->result_source->unique_constraint_columns($name); - my $unique_query = $self->_build_unique_query($query, \@unique_cols); + my @constraint_cols = $self->result_source->unique_constraint_columns($name); - my $num_cols = scalar @unique_cols; + my $constraint_sig = join "\x00", sort @constraint_cols; + next if $seen_column_combinations{$constraint_sig}++; + + my $unique_query = $self->_build_unique_query($query, \@constraint_cols); + + my $num_cols = scalar @constraint_cols; my $num_query = scalar keys %$unique_query; my $total = $num_query + $num_where; diff --git a/lib/DBIx/Class/ResultSourceHandle.pm b/lib/DBIx/Class/ResultSourceHandle.pm index d7d0190..33204df 100644 --- a/lib/DBIx/Class/ResultSourceHandle.pm +++ b/lib/DBIx/Class/ResultSourceHandle.pm @@ -106,7 +106,8 @@ sub STORABLE_thaw { $self->{schema} = $rs->schema if $rs; } - carp "Unable to restore schema" unless $self->{schema}; + carp "Unable to restore schema. Look at 'freeze' and 'thaw' methods in DBIx::Class::Schema." + unless $self->{schema}; } =head1 AUTHOR diff --git a/lib/DBIx/Class/Storage/DBI/MSSQL.pm b/lib/DBIx/Class/Storage/DBI/MSSQL.pm index d528b22..3189a3c 100644 --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@ -32,18 +32,38 @@ sub _set_identity_insert { } } +sub _unset_identity_insert { + my ($self, $table) = @_; + + my $sql = sprintf ( + 'SET IDENTITY_INSERT %s OFF', + $self->sql_maker->_quote ($table), + ); + + my $dbh = $self->_get_dbh; + $dbh->do ($sql); +} + sub insert_bulk { my $self = shift; my ($source, $cols, $data) = @_; - if (List::Util::first + my $is_identity_insert = (List::Util::first { $source->column_info ($_)->{is_auto_increment} } (@{$cols}) - ) { - $self->_set_identity_insert ($source->name); + ) + ? 1 + : 0; + + if ($is_identity_insert) { + $self->_set_identity_insert ($source->name); } $self->next::method(@_); + + if ($is_identity_insert) { + $self->_unset_identity_insert ($source->name); + } } # support MSSQL GUID column types @@ -83,12 +103,21 @@ sub insert { $updated_cols->{$guid_col} = $to_insert->{$guid_col} = $new_guid; } - if (List::Util::first { $_->{is_auto_increment} } (values %$supplied_col_info) ) { - $self->_set_identity_insert ($source->name); + my $is_identity_insert = (List::Util::first { $_->{is_auto_increment} } (values %$supplied_col_info) ) + ? 1 + : 0; + + if ($is_identity_insert) { + $self->_set_identity_insert ($source->name); } $updated_cols = { %$updated_cols, %{ $self->next::method(@_) } }; + if ($is_identity_insert) { + $self->_unset_identity_insert ($source->name); + } + + return $updated_cols; } diff --git a/lib/DBIx/Class/Storage/DBI/Pg.pm b/lib/DBIx/Class/Storage/DBI/Pg.pm index dd9e339..3d25b83 100644 --- a/lib/DBIx/Class/Storage/DBI/Pg.pm +++ b/lib/DBIx/Class/Storage/DBI/Pg.pm @@ -20,15 +20,22 @@ sub with_deferred_fk_checks { } sub last_insert_id { - my ($self,$source,$col) = @_; - my $seq = ( $source->column_info($col)->{sequence} ||= $self->dbh_do('_dbh_get_autoinc_seq', $source, $col) ) + my ($self,$source,@cols) = @_; + + my @values; + + for my $col (@cols) { + my $seq = ( $source->column_info($col)->{sequence} ||= $self->dbh_do('_dbh_get_autoinc_seq', $source, $col) ) or $self->throw_exception( "could not determine sequence for " . $source->name . ".$col, please consider adding a " . "schema-qualified sequence to its column info" ); - $self->_dbh_last_insert_id ($self->_dbh, $seq); + push @values, $self->_dbh_last_insert_id ($self->_dbh, $seq); + } + + return @values; } # there seems to be absolutely no reason to have this as a separate method, diff --git a/t/80unique.t b/t/80unique.t index 8bd7e2c..2245511 100644 --- a/t/80unique.t +++ b/t/80unique.t @@ -1,14 +1,14 @@ use strict; -use warnings; +use warnings; use Test::More; use lib qw(t/lib); use DBICTest; +use DBIC::SqlMakerTest; +use DBIC::DebugObj; my $schema = DBICTest->init_schema(); -plan tests => 49; - # Check the defined unique constraints is_deeply( [ sort $schema->source('CD')->unique_constraint_names ], @@ -209,4 +209,27 @@ is($row->baz, 3, 'baz is correct'); ); ok($cd2->in_storage, 'Updating year using update_or_new was successful'); is($cd2->id, $cd1->id, 'Got the same CD using update_or_new'); -} \ No newline at end of file +} + +# make sure the ident condition is assembled sanely +{ + my $artist = $schema->resultset('Artist')->next; + + my ($sql, @bind); + $schema->storage->debugobj(DBIC::DebugObj->new(\$sql, \@bind)), + $schema->storage->debug(1); + + $artist->discard_changes; + + is_same_sql_bind ( + $sql, + \@bind, + 'SELECT me.artistid, me.name, me.rank, me.charfield FROM artist me WHERE me.artistid = ?', + [qw/'1'/], + ); + + $schema->storage->debug(0); + $schema->storage->debugobj(undef); +} + +done_testing; diff --git a/t/lib/DBICTest/Schema/Artist.pm b/t/lib/DBICTest/Schema/Artist.pm index 2745c03..56c1191 100644 --- a/t/lib/DBICTest/Schema/Artist.pm +++ b/t/lib/DBICTest/Schema/Artist.pm @@ -30,6 +30,7 @@ __PACKAGE__->add_columns( }, ); __PACKAGE__->set_primary_key('artistid'); +__PACKAGE__->add_unique_constraint(['artistid']); # do not remove, part of a test __PACKAGE__->mk_classdata('field_name_for', { artistid => 'primary key',