Finished ripping hand-hacked abstract implementation out of core
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / SQL / Abstract.pm
diff --git a/lib/DBIx/Class/SQL/Abstract.pm b/lib/DBIx/Class/SQL/Abstract.pm
deleted file mode 100644 (file)
index a0740c2..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-package DBIx::Class::SQL::Abstract;
-
-use strict;
-use warnings;
-
-# Many thanks to SQL::Abstract, from which I stole most of this
-
-sub _debug { }
-
-sub _cond_resolve {
-  my ($self, $cond, $attrs, $join) = @_;
-  $cond = $self->_anoncopy($cond);   # prevent destroying original
-  my $ref   = ref $cond || '';
-  $join   ||= $attrs->{logic} || ($ref eq 'ARRAY' ? 'OR' : 'AND');
-  my $cmp   = uc($attrs->{cmp}) || '=';
-
-  # For assembling SQL fields and values
-  my(@sqlf) = ();
-
-  # If an arrayref, then we join each element
-  if ($ref eq 'ARRAY') {
-    # need to use while() so can shift() for arrays
-    my $subjoin;
-    while (my $el = shift @$cond) {
-      
-      # skip empty elements, otherwise get invalid trailing AND stuff
-      if (my $ref2 = ref $el) {
-        if ($ref2 eq 'ARRAY') {
-          next unless @$el;
-        } elsif ($ref2 eq 'HASH') {
-          next unless %$el;
-          $subjoin ||= 'AND';
-        } elsif ($ref2 eq 'SCALAR') {
-          # literal SQL
-          push @sqlf, $$el;
-          next;
-        }
-        $self->_debug("$ref2(*top) means join with $subjoin");
-      } else {
-        # top-level arrayref with scalars, recurse in pairs
-        $self->_debug("NOREF(*top) means join with $subjoin") if $subjoin;
-        $el = {$el => shift(@$cond)};
-      }
-      my @ret = $self->_cond_resolve($el, $attrs, $subjoin);
-      push @sqlf, shift @ret;
-    }
-  }
-  elsif ($ref eq 'HASH') {
-    # Note: during recursion, the last element will always be a hashref,
-    # since it needs to point a column => value. So this be the end.
-    for my $k (sort keys %$cond) {
-      my $v = $cond->{$k};
-      if ($k =~ /^-(.*)/) {
-        # special nesting, like -and, -or, -nest, so shift over
-        my $subjoin = $self->_modlogic($attrs, uc($1));
-        $self->_debug("OP(-$1) means special logic ($subjoin), recursing...");
-        my @ret = $self->_cond_resolve($v, $attrs, $subjoin);
-        push @sqlf, shift @ret;
-      } elsif (! defined($v)) {
-        # undef = null
-        $self->_debug("UNDEF($k) means IS NULL");
-        push @sqlf, $self->_cond_key($attrs => $k) . ' IS NULL'
-      } elsif (ref $v eq 'ARRAY') {
-        # multiple elements: multiple options
-        # warnings... $self->_debug("ARRAY($k) means multiple elements: [ @$v ]");
-        
-        # special nesting, like -and, -or, -nest, so shift over
-        my $subjoin = 'OR';
-        if ($v->[0] =~ /^-(.*)/) {
-          $subjoin = $self->_modlogic($attrs, uc($1));    # override subjoin
-          $self->_debug("OP(-$1) means special logic ($subjoin), shifting...");
-          shift @$v;
-        }
-
-        # map into an array of hashrefs and recurse
-        my @ret = $self->_cond_resolve([map { {$k => $_} } @$v], $attrs, $subjoin);
-        
-        # push results into our structure
-        push @sqlf, shift @ret;        
-      } elsif (ref $v eq 'HASH') {
-        # modified operator { '!=', 'completed' }
-        for my $f (sort keys %$v) {
-          my $x = $v->{$f};
-          $self->_debug("HASH($k) means modified operator: { $f }");
-
-          # check for the operator being "IN" or "BETWEEN" or whatever
-          if (ref $x eq 'ARRAY') {
-            if ($f =~ /^-?\s*(not[\s_]+)?(in|between)\s*$/i) {
-              my $mod = $1 ? $1 . $2 : $2;  # avoid uninitialized value warnings
-              my $u = $self->_modlogic($attrs, uc($mod));
-              $self->_debug("HASH($f => $x) uses special operator: [ $u ]");
-              if ($u =~ /BETWEEN/) {
-                # SQL sucks
-                $self->throw( "BETWEEN must have exactly two arguments" ) unless @$x == 2;
-                push @sqlf, join ' ',
-                              $self->_cond_key($attrs => $k), $u,
-                              $self->_cond_value($attrs => $k => $x->[0]),
-                              'AND',
-                              $self->_cond_value($attrs => $k => $x->[1]);
-              } else {
-                push @sqlf, join ' ', $self->_cond_key($attrs, $k), $u, '(',
-                        join(', ',
-                          map { $self->_cond_value($attrs, $k, $_) } @$x),
-                      ')';
-              }
-            } else {
-              # multiple elements: multiple options
-              $self->_debug("ARRAY($x) means multiple elements: [ @$x ]");
-  
-              # map into an array of hashrefs and recurse
-              my @ret = $self->_cond_resolve([map { {$k => {$f, $_}} } @$x], $attrs);
-
-              # push results into our structure
-              push @sqlf, shift @ret;              
-            }
-          } elsif (! defined($x)) {
-            # undef = NOT null
-            my $not = ($f eq '!=' || $f eq 'not like') ? ' NOT' : '';
-            push @sqlf, $self->_cond_key($attrs => $k) . " IS${not} NULL";
-          } else {
-            # regular ol' value
-            $f =~ s/^-//;   # strip leading -like =>
-            $f =~ s/_/ /;   # _ => " "
-            push @sqlf, join ' ', $self->_cond_key($attrs => $k), uc($f),
-                          $self->_cond_value($attrs => $k => $x);
-          }
-        }
-      } elsif (ref $v eq 'SCALAR') {
-        # literal SQL
-        $self->_debug("SCALAR($k) means literal SQL: $$v");
-        push @sqlf, join ' ', $self->_cond_key($attrs => $k), $$v;
-      } else {
-        # standard key => val
-        $self->_debug("NOREF($k) means simple key=val: $k ${cmp} $v");
-        push @sqlf, join ' ', $self->_cond_key($attrs => $k), $cmp,
-                      $self->_cond_value($attrs => $k => $v);
-      }
-    }
-  }
-  elsif ($ref eq 'SCALAR') {
-    # literal sql
-    $self->_debug("SCALAR(*top) means literal SQL: $$cond");
-    push @sqlf, $$cond;
-  }
-  elsif (defined $cond) {
-    # literal sql
-    $self->_debug("NOREF(*top) means literal SQL: $cond");
-    push @sqlf, $cond;
-  }
-
-  # assemble and return sql
-  my $wsql = @sqlf ? '( ' . join(" $join ", @sqlf) . ' )' : '1 = 1';
-  return wantarray ? ($wsql, @{$attrs->{bind} || []}) : $wsql; 
-}
-
-sub _cond_key {
-  my ($self, $attrs, $key) = @_;
-  return $key;
-}
-
-sub _cond_value {
-  my ($self, $attrs, $key, $value) = @_;
-  push(@{$attrs->{bind}}, $value);
-  return '?';
-}
-
-# Anon copies of arrays/hashes
-sub _anoncopy {
-  my ($self, $orig) = @_;
-  return (ref $orig eq 'HASH' ) ? { %$orig }
-     : (ref $orig eq 'ARRAY') ? [ @$orig ]
-     : $orig;     # rest passthru ok
-}
-
-sub _modlogic {
-  my ($self, $attrs, $sym) = @_;
-  $sym ||= $attrs->{logic};
-  $sym =~ tr/_/ /;
-  $sym = $attrs->{logic} if $sym eq 'nest';
-  return uc($sym);  # override join
-}
-  
-1;
-
-=head1 NAME 
-
-DBIx::Class::SQL::Abstract - SQL::Abstract customized for DBIC.
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-This is a customized version of L<SQL::Abstract> for use in 
-generating L<DBIx::Searchbuilder> searches.
-
-=cut
-
-=head1 AUTHORS
-
-Matt S. Trout <perl-stuff@trout.me.uk>
-
-=head1 LICENSE
-
-You may distribute this code under the same terms as Perl itself.
-
-=cut