File Coverage

blib/lib/DBIx/Class/CDBICompat/SQLTransformer.pm
Criterion Covered Total %
statement 6 60 10.0
branch 0 10 0.0
condition 0 17 0.0
subroutine 2 9 22.2
pod 0 3 0.0
total 8 99 8.0


line stmt bran cond sub pod time code
1             package DBIx::Class::CDBICompat::SQLTransformer;
2              
3 2     2   1002 use strict;
  2         4  
  2         54  
4 2     2   9 use warnings;
  2         4  
  2         1421  
5              
6             =head1 NAME
7              
8             DBIx::Class::CDBICompat::SQLTransformer - Transform SQL
9              
10             =head1 DESCRIPTION
11              
12             This is a copy of L<Class::DBI::SQL::Transformer> from Class::DBI 3.0.17.
13             It is here so we can be compatible with L<Class::DBI> without having it
14             installed.
15              
16             =cut
17              
18             sub new {
19 0     0 0   my ($me, $caller, $sql, @args) = @_;
20 0           bless {
21             _caller => $caller,
22             _sql => $sql,
23             _args => [@args],
24             _transformed => 0,
25             } => $me;
26             }
27              
28             sub sql {
29 0     0 0   my $self = shift;
30 0 0         $self->_do_transformation if !$self->{_transformed};
31 0           return $self->{_transformed_sql};
32             }
33              
34             sub args {
35 0     0 0   my $self = shift;
36 0 0         $self->_do_transformation if !$self->{_transformed};
37 0           return @{ $self->{_transformed_args} };
  0            
38             }
39              
40             sub _expand_table {
41 0     0     my $self = shift;
42 0           my ($class, $alias) = split /=/, shift, 2;
43 0           my $caller = $self->{_caller};
44 0 0         my $table = $class ? $class->table : $caller->table;
45 0   0       $self->{cmap}{ $alias || $table } = $class || ref $caller || $caller;
      0        
46 0   0       ($alias ||= "") &&= " $alias";
      0        
47 0           return $table . $alias;
48             }
49              
50             sub _expand_join {
51 0     0     my $self = shift;
52 0           my $joins = shift;
53 0           my @table = split /\s+/, $joins;
54              
55 0           my $caller = $self->{_caller};
56 0           my %tojoin = map { $table[$_] => $table[ $_ + 1 ] } 0 .. $#table - 1;
  0            
57 0           my @sql;
58 0           while (my ($t1, $t2) = each %tojoin) {
59 0   0       my ($c1, $c2) = map $self->{cmap}{$_}
60             || $caller->_croak("Don't understand table '$_' in JOIN"), ($t1, $t2);
61              
62             my $join_col = sub {
63 0     0     my ($c1, $c2) = @_;
64 0           my $meta = $c1->meta_info('has_a');
65 0           my ($col) = grep $meta->{$_}->foreign_class eq $c2, keys %$meta;
66 0           $col;
67 0           };
68              
69 0   0       my $col = $join_col->($c1 => $c2) || do {
70             ($c1, $c2) = ($c2, $c1);
71             ($t1, $t2) = ($t2, $t1);
72             $join_col->($c1 => $c2);
73             };
74              
75 0 0         $caller->_croak("Don't know how to join $c1 to $c2") unless $col;
76 0           push @sql, sprintf " %s.%s = %s.%s ", $t1, $col, $t2, $c2->primary_column;
77             }
78 0           return join " AND ", @sql;
79             }
80              
81             sub _do_transformation {
82 0     0     my $me = shift;
83 0           my $sql = $me->{_sql};
84 0           my @args = @{ $me->{_args} };
  0            
85 0           my $caller = $me->{_caller};
86              
87 0           $sql =~ s/__TABLE\(?(.*?)\)?__/$me->_expand_table($1)/eg;
  0            
88 0           $sql =~ s/__JOIN\((.*?)\)__/$me->_expand_join($1)/eg;
  0            
89 0           $sql =~ s/__ESSENTIAL__/join ", ", $caller->_essential/eg;
  0            
90 0           $sql =~
91 0           s/__ESSENTIAL\((.*?)\)__/join ", ", map "$1.$_", $caller->_essential/eg;
92 0 0         if ($sql =~ /__IDENTIFIER__/) {
93 0           my $key_sql = join " AND ", map "$_=?", $caller->primary_columns;
94 0           $sql =~ s/__IDENTIFIER__/$key_sql/g;
95             }
96              
97 0           $me->{_transformed_sql} = $sql;
98 0           $me->{_transformed_args} = [@args];
99 0           $me->{_transformed} = 1;
100 0           return 1;
101             }
102              
103             =head1 FURTHER QUESTIONS?
104              
105             Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
106              
107             =head1 COPYRIGHT AND LICENSE
108              
109             This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
110             by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
111             redistribute it and/or modify it under the same terms as the
112             L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
113              
114             =cut
115              
116             1;