package SQL::Builder::Select; use strict; use warnings; use Exporter; use Carp; use vars qw / $VERSION @ISA /; $VERSION = 1.00; @ISA = qw/ Exporter /; sub new { my $class = shift; my $self = {}; bless ($self, $class); return $self; } ##################################################################### sub column { my $class = shift; push @{$class->{column}}, @_; return scalar( @{$class->{column}} ); } sub table { my $class = shift; push @{$class->{table}}, @_; return scalar( @{$class->{table}} ); } ##################################################################### sub where { my $class = shift; push @{$class->{where}}, @_; return scalar( @{$class->{where}} ); } sub where_and { my $class = shift; push @{$class->{where_and}}, @_; return scalar( @{$class->{where_and}} ); } sub where_or { my $class = shift; push @{$class->{where_or}}, @_; return scalar( @{$class->{where_or}} ); } sub where_eq_and { my $class = shift; push @{$class->{where_and}}, map { $_ . ' = ?' } @_; return scalar( @{$class->{where_and}} ); } sub where_ne_and { my $class = shift; push @{$class->{where_and}}, map { $_ . ' != ?' } @_; return scalar( @{$class->{where_and}} ); } sub where_eq_or { my $class = shift; push @{$class->{where_or}}, map { $_ . ' = ?' } @_; return scalar( @{$class->{where_or}} ); } sub where_ne_or { my $class = shift; push @{$class->{where_or}}, map { $_ . ' != ?' } @_; return scalar( @{$class->{where_or}} ); } sub where_logic { my $class = shift; $class->{where_logic} = shift; } ##################################################################### sub order_by { my $class = shift; push @{$class->{order_by}}, @_; return scalar( @{$class->{order_by}} ); } ##################################################################### sub limit_offset { my $class = shift; $class->{limit_offset} = shift; } sub limit_value { my $class = shift; $class->{limit_value} = shift; } ##################################################################### sub return { my $class = shift; my $sql; unless (@{$class->{column}}) { croak "column() not defined in SQL::Builder::Select::return"; } unless (@{$class->{table}}) { croak "table() not defined in SQL::Builder::Select::return"; } $sql = 'SELECT ' . join (', ', @{$class->{column}}) . ' FROM ' . join (', ', @{$class->{table}}); push @{$class->{error}}, 'sql column table', $sql; ### DEBUG my $s = $class->return_where(); if (defined $s) { $sql .= ' WHERE ' . $s; push @{$class->{error}}, 'return_where output', $s; ### DEBUG } if (defined $class->{order_by}) { $sql .= ' ORDER BY ' . join (', ', @{$class->{order_by}}); push @{$class->{error}}, 'sql order by', $sql; ### DEBUG } if (defined $class->{limit_value}) { $sql .= ' LIMIT '; if (defined $class->{limit_offset}) { $sql .= $class->{limit_offset} . ', '; } $sql .= $class->{limit_value}; push @{$class->{error}}, 'sql limit', $sql; ### DEBUG } if (defined $class->{debug}) { if (defined $ENV{SERVER_NAME}) { print "Content-type: text/plain\n\n"; $/ = '
'; } if (defined ${$class->{error}}[0]) { print map { $_, $/ } @{$class->{error}}; print $/; } print $sql; exit; } return $sql; } ##################################################################### sub return_where { my $class = shift; if (defined $class->{where_logic}) { my $logic = $class->{where_logic}; if ($logic =~ /^and$/i) { $class->{where_logic} = 'AND'; return $class->_where_and_or(); } elsif ($logic =~ /^or$/i) { $class->{where_logic} = 'OR'; return $class->_where_and_or(); } else { my ($decision, @func); if ($logic =~ /and/i) { $decision = 'AND'; @func = split( /and/i, $logic); } elsif ($logic =~ /or/i) { $decision = 'OR'; @func = split( /or/i, $logic); } else { return; } unless (defined $func[1]) { return; } for ($func[0], $func[1]) { if ($_ =~ /w/i) { push @{$class->{sql}}, $class->_join_values( 'where', $decision ); } elsif ($_ =~ /a/i) { push @{$class->{sql}}, $class->_join_values( 'where_and', 'AND' ); } elsif ($_ =~ /o/i) { push @{$class->{sql}}, $class->_join_values( 'where_or', 'OR' ); } else { return; } } return $class->_join_values( 'sql', $decision ); } } else { $class->{where_logic} = 'AND'; return $class->_where_and_or(); } return; } ##################################################################### sub debug { my $class = shift; if (@_) { my $result = shift; if (defined $result && $result ne '' && $result != 0) { $class->{debug} = 1; } return 1; } elsif (defined $class->{debug} && $class->{debug} == 1) { return 1; } return; } ##################################################################### ##################################################################### sub _where_and_or { my $class = shift; my $logic = $class->{where_logic}; if (defined ${$class->{where}}[0]) { return $class->_join_values( 'where', $logic ); } elsif (defined ${$class->{where_and}}[0]) { return $class->_join_values( 'where_and', 'AND' ); } elsif (defined ${$class->{where_or}}[0]) { return $class->_join_values( 'where_or', 'OR' ); } return; } sub _join_values { my $class = shift; my $name = shift; my $logic = shift if (defined ${$class->{$name}}[0]); if (defined ${$class->{$name}}[1]) { my $s = '(' . join(") $logic (", @{$class->{$name}}) . ')'; return $s; } elsif (defined ${$class->{$name}}[0]) { return @{$class->{$name}}[0]; } return; } 1; #### use SQL::Builder::Select; $select = new SQL::Builder::Select; $select->column('col1', 'col2'); $select->table('table'); $select->order_by('col1'); $select->limit_value('10'); $select->limit_offset('10'); print $select->return(); #### SELECT col1, col2 FROM table ORDER BY col1 LIMIT 10, 10 #### use SQL::Builder::Select; $select = new SQL::Builder::Select; $select->column('*'); $select->table('table'); $select->where_and('col1 = 1', 'col2 = 1'); print $select->return(); #### SELECT * FROM table WHERE (col1 = 1) AND (col2 = 1) #### use SQL::Builder::Select; $select = new SQL::Builder::Select; $select->where_eq_or('col1', 'col2'); $where = $select->return_where(); $select = new SQL::Builder::Select; $select->column('*'); $select->table('table'); $select->where( $where ); $select->where_ne_or('col1', 'col2'); $select->where_logic('w AND o'); print $select->return(); #### SELECT * FROM table WHERE ((col1 = ?) OR (col2 = ?)) AND ((col1 != ?) OR (col2 != ?))