Add storage component of multipk resultset update/delete for multicolumn IN capable...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / MultiColumnIn.pm
1 package DBIx::Class::Storage::DBI::MultiColumnIn;
2
3 use strict;
4 use warnings;
5
6 use base 'DBIx::Class::Storage::DBI';
7
8 =head1 NAME 
9
10 DBIx::Class::Storage::DBI::MultiColumnIn - Storage component for RDBMS supporting multicolumn in clauses
11
12 =head1 DESCRIPTION
13
14 While ANSI SQL does not define a multicolumn in operator, many databases can
15 in fact understand WHERE (cola, colb) IN ( SELECT subcol_a, subcol_b ... )
16 The storage class for any such RDBMS should inherit from this class, in order
17 to dramatically speed up update/delete operations on joined multipk resultsets.
18
19 At this point the only overriden method is C<_multipk_update_delete()>
20
21 =cut
22
23 sub _multipk_update_delete {
24   my $self = shift;
25   my ($rs, $op, $values) = @_;
26
27   my $rsrc = $rs->result_source;
28   my @pcols = $rsrc->primary_columns;
29   my $attrs = $rs->_resolved_attrs;
30
31   # naive check - this is an internal method after all, we should know what we are doing 
32   $self->throw_exception ('Number of columns selected by supplied resultset does not match number of primary keys')
33     if ( ref $attrs->{select} ne 'ARRAY' or @{$attrs->{select}} != @pcols );
34
35   # This is hideously ugly, but SQLA does not understand multicol IN expressions
36   my ($sql, @bind) = @${$rs->as_query};
37   $sql = sprintf ('(%s) IN %s',
38     join (', ', @pcols),
39     $sql,
40   );
41
42   return $self->$op (
43     $rsrc,
44     $op eq 'update' ? $values : (),
45     \[$sql, @bind],
46   );
47
48 }
49
50 =head1 AUTHORS
51
52 See L<DBIx::Class/CONTRIBUTORS>
53
54 =head1 LICENSE
55
56 You may distribute this code under the same terms as Perl itself.
57
58 =cut
59
60 1;