NAME

DBIx::Class::Async::Row - Asynchronous row object for DBIx::Class::Async

VERSION

Version 0.22

SYNOPSIS

use DBIx::Class::Async::Row;

# Typically created by DBIx::Class::Async, not directly
my $row = DBIx::Class::Async::Row->new(
    schema      => $schema,
    async_db    => $async_db,
    source_name => 'User',
    row_data    => { id => 1, name => 'John', email => 'john@example.com' },
);

# Access columns
my $name = $row->name;  # Returns 'John'
my $email = $row->get_column('email');  # Returns 'john@example.com'

# Get all columns
my %columns = $row->get_columns;

# Update asynchronously
$row->update({ name => 'John Doe' })->then(sub {
    my ($updated_row) = @_;
    say "Updated: " . $updated_row->name;
});

# Delete asynchronously
$row->delete->then(sub {
    my ($success) = @_;
    say "Deleted: " . ($success ? 'yes' : 'no');
});

# Discard changes and refetch from database
$row->discard_changes->then(sub {
    my ($fresh_row) = @_;
    # $fresh_row contains latest data from database
});

DESCRIPTION

DBIx::Class::Async::Row provides an asynchronous row object that represents a single database row in a DBIx::Class::Async application. It mimics the interface of DBIx::Class::Row but returns Future objects for asynchronous database operations.

This class is typically instantiated by DBIx::Class::Async and not directly by users. It provides both synchronous column access and asynchronous methods for database operations.

CONSTRUCTOR

new

my $row = DBIx::Class::Async::Row->new(
    schema      => $schema,            # DBIx::Class::Schema instance
    async_db    => $async_db,          # DBIx::Class::Async instance
    source_name => $source_name,       # Result source name
    row_data    => \%data,             # Hashref of row data
);

Creates a new asynchronous row object.

Parameters
schema

A DBIx::Class::Schema instance. Required.

async_db

A DBIx::Class::Async instance. Required.

source_name

The name of the result source (table). Required.

row_data

Hash reference containing the row's column data. Required.

Throws
  • Croaks if any required parameter is missing.

METHODS

get_column

my $value = $row->get_column($column_name);

Synchronously retrieves a column value from the row.

Parameters
$column_name

Name of the column to retrieve.

Returns

The column value. If the column has an inflator defined, returns the inflated value.

Throws

Croaks if the column doesn't exist.

get_columns

my %columns = $row->get_columns;

Returns all columns as a hash.

Returns

Hash containing all column names and values.

get_inflated_columns

my %inflated_columns = $row->get_inflated_columns;

Returns all columns with inflated values where applicable.

Returns

Hash containing all column names and inflated values.

update

$row->update({ column1 => $value1, column2 => $value2 })
    ->then(sub {
        my ($updated_row) = @_;
        # Handle updated row
    })
    ->catch(sub {
        my ($error) = @_;
        # Handle error
    });

Asynchronously updates the row in the database.

Parameters
$data

Hash reference containing column-value pairs to update.

Returns

A Future that resolves to the updated row object.

Throws
  • Croaks if $data is not a hash reference.

  • Croaks if the row is not in storage.

delete

$row->delete
    ->then(sub {
        my ($success) = @_;
        if ($success) {
            say "Row deleted successfully";
        }
    })
    ->catch(sub {
        my ($error) = @_;
        # Handle error
    });

Asynchronously deletes the row from the database.

Returns

A Future that resolves to true if the row was deleted, false otherwise.

Throws

Croaks if the row doesn't have a primary key.

discard_changes

$row->discard_changes
    ->then(sub {
        my ($fresh_row) = @_;
        # Row now contains latest data from database
    })
    ->catch(sub {
        my ($error) = @_;
        # Handle error
    });

Discards any local changes and refetches the row from the database.

Returns

A Future that resolves to the row object with fresh data.

Throws
  • Croaks if the row doesn't have a primary key.

in_storage

if ($row->in_storage) {
    # Row exists in database
}

Checks whether the row exists in the database.

Returns

True if the row is in storage (has a primary key and hasn't been deleted), false otherwise.

result_source

my $source = $row->result_source;

Returns the DBIx::Class::ResultSource for this row.

Returns

The result source object, or undef if not available.

my $rs = $row->related_resultset($relationship_name);

Returns a resultset for a related table.

Parameters
$relationship_name

Name of the relationship as defined in the result class.

Returns

A DBIx::Class::ResultSet for the related table, filtered by the relationship condition.

Throws
  • Croaks if the relationship doesn't exist.

  • Croaks if the relationship condition cannot be parsed.

insert

$row->insert
    ->then(sub {
        my ($inserted_row) = @_;
        # Row has been inserted
    });

Asynchronously inserts the row into the database.

Note: This method is typically called automatically by "create" in DBIx::Class::Async. For existing rows, it returns an already-resolved Future.

Returns

A Future that resolves to the row object.

my $post_future = $user->create_related('posts', {
    title   => 'My First Post',
    content => 'Hello World!'
});

my $post = await $post_future;

A convenience method that creates a new record in the specified relationship.

It internally calls related_resultset to identify the correct foreign key mapping (e.g., setting user_id to the current user's ID) and then invokes create on the resulting ResultSet.

This method returns a Future that resolves to a new Row object of the related type.

Note: Just like "create" in DBIx::Class::Async::ResultSet, this method automatically merges the relationship's foreign key constraints into the provided hashref, ensuring that NOT NULL constraints on the foreign key columns are satisfied.

AUTOLOAD METHODS

Called automatically for column and relationship access

my $value = $row->column_name;
my $related = $row->relationship_name;

Handles dynamic method dispatch for columns and relationships.

The class uses AUTOLOAD to provide dynamic accessors for:

  • Column values (e.g., $row->name for column 'name')

  • Relationship accessors (e.g., $row->orders for 'orders' relationship)

Relationship results are cached in the object after first access.

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.

SEE ALSO

AUTHOR

Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>

REPOSITORY

https://github.com/manwar/DBIx-Class-Async

BUGS

Please report any bugs or feature requests through the web interface at https://github.com/manwar/DBIx-Class-Async/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc DBIx::Class::Async::Row

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright (C) 2026 Mohammad Sajid Anwar.

This program is free software; you can redistribute it and / or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:

http://www.perlfoundation.org/artistic_license_2_0

Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License.By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made by someone other than you,you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement,then this Artistic License to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.