NAME

DBIx::QuickORM::Connection::RowData - Per-row state tracked across a transaction stack.

DESCRIPTION

Holds the mutable state behind a single row for one connection: the stored (as-fetched) data, pending (unsaved) changes, and a desync map flagging fields whose stored value changed underneath a pending edit. The state is kept as a stack of frames keyed by transaction, so that committing or rolling back a transaction merges or discards the right frame.

The frame stack always mirrors the connection's transaction nesting: when a state frame is pushed for a transaction, carrier frames are inserted for any open transactions between the current frame's transaction and the new one, each starting as a copy of the data beneath it. When a transaction commits, its frame merges into the frame immediately below it (and no further), so data committed inside a savepoint is still discarded if an enclosing transaction later rolls back.

A row becomes invalid when the transaction it was created in rolls back, or when explicitly invalidated; an invalid row has an empty stack and a reason.

The state-frame keys (STORED, PENDING, DESYNC, TRANSACTION, ROW_DATA) are available as exported constants.

SYNOPSIS

my $data = DBIx::QuickORM::Connection::RowData->new(
    source     => $source,
    connection => $connection,
);

my $stored  = $data->stored_data;
my $pending = $data->pending_data;

ATTRIBUTES

connection

The owning DBIx::QuickORM::Connection, stored internally as a coderef and returned resolved by the connection method.

source

The row's source object (consumes DBIx::QuickORM::Role::Source), stored internally as a coderef and returned resolved by the source method.

stack

Arrayref of state frames, newest first. Empty when the row is invalid.

invalid

The reason string when the row has been invalidated.

EXPORTS

Nothing is exported by default. The following state-frame key constants may be imported by name:

STORED
PENDING
DESYNC
TRANSACTION
ROW_DATA

PUBLIC METHODS

$bool = $data->valid

True when the row has a live active state.

$reason = $data->invalid

False when the row is valid, otherwise the invalidation reason string.

$data->invalidate(reason => $why)

Marks the row invalid with the given reason (defaulting to the call site), clears the state stack, and warns if pending data was discarded.

$source = $data->source

The resolved source object.

$connection = $data->connection

The resolved connection object.

$href = $data->stored_data
$href = $data->pending_data
$href = $data->desync_data
$txn = $data->transaction

The respective fields of the active state frame.

$frame = $data->active
$frame = $data->active(no_fatal => 1)

Returns the active (top) state frame, first resolving the stack: a frame whose transaction rolled back is discarded, a frame whose transaction committed is merged into the frame immediately below it. Confesses when the row is invalid unless no_fatal is set, in which case it returns nothing.

$data->change_state($state)

Applies a new state frame: merges it into the active frame when they share a transaction (or neither has one), otherwise pushes it as a new frame. Croaks when asked to merge down a rolled-back transaction.

PUBLIC METHODS

$bool = $data->compare_field($field, \%a, \%b)

Returns true when the named field compares equal between two field hashes, using the field's type comparator when one exists and otherwise comparing by affinity. Treats existence and definedness mismatches as unequal.

PRIVATE METHODS

$data->_up_state($state)

Pushes a new state frame onto the stack. When the state carries a transaction, carrier frames are first inserted for any open transactions between the current top frame and the new one, and the new frame starts as a copy of the data beneath it with the state merged in. Croaks when there is already a base state and the new frame carries no transaction.

$data->_fill_frames($txn)

Insert carrier frames for every open transaction between the current top frame's transaction and $txn, so the stack mirrors the connection's transaction nesting.

$frame = $data->_carry_frame($txn)

Build a new frame owned by $txn carrying a shallow copy of the data in the current top frame (if any).

$data->_merge_state($merge, $into)

Merges the $merge state frame into the $into frame, reconciling stored, pending, and desync fields.

SOURCE

The source code repository for DBIx::QuickORM can be found at https://github.com/exodist/DBIx-QuickORM.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright Chad Granum <exodist7@gmail.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See https://dev.perl.org/licenses/