Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/SQLMaker.pm view on Meta::CPAN
{
$self->{sql} .= '(';
$self->{sql} .= $self->_subselect($rhs);
$self->{sql} .= ')';
}
else
{
$self->{sql} .= $self->_rhs($rhs);
}
}
}
sub _rhs
{
my $self = shift;
my $rhs = shift;
if ( Alzabo::Utils::safe_can( $rhs, 'table' ) )
{
unless ( $self->{tables}{ $rhs->table } )
{
my $err = 'Cannot use column (';
$err .= join '.', $rhs->table->name, $rhs->name;
$err .= ") in $self->{type} unless its table is included in the ";
$err .= $self->{type} eq 'update' ? 'UPDATE' : 'FROM';
$err .= ' clause';
Alzabo::Exception::SQL->throw( error => $err );
}
return ( $self->{quote_identifiers} ?
$self->{driver}->quote_identifier( $rhs->table->alias_name, $rhs->name ) :
$rhs->table->alias_name . '.' . $rhs->name );
}
else
{
return $self->_bind_val($rhs);
}
}
sub _subselect
{
my $self = shift;
my $sql = shift;
push @{ $self->{bind} }, @{ $sql->bind };
return $sql->sql;
}
sub order_by
{
my $self = shift;
$self->_assert_last_op( qw( select from condition group_by ) );
Alzabo::Exception::SQL->throw
( error => "Cannot use order by in a '$self->{type}' statement" )
unless $self->{type} eq 'select';
validate_pos( @_, ( { type => SCALAR | OBJECT,
callbacks =>
{ 'column_or_function_or_sort' =>
sub { Alzabo::Utils::safe_can( $_[0], 'table' ) ||
Alzabo::Utils::safe_isa( $_[0], 'Alzabo::SQLMaker::Function' ) ||
$_[0] =~ /^(?:ASC|DESC)$/i } } }
) x @_ );
$self->{sql} .= ' ORDER BY ';
my $x = 0;
my $last = '';
foreach my $i (@_)
{
if ( Alzabo::Utils::safe_can( $i, 'table' ) )
{
unless ( $self->{tables}{ $i->table } )
{
my $err = 'Cannot use column (';
$err .= join '.', $i->table->name, $i->name;
$err .= ") in $self->{type} unless its table is included in the FROM clause";
Alzabo::Exception::SQL->throw( error => $err );
}
# no comma needed for first column
$self->{sql} .= ', ', if $x++;
$self->{sql} .=
( $self->{quote_identifiers} ?
$self->{driver}->quote_identifier( $i->table->alias_name, $i->alias_name ) :
$i->table->alias_name . '.' . $i->alias_name );
$last = 'column';
}
elsif ( Alzabo::Utils::safe_isa( $i, 'Alzabo::SQLMaker::Function' ) )
{
my $string = $i->as_string( $self->{driver}, $self->{quote_identifiers} );
if ( exists $self->{functions}{$string} )
{
$self->{sql} .= ', ', if $x++;
$self->{sql} .= $self->{functions}{$string};
}
else
{
$self->{sql} .= ', ', if $x++;
$self->{sql} .= $string;
}
$last = 'function';
}
else
{
Alzabo::Exception::Params->throw
( error => 'A sort specifier cannot follow another sort specifier in an ORDER BY clause' )
if $last eq 'sort';
$self->{sql} .= " \U$i";
$last = 'sort';
}
}
$self->{last_op} = 'order_by';
( run in 0.663 second using v1.01-cache-2.11-cpan-437f7b0c052 )