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