DBIx-QuickORM

 view release on metacpan or  search on metacpan

lib/DBIx/QuickORM/Row/Async.pm  view on Meta::CPAN

package DBIx::QuickORM::Row::Async;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp();
use Scalar::Util();

use overload (
    'bool' => sub {
        my $s = $_[0];
        return $s->{row} ? 1 : 0 if exists $s->{row};      # already materialized
        return 0 if $s->{invalid};                          # known empty / cancelled
        return 1 unless $s->{async} && $s->{async}->ready;  # still pending: treat as truthy
        return $s->row ? 1 : 0;                             # ready: resolve now
    },
);

=pod

=encoding UTF-8

=head1 NAME

DBIx::QuickORM::Row::Async - Placeholder that swaps itself for a real row once async results arrive.

=head1 DESCRIPTION

A transparent proxy returned for an asynchronous single-row query. It holds an
async statement handle and, once results are ready, materializes the real row
and swaps itself out in place via the C<$_[0]> alias, so callers transparently
end up holding the real row object. Until then it forwards method calls,
C<isa>, C<can>, and C<DOES> to the eventual row's class. If the query returns
no data or is cancelled the proxy becomes invalid: boolean context is false
and method calls croak.

Construction requires an C<async> handle implementing
L<DBIx::QuickORM::Role::Async>. Optional C<auto_refresh> refreshes the row once
materialized; C<state_method> (default C<state_select_row>) and C<state_args>
control how the connection builds the row.

=head1 SYNOPSIS

    my $row = $async_row;       # placeholder, true while pending/valid
    print $row->column;         # swaps in the real row, then forwards

=head1 PUBLIC METHODS

=over 4

=item $bool = $row->isa($class)

True if the eventual row would satisfy the C<isa> check; swaps the proxy out
once results are ready.

=cut

sub isa {
    my ($this, $check) = @_;

    return 1 if $check eq __PACKAGE__;
    return 1 if $check eq 'DBIx::QuickORM::Row';
    return 1 if DBIx::QuickORM::Row->isa($check);

    if (my $class = Scalar::Util::blessed($this)) {

        if ($this->ready) {
            my $a = $_[0];
            $_[0] = $this->swapout;
            return $_[0]->isa($check) unless Scalar::Util::refaddr($a) eq Scalar::Util::refaddr($_[0]);
        }

        return 1 if $check eq $class;

        # Constructors do not reliably supply row_class; guard its use.
        if (my $row_class = $this->{row_class}) {
            return 1 if $check eq $row_class;
            return 1 if $row_class->isa($check);
        }
    }

    return 0;
}

=pod

=item $code = $row->can($method)

Forward C<can> to the eventual row's class; swaps the proxy out once results
are ready.



( run in 1.086 second using v1.01-cache-2.11-cpan-7fcb06a456a )