DBIx-Class-Async

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

      - Added CI workflow thanks Gabor Szabo.
      - Tidied up pod document.

0.19  2026-01-08
      - Added sub search_related[_rs] to DBIx::Class::Async::ResultSet.

0.18  2026-01-08
      - Added sub delete_all() to DBIx::Class::Async::ResultSet.

0.17  2026-01-08
      - Added sub update_or_[new|create]() to DBIx::Class::Async::ResultSet.

0.16  2026-01-08
      - Added sub find_or_[new|create]() to DBIx::Class::Async::ResultSet.

0.15  2026-01-08
      - Added sub populate() and populate_bulk() to DBIx::Class::Async::ResultSet.

0.14  2026-01-08
      - Added sub slice() to DBIx::Class::Async::ResultSet.

lib/DBIx/Class/Async/ResultSet.pm  view on Meta::CPAN

    my $future = $rs->search({ active => 1 })
                    ->update({
                        last_updated => \'NOW()',
                        metadata     => { version => '2.0', source => 'api' }
                    });

    $future->on_done(sub { say "Batch update complete." });

=cut

sub update {
    my $self = shift;
    my ($cond, $updates);

    # Logic to handle both:
    #   ->update({ col => val })
    #   ->update({ id => 1 }, { col => val })
    if (@_ > 1) {
        ($cond, $updates) = @_;
    } else {
        $updates = shift;

lib/DBIx/Class/Async/ResultSet.pm  view on Meta::CPAN


Example: Safe Batch Update

    $rs->update_all({ last_processed => \'NOW()' })->on_done(sub {
        my $count = shift;
        print "Successfully updated $count specific records.\n";
    });

=cut

sub update_all {
    my ($self, $updates) = @_;
    my $bridge = $self->{_async_db};

    return $self->all->then(sub {
        my $rows = shift;

        # Hard check: is it really an arrayref?
        unless ($rows && ref($rows) eq 'ARRAY' && @$rows) {
            warn "[PID $$] update_all found no rows to update or invalid data type"
                if ASYNC_TRACE;

lib/DBIx/Class/Async/ResultSet.pm  view on Meta::CPAN

            say "Updated existing user: " . $user->id;
        } else {
            say "Prepared new user for registration.";
            # You must call ->insert on the new object to persist it
            return $user->insert;
        }
    });

=cut

sub update_or_new {
    my ($self, $data, $attrs) = @_;
    $attrs //= {};

    # Identify the primary key or unique constraint values for the lookup
    my $lookup = $self->_extract_unique_lookup($data, $attrs);

    return $self->find($lookup, $attrs)->then(sub {
        my ($row) = @_;

        if ($row) {

lib/DBIx/Class/Async/ResultSet.pm  view on Meta::CPAN

        token       => $new_secure_token
    })->on_done(sub {
        my $row = shift;
        say "Token synced for ID: " . $row->id;
    })->on_fail(sub {
        die "Sync failed: " . shift;
    });

=cut

sub update_or_create {
    my ($self, $data, $attrs) = @_;
    $attrs //= {};

    my $lookup = $self->_extract_unique_lookup($data, $attrs);

    return $self->find($lookup, $attrs)->then(sub {
        my ($row) = @_;

        if ($row) {
            # 1. Standard Update Path

lib/DBIx/Class/Async/ResultSet.pm  view on Meta::CPAN

    my ($sql, @bind) = $rs->update_query({ active => 1 });
    # $sql = \'UPDATE users SET active = ? WHERE active = ?'
    # @bind = (1, 0)

    # Audit logging
    warn "About to execute: $$sql with binds: @bind";
    $rs->update({ active => 1 })->get;  # Now execute

=cut

sub update_query {
    my ($self, $values) = @_;

    my $bridge       = $self->{_async_db};
    my $schema_class = $bridge->{_schema_class};

    unless ($schema_class->can('resultset')) {
        eval "require $schema_class" or die "update_query: $@";
    }

    # Silence warnings

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

        }
    }

    # 2. Update state flags
    $self->{_in_storage} = 1;
    delete $self->{_dirty}; # Clear dirty flags

    return $self;
}

sub update {
    my ($self, $values) = @_;

    if (!$self->{_schema_instance}) {
        # Return a failed future to prevent further cascading failures
        return Future->fail("ResultSet is not initialized with a schema instance.");
    }

    unless ($self->in_storage) {
        return Future->fail("Cannot update row: not in storage. Did you mean to call insert or update_or_insert?");
    }

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

        my %pk_cond = map { $_ => $self->get_column($_) } @pk_cols;

        # 4. Now we can safely call _generate_cache_key
        my $cache_key = $rs->_generate_cache_key(0, \%pk_cond);

        $rs->clear_cache($cache_key);
        return $self->_update_internal_state($rs);
    });
}

sub update_or_insert {
    my ($self, $data) = @_;

    my $async_db    = $self->{_async_db};
    my $source_name = $self->{_source_name};
    my $source      = $self->result_source;
    my ($pk_col)    = $source->primary_columns;

    # 1. Apply changes to the object
    if ($data && ref $data eq 'HASH') {
        foreach my $col (keys %$data) {



( run in 0.810 second using v1.01-cache-2.11-cpan-39bf76dae61 )