File Coverage

blib/lib/DBIx/Class/CDBICompat/SQLTransformer.pm
Criterion Covered Total %
statement 9 63 14.2
branch 0 10 0.0
condition 0 17 0.0
subroutine 3 10 30.0
pod 0 3 0.0
total 12 103 11.6


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