Aniki

 view release on metacpan or  search on metacpan

lib/Aniki/Plugin/SelectJoined.pm  view on Meta::CPAN

package Aniki::Plugin::SelectJoined;
use 5.014002;

use namespace::autoclean;
use Mouse::Role;
use Aniki::QueryBuilder;
use Aniki::Result::Collection::Joined;
use Carp qw/croak/;

requires qw/schema query_builder suppress_row_objects txn_manager execute/;

Aniki::QueryBuilder->load_plugin('JoinSelect');

sub select_joined {
    my ($self, $base_table, $join_conditions, $where, $opt) = @_;
    croak '(Aniki::Plugin::SelectJoined#select_joined) `where` condition must be a reference.' unless ref $where;

    my @table_names = ($base_table);
    for (my $i = 0; my $table = $join_conditions->[$i]; $i += 2) {
        push @table_names => $table;
    }
    my @tables = map { $self->schema->get_table($_) } @table_names;

    my $name_sep = $self->query_builder->name_sep;
    my @columns;
    for my $table (@tables) {
        my $table_name = $table->name;
        push @columns =>
            map { "$table_name$name_sep$_" }
            map { $_->name } $table->get_fields();
    }

    my ($sql, @bind) = $self->query_builder->join_select($base_table, $join_conditions, \@columns, $where, $opt);
    return $self->select_joined_by_sql($sql, \@bind, {
        table_names => \@table_names,
        columns     => \@columns,
        %$opt,
    });
}

sub select_joined_by_sql {
    my ($self, $sql, $bind, $opt) = @_;
    $opt //= {};

    my $table_names = $opt->{table_names} or croak 'table_names is required';
    my $columns     = $opt->{columns}     or croak 'columns is required';
    my $prefetch    = exists $opt->{prefetch} ? $opt->{prefetch} : {};

    my $prefetch_enabled_fg = %$prefetch && !$self->suppress_row_objects;
    if ($prefetch_enabled_fg) {
        my $txn; $txn = $self->txn_scope unless $self->txn_manager->in_transaction;

        my $sth = $self->execute($sql, @$bind);
        my $result = $self->_fetch_joined_by_sth($sth, $table_names, $columns);

        for my $table_name (@$table_names) {
            my $rows  = $result->rows($table_name);
            my $prefetch = $prefetch->{$table_name};
               $prefetch = [$prefetch] if ref $prefetch eq 'HASH';
            $self->fetch_and_attach_relay_data($table_name, $prefetch, $rows);
        }

        $txn->rollback if defined $txn; ## for read only
        return $result;



( run in 2.193 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )