still busted :-(
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / ODBC / Microsoft_SQL_Server.pm
CommitLineData
c1cac633 1package DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server;
2use strict;
3use warnings;
4
eb0323df 5use base qw/DBIx::Class::Storage::DBI::MSSQL/;
c1cac633 6
7sub _prep_for_execute {
259c0e40 8 my $self = shift;
9 my ($op, $extra_bind, $ident, $args) = @_;
10
11 my ($sql, $bind) = $self->next::method (@_);
12 $sql .= ';SELECT SCOPE_IDENTITY()' if $op eq 'insert';
13
764a1b60 14 my $alias2src = $self->_resolve_ident_sources($ident);
15 my %identity_insert_tables;
16 foreach my $bound (@{$bind}) {
17 my $col = $bound->[0];
18 my $name_sep = $self->_sql_maker_opts->{name_sep} || '.';
19
20 $col =~ s/^([^\Q${name_sep}\E]*)\Q${name_sep}\E//;
21 my $alias = $1 || 'me';
22 my $rsrc = $alias2src->{$alias};
23
24 my $is_auto_increment = $rsrc && $rsrc->column_info($col)->{is_auto_increment};
25 my $table;
26 if ($is_auto_increment) {
27 $identity_insert_tables{$rsrc->from} = 1;
259c0e40 28 }
29 }
c1cac633 30
764a1b60 31 my $identity_insert_on = join '', map { "SET IDENTITY_INSERT $_ ON; " } keys %identity_insert_tables;
32 my $identity_insert_off = join '', map { "SET IDENTITY_INSERT $_ OFF; " } keys %identity_insert_tables;
33 $sql = "$identity_insert_on $sql $identity_insert_off";
34
259c0e40 35 return ($sql, $bind);
c1cac633 36}
37
2eebd801 38sub _execute {
39 my $self = shift;
40 my ($op) = @_;
c1cac633 41
2eebd801 42 my ($rv, $sth, @bind) = $self->dbh_do($self->can('_dbh_execute'), @_);
77af494b 43 if ($op eq 'insert') {
44 $self->{_scope_identity} = $sth->fetchrow_array;
45 $sth->finish;
46 }
c1cac633 47
2eebd801 48 return wantarray ? ($rv, $sth, @bind) : $rv;
c1cac633 49}
50
51sub last_insert_id { shift->{_scope_identity} }
52
c1cac633 531;
54
55__END__
56
57=head1 NAME
58
a89c6fc0 59DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - Support specific
60to Microsoft SQL Server over ODBC
c1cac633 61
62=head1 DESCRIPTION
63
64This class implements support specific to Microsoft SQL Server over ODBC,
65including auto-increment primary keys and SQL::Abstract::Limit dialect. It
66is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it
67detects a MSSQL back-end.
68
69=head1 IMPLEMENTATION NOTES
70
71Microsoft SQL Server supports three methods of retrieving the IDENTITY
72value for inserted row: IDENT_CURRENT, @@IDENTITY, and SCOPE_IDENTITY().
73SCOPE_IDENTITY is used here because it is the safest. However, it must
74be called is the same execute statement, not just the same connection.
75
76So, this implementation appends a SELECT SCOPE_IDENTITY() statement
77onto each INSERT to accommodate that requirement.
78
c1cac633 79=head1 AUTHORS
80
81Marc Mims C<< <marc@questright.com> >>
82
83=head1 LICENSE
84
85You may distribute this code under the same terms as Perl itself.
86
87=cut
259c0e40 88# vim: sw=2 sts=2