Fey::Role::SetOperation - A role for things that are a set operation


Fey documentation Contained in the Fey distribution.

Index


Code Index:

NAME

Top

Fey::Role::SetOperation - A role for things that are a set operation

VERSION

Top

version 0.40

SYNOPSIS

Top

  use Moose;

  with 'Fey::Role::SetOperation' => { keyword => $keyword };

DESCRIPTION

Top

Classes which do this role represent a query which can include multiple SELECT queries or set operations.

PARAMETERS

Top

keyword

The SQL keyword for this set operation (i.e. UNION, INTERSECT, EXCEPT).

METHODS

Top

This role provides the following methods, where $keyword is the keyword parameter, above:

$query->$keyword()

  $union->union($select1, $select2, $select3);

  $union->union($select, $except->except($select2, $select3));

Adds SELECT queries or set operations to the list of queries that this set operation includes.

A set operation must include at least two queries, so the first time this is called, at least two arguments must be provided; subsequent calls do not suffer this constraint.

$query->all()

Sets whether or not ALL is included in the SQL for this set operation (e.g. UNION ALL).

$query->is_all()

Returns true if $query->all() has previously been called.

$query->keyword_clause()

Returns the SQL keyword and possible ALL for this set operation.

$query->${keyword}_clause()

  print $query->union_clause();

Returns each of the selects for this set operation, joined by the keyword_clause.

ROLES

Top

This class includes Fey::Role::SQL::HasOrderByClause, Fey::Role::SQL::HasLimitClause, and Fey::Role::SQL::HasAliasName.

BUGS

Top

See Fey for details on how to report bugs.

AUTHOR

Top

Dave Rolsky <autarch@urth.org>

COPYRIGHT AND LICENSE

Top


Fey documentation Contained in the Fey distribution.

package Fey::Role::SetOperation;
BEGIN {
  $Fey::Role::SetOperation::VERSION = '0.40';
}

use strict;
use warnings;
use namespace::autoclean;

use Fey::Types qw( ArrayRef Bool SetOperationArg Str );

use MooseX::Role::Parameterized;
use MooseX::Params::Validate qw( pos_validated_list );

parameter keyword => (
    isa      => Str,
    required => 1,
);

with 'Fey::Role::Comparable',
    'Fey::Role::SQL::HasOrderByClause',
    'Fey::Role::SQL::HasLimitClause',
    'Fey::Role::SQL::ReturnsData';

has 'is_all' => (
    is      => 'rw',
    isa     => Bool,
    default => 0,
    writer  => '_set_is_all',
);

has '_set_elements' => (
    traits  => ['Array'],
    is      => 'bare',
    isa     => ArrayRef[SetOperationArg],
    default => sub { [] },
    handles => {
        _add_set_elements  => 'push',
        _set_element_count => 'count',
        _set_elements      => 'elements',
    },
    init_arg => undef,
);

sub id {
    return $_[0]->sql('Fey::FakeDBI');
}

sub all {
    $_[0]->_set_is_all(1);
    return $_[0];
}

sub bind_params {
    my $self = shift;
    return map { $_->bind_params } $self->_set_elements();
}

sub select_clause_elements {
    return ( $_[0]->_set_elements() )[0]->select_clause_elements();
}

role {
    my $p     = shift;
    my %extra = @_;

    my $name = lc $p->keyword();

    method 'keyword_clause' => sub {
        my $self = shift;

        my $sql = uc($name);
        $sql .= ' ALL' if $self->is_all();
        return $sql;
    };

    my $clause_method = $name . '_clause';

    method 'sql' => sub {
        my $self = shift;
        my $dbh  = shift;

        return (
            join q{ },
            $self->$clause_method($dbh),
            $self->order_by_clause($dbh),
            $self->limit_clause($dbh),
        );
    };

    method $name => sub {
        my $self = shift;

        my $count = @_;
        $count = 2
            if $count < 2 && $self->_set_element_count() < 2;

        my (@set) = pos_validated_list(
            \@_,
            ( ( { isa => SetOperationArg } ) x $count ),
            MX_PARAMS_VALIDATE_NO_CACHE => 1,
        );

        $self->_add_set_elements(@set);

        return $self;
    };

    method $clause_method => sub {
        my $self = shift;
        my $dbh  = shift;

        return (
            join q{ } . $self->keyword_clause($dbh) . q{ },
            map { '(' . $_->sql($dbh) . ')' } $self->_set_elements()
        );
    };

    with 'Fey::Role::HasAliasName' => {
        generated_alias_prefix => uc $name,
        sql_needs_parens       => 1,
    };
};

1;

# ABSTRACT: A role for things that are a set operation




__END__