From: Peter Rabbitson Date: Sun, 6 Sep 2009 18:35:30 +0000 (+0000) Subject: Centralize identity insert control for mssql (it seems that issuing an OFF is not... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=afcfff010f5a1d6dbc3a5fb6dfbaeb6246c33372;p=dbsrgits%2FDBIx-Class-Historic.git Centralize identity insert control for mssql (it seems that issuing an OFF is not necessary) --- diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 6b5ec3d..7ebea34 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -1359,6 +1359,7 @@ sub insert_bulk { local $Data::Dumper::Indent = 1; local $Data::Dumper::Useqq = 1; local $Data::Dumper::Quotekeys = 0; + local $Data::Dumper::Sortkeys = 1; $self->throw_exception(sprintf "%s for populate slice:\n%s", $tuple_status->[$i][1], diff --git a/lib/DBIx/Class/Storage/DBI/MSSQL.pm b/lib/DBIx/Class/Storage/DBI/MSSQL.pm index 8bcb8cb..c4611b3 100644 --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@ -14,31 +14,26 @@ __PACKAGE__->mk_group_accessors(simple => qw/ __PACKAGE__->sql_maker_class('DBIx::Class::SQLAHacks::MSSQL'); +sub _set_identity_insert { + my ($self, $table) = @_; + $self->_get_dbh->do (sprintf + 'SET IDENTITY_INSERT %s ON', + $self->sql_maker->_quote ($table) + ); +} + sub insert_bulk { my $self = shift; my ($source, $cols, $data) = @_; - my $identity_insert = 0; - - COLUMNS: - foreach my $col (@{$cols}) { - if ($source->column_info($col)->{is_auto_increment}) { - $identity_insert = 1; - last COLUMNS; - } - } - - if ($identity_insert) { - my $table = $source->from; - $self->_get_dbh->do("SET IDENTITY_INSERT $table ON"); + if (List::Util::first + { $source->column_info ($_)->{is_auto_increment} } + (@{$cols}) + ) { + $self->_set_identity_insert ($source->name); } $self->next::method(@_); - - if ($identity_insert) { - my $table = $source->from; - $self->_get_dbh->do("SET IDENTITY_INSERT $table OFF"); - } } # support MSSQL GUID column types @@ -47,7 +42,7 @@ sub insert { my $self = shift; my ($source, $to_insert) = @_; - my $updated_cols = {}; + my $supplied_col_info = $self->_resolve_column_info($source, [keys %$to_insert] ); my %guid_cols; my @pk_cols = $source->primary_columns; @@ -71,11 +66,17 @@ sub insert { my @get_guids_for = grep { not exists $to_insert->{$_} } (@pk_guids, @auto_guids); + my $updated_cols = {}; + for my $guid_col (@get_guids_for) { my ($new_guid) = $self->_get_dbh->selectrow_array('SELECT NEWID()'); $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); + } + $updated_cols = { %$updated_cols, %{ $self->next::method(@_) } }; return $updated_cols; @@ -105,14 +106,6 @@ sub _prep_for_execute { if ($op eq 'insert') { $sql .= ';SELECT SCOPE_IDENTITY()'; - my $col_info = $self->_resolve_column_info($ident, [map $_->[0], @{$bind}]); - if (List::Util::first { $_->{is_auto_increment} } (values %$col_info) ) { - - my $table = $ident->from; - my $identity_insert_on = "SET IDENTITY_INSERT $table ON"; - my $identity_insert_off = "SET IDENTITY_INSERT $table OFF"; - $sql = "$identity_insert_on; $sql; $identity_insert_off"; - } } return ($sql, $bind); diff --git a/t/746mssql.t b/t/746mssql.t index 2ee8cc3..a75001e 100644 --- a/t/746mssql.t +++ b/t/746mssql.t @@ -12,8 +12,6 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PA plan skip_all => 'Set $ENV{DBICTEST_MSSQL_ODBC_DSN}, _USER and _PASS to run this test' unless ($dsn && $user); -plan tests => 39; - DBICTest::Schema->load_classes('ArtistGUID'); my $schema = DBICTest::Schema->connect($dsn, $user, $pass); @@ -220,6 +218,19 @@ lives_ok ( sub { ]); }, 'populate with PKs supplied ok' ); +lives_ok (sub { + # start a new connection, make sure rebless works + # test an insert with a supplied identity, followed by one without + my $schema = DBICTest::Schema->connect($dsn, $user, $pass); + for (1..2) { + my $id = $_ * 20 ; + $schema->resultset ('Owners')->create ({ id => $id, name => "troglodoogle $id" }); + $schema->resultset ('Owners')->create ({ name => "troglodoogle " . ($id + 1) }); + } +}, 'create with/without PKs ok' ); + +is ($schema->resultset ('Owners')->count, 19, 'owner rows really in db' ); + lives_ok ( sub { # start a new connection, make sure rebless works my $schema = DBICTest::Schema->connect($dsn, $user, $pass); @@ -329,9 +340,10 @@ $schema->storage->_sql_maker->{name_sep} = '.'; ], ); } - } +done_testing; + # clean up our mess END { if (my $dbh = eval { $schema->storage->_dbh }) {