package DBIx::Romani::Query::Select; use DBIx::Romani::Query::Select::Result; use DBIx::Romani::Query::Select::Join; use DBIx::Romani::Query::Select::OrderBy; use strict; sub new { my $class = shift; my $args = shift; my $self = { from => [], result => [], where => undef, join => undef, group_by => [], order_by => [], limit => undef, offset => undef, distinct => 0, }; bless $self, $class; return $self; } sub get_from { return shift->{from}; } sub get_result { return shift->{result}; } sub get_where { return shift->{where}; } sub get_group_by { return shift->{group_by}; } sub get_order_by { return shift->{order_by}; } sub get_join { return shift->{join}; } sub get_limit { return shift->{limit}; } sub get_offset { return shift->{offset}; } sub get_distinct { return shift->{distinct}; } sub clear_from { shift->{from} = [ ]; } sub clear_result { shift->{result} = [ ]; } sub clear_where { shift->{where} = undef; } sub clear_group_by { shift->{group_by} = [ ]; } sub clear_order_by { shift->{order_by} = [ ]; } sub clear_limit { my $self = shift; # must clear both for sanity $self->{limit} = undef; $self->{offset} = undef; } sub add_from { my ($self, $table_name) = @_; foreach my $other ( @{$self->get_from()} ) { if ( $table_name eq $other ) { # don't add it twice!! return; } } push @{$self->{from}}, $table_name; } sub add_result { my $self = shift; my $result = DBIx::Romani::Query::Select::Result->new( @_ ); my $name = $result->get_name(); if ( defined $name ) { my @temp = grep { $_->get_name() eq $name } @{$self->{result}}; if ( scalar @temp > 0 ) { die "Cannot add two results with the same name"; } } push @{$self->{result}}, $result; } sub add_group_by { my ($self, $result) = @_; push @{$self->{group_by}}, $result; } sub add_order_by { my $self = shift; my $order_by = DBIx::Romani::Query::Select::OrderBy->new( @_ ); push @{$self->{order_by}}, $order_by; } sub set_where { my ($self, $where) = @_; $self->{where} = $where; } sub set_join { my $self = shift; my $join = DBIx::Romani::Query::Select::Join->new( @_ ); $self->{join} = $join; } sub set_limit { my ($self, $limit, $offset) = @_; $self->{limit} = $limit; $self->{offset} = $offset; } sub set_distinct { my ($self, $distinct) = @_; $self->{distinct} = $distinct; } sub visit { my ($self, $visitor) = @_; return $visitor->visit_select( $self ); } sub clone { my $self = shift; my $query = DBIx::Romani::Query::Select->new(); # from foreach my $from ( @{$self->get_from()} ) { $query->add_from( $from ); } # result foreach my $result ( @{$self->get_result()} ) { # A little non-standard push @{$query->{result}}, $result->clone(); } # where if ( defined $query->get_where() ) { $query->set_where( $query->get_where()->clone() ); } # join if ( defined $query->get_join() ) { $query->set_join( $query->get_join()->clone() ); } # group by foreach my $group_by ( @{$self->get_group_by()} ) { $query->add_group_by( $group_by ); } # order by foreach my $order_by ( @{$self->get_order_by()} ) { $query->add_order_by( $order_by ); } return $query; } 1;