no warnings 'redefine';

# {{{ sub LimitAttribute

=head2 LimitAttribute PARAMHASH

Takes NAME, OPERATOR and VALUE to find records that has the
matching Attribute.

=cut

my %Negate = qw(
    =		!=
    !=		=
    >		<=
    <		>=
    >=		<
    <=		>
    LIKE	NOT LIKE
    NOT LIKE	LIKE
    IS		IS NOT
    IS NOT	IS
);

sub LimitAttribute {
    my ($self, %args) = @_;
    my $clause = 'ALIAS';
    my $operator = ($args{OPERATOR} || '=');
    
    if ($args{NULL} and exists $args{VALUE}) {
	$clause = 'LEFTJOIN';
	$operator = $Negate{$operator};
    }
    elsif ($args{NEGATE}) {
	$operator = $Negate{$operator};
    }
    
    my $alias = $self->Join(
	TYPE   => 'left',
	ALIAS1 => $args{ALIAS} || 'main',
	FIELD1 => 'id',
	TABLE2 => 'Attributes',
	FIELD2 => 'ObjectId'
    );

    my $type = ref($self);
    $type =~ s/(?:s|Collection)$//; # XXX - Hack!

    $self->Limit(
	$clause	   => $alias,
	FIELD      => 'ObjectType',
	OPERATOR   => '=',
	VALUE      => $type,
    );
    $self->Limit(
	$clause	   => $alias,
	FIELD      => 'Name',
	OPERATOR   => '=',
	VALUE      => $args{NAME},
    ) if exists $args{NAME};

    return unless exists $args{VALUE};

    $self->Limit(
	$clause	   => $alias,
	FIELD      => 'Description',
	OPERATOR   => $operator,
	VALUE      => $args{VALUE},
    );

    # Capture rows with the attribute defined as an empty string.
    $self->Limit(
	$clause    => $alias,
	FIELD      => 'Description',
	OPERATOR   => $args{NULL} ? '!=' : '=',
	VALUE      => '',
	ENTRYAGGREGATOR => $args{NULL} ? 'AND' : 'OR',
    ) if $args{EMPTY};

    # Capture rows without the attribute defined
    $self->Limit(
	%args,
	ALIAS      => $alias,
	FIELD	   => 'id',
	OPERATOR   => ($args{NEGATE} ? 'IS NOT' : 'IS'),
	VALUE      => 'NULL',
    ) if $args{NULL};
}
# }}}

sub OrderByAttribute {
    my ($self, %args) = @_;
    
    my $alias = $self->Join(
	TYPE   => 'left',
	ALIAS1 => 'main',
	FIELD1 => 'id',
	TABLE2 => 'Attributes',
	FIELD2 => 'ObjectId'
    );

    my $type = ref($self);
    $type =~ s/(?:s|Collection)$//; # XXX - Hack!

    $self->Limit(
	ALIAS	   => $alias,
	FIELD      => 'ObjectType',
	OPERATOR   => '=',
	VALUE      => $type,
    );
    $self->Limit(
	ALIAS	   => $alias,
	FIELD      => 'Name',
	OPERATOR   => '=',
	VALUE      => $args{NAME},
    ) if exists $args{NAME};

    my $field = 'Description';
    if ($args{NUMERIC}) {
	$field = (
	    (eval { $self->_Handle->dbh->{Driver}{Name} } eq 'Pg')
		? 'INT8' : 'ROUND'
	) . "($field)";
    }

    $self->OrderBy(
	ALIAS	   => $alias,
	FIELD      => $field,
	ORDER      => $args{ORDER},
    );
}
# }}}

1;
