NAME

DBIx::Class::Async::Row - Asynchronous Row object representing a single database record.

VERSION

Version 0.52

SYNOPSIS

# Rows are typically retrieved via a ResultSet
my $future = $rs->find(1);

$future->on_done(sub {
    my $user = shift;

    # Access columns (non-blocking if pre-inflated)
    say $user->username;

    # Update columns
    $user->last_login('2026-02-02');

    # Persist changes asynchronously
    $user->update->on_done(sub {
        say "User updated!";
    });

    # Traverse relationships (Returns a Future)
    $user->posts->all->on_done(sub {
        my $posts = shift;
        say "User has " . scalar(@$posts) . " posts.";
    });
});

DESCRIPTION

This class provides an asynchronous interface to individual database rows. It maintains internal state regarding "dirty" (unsaved) columns and handles the hand-off to the background worker for all I/O operations.

ATTRIBUTES

in_storage

my $bool = $row->in_storage;
$row->in_storage(1);

Returns or sets whether the row is considered "in the database." Setting this to true clears the "dirty" status of all columns.

PERSISTENCE METHODS

update

$row->update({ status => 'active' })->then(sub { ... });

If the row is in storage, dispatches an UPDATE command to the worker for any modified (dirty) columns. Returns a Future resolving to the updated row object.

delete

$row->delete->on_done(sub { say "Gone!" });

Asynchronously deletes the row from the database using its Primary Key. Upon success, in_storage is set to 0.

discard_changes

$row->discard_changes->then(sub { ... });

Re-fetches the row data from the database, overwriting any local unsaved changes and resetting the "dirty" flag.

copy

$row->copy({ username => 'new_user' })->then(sub { ... });

Creates a new record in the database using the current row's data as a template, excluding Primary Keys unless explicitly provided in the changes hashref.

DATA ACCESSORS

get_column / set_column

my $val = $row->get_column('email');
$row->set_column('email', 'new@example.com');

Standard DBIC-style column accessors. set_column marks the column as "dirty."

get_dirty_columns

my %dirty = $row->get_dirty_columns;

Returns a list of key-value pairs for columns that have been modified but not yet saved to the database.

RELATIONSHIPS

my $rel_rs = $row->related_resultset('posts');

Returns a DBIx::Class::Async::ResultSet for the named relationship, pre-configured with the foreign key join condition.

$row->create_related('posts', { title => 'New Post' });

Shorthand for $row->related_resultset($rel)->create($data).

DESTROY

# Called automatically when object is destroyed

Destructor method.

INTERNAL METHODS

These methods are for internal use and are documented for completeness.

_build_relationship_accessor

my $coderef = $row->_build_relationship_accessor($method, $rel_info);

Builds an accessor for a relationship that checks for prefetched data first, then falls back to lazy loading if needed. For has_many relationships, the ResultSet object is cached in the row.

_ensure_accessors

$row->_ensure_accessors;

Creates accessor methods for all columns in the result source.

_extract_foreign_key

Extracts foreign key mapping from a relationship condition.

_get_primary_key_info

my $pk_info = $row->_get_primary_key_info;

Returns information about the primary key(s) for this row.

Returns

Hash reference with keys:

- columns: Array reference of primary key column names - count: Number of primary key columns - is_composite: Boolean indicating composite primary key

_get_source

my $source = $row->_get_source;

Returns the result source for this row, loading it lazily if needed.

PERFORMANCE OPTIMISATIONS

  • Shadow Keys

    For performance, non-inflated columns are shadowed directly onto the object hash, allowing for fast access without method calls.

  • Inflation Map

    The object maintains an internal _inflation_map to avoid repeated metadata lookups against the ResultSource.

  • Warm-up

    The constructor pre-calculates metadata to ensure the first data access is as fast as subsequent ones.