DBIx-QuickORM

 view release on metacpan or  search on metacpan

lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/confess croak carp/;
use Scalar::Util qw/blessed weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Handle;
use DBIx::QuickORM::Connection::Transaction;

use Object::HashBase qw{
    <orm
    <dbh
    <dialect
    <pid

lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

        # move a blessed manager to a new connection.
        if (my $other = $manager->connection) {
            croak "This row_manager instance is already in use by another live connection; one row_manager cannot be shared across connections. Pass a class name (each connection builds its own manager), pass a fresh instance per connection, or disco...
                if $other != $self && $other->manager && $other->manager == $manager && $other->connected;
        }

        $manager->set_connection($self);

        # The HashBase setter stores a strong reference, which would create a
        # connection <-> manager cycle; the manager holds its connection weakly.
        weaken($manager->{DBIx::QuickORM::RowManager::CONNECTION()});

        $manager->set_transactions($txns);
    }
    else {
        my $class = load_class($manager) or die $@;
        $self->{+MANAGER} = $class->new(transactions => $txns, connection => $self);
    }

    if (my $autofill = $orm->autofill) {
        # Tables asserted to have no volatile columns (so the introspection

lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN


=cut

sub set_async {
    my $self = shift;
    my ($async) = @_;

    croak "There is already an async query in progress" if $self->{+IN_ASYNC} && !$self->{+IN_ASYNC}->done;

    $self->{+IN_ASYNC} = $async;
    weaken($self->{+IN_ASYNC});

    return $async;
}

sub add_aside {
    my $self = shift;
    my ($aside) = @_;

    $self->{+ASIDES}->{$aside} = $aside;
    weaken($self->{+ASIDES}->{$aside});

    return $aside;
}

sub add_fork {
    my $self = shift;
    my ($fork) = @_;

    $self->{+FORKS}->{$fork} = $fork;
    weaken($self->{+FORKS}->{$fork});

    return $fork;
}

sub clear_async {
    my $self = shift;
    my ($async) = @_;

    # A reconnect drops the async registry; a handle that survived it (it ran on
    # the now-dead handle) can still try to clear itself as it finalizes. Treat a

lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

        savepoint     => $sp,
        trace         => \@caller,
        on_fail       => $params{on_fail},
        on_success    => $params{on_success},
        on_completion => $params{on_completion},
    );

    $self->_txn_attach_relative_callbacks($txn, \%params);

    push @{$txns} => $txn;
    weaken($txns->[-1]);

    my $finalize = $self->_txn_finalizer($sp);

    unless($cb) {
        $txn->set_no_last(1);
        $txn->set_finalize($finalize);
        return $txn;
    }

    local $@;

lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection::Transaction;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/croak confess/;
use Scalar::Util qw/weaken/;

use Object::HashBase qw{
    <id
    +connection
    +savepoint

    +on_success
    +on_fail
    +on_completion

lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN

normalizes the callback queues. Not called directly.

=cut

sub init {
    my $self = shift;

    croak "A transaction ID is required" unless $self->{+ID};

    # Hold the connection weakly. The connection holds its transactions weakly in
    # turn, so this back-reference does not create a strong cycle; weakening it
    # keeps a transaction from pinning its connection alive and from dragging the
    # whole connection into a dump or deep comparison of the txn.
    weaken($self->{+CONNECTION}) if $self->{+CONNECTION};

    $self->{+RESULT} = undef;

    $self->{+ON_SUCCESS}    = [$self->{+ON_SUCCESS}]    if 'CODE' eq ref($self->{+ON_SUCCESS});
    $self->{+ON_FAIL}       = [$self->{+ON_FAIL}]       if 'CODE' eq ref($self->{+ON_FAIL});
    $self->{+ON_COMPLETION} = [$self->{+ON_COMPLETION}] if 'CODE' eq ref($self->{+ON_COMPLETION});
}

=pod

lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/carp confess croak/;
use Scalar::Util qw/weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Connection::RowData qw{
    STORED
    PENDING
    DESYNC
    TRANSACTION
    ROW_DATA
};

lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

=back

=cut

sub init {
    my $self = shift;

    my $con = $self->{+CONNECTION} or croak "Connection was not provided";
    $self->{+TRANSACTIONS} //= $con->transactions;

    weaken($self->{+CONNECTION});
}

=pod

=head1 PUBLIC METHODS

=over 4

=item $bool = $mgr->does_cache

lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager::Cached;
use strict;
use warnings;

our $VERSION = '0.000028';

use Scalar::Util qw/weaken/;

use parent 'DBIx::QuickORM::RowManager';
use Object::HashBase qw {
    +cache
    +sweep
};

use constant SWEEP_FLOOR => 8;

=pod

lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

        my $old_key = $self->cache_key($old_pk);
        delete $scache->{$old_key} if defined $old_key;
    }

    $new_pk //= [$row->primary_key_value_list];
    my $new_key = $self->cache_key($new_pk) // return $row;

    $self->_purge_dead($scache) if exists $scache->{$new_key} && !defined $scache->{$new_key};

    $scache->{$new_key} = $row;
    weaken($scache->{$new_key});

    $self->_maybe_sweep($source, $scache);

    return $row;
}

=pod

=item $row = $mgr->uncache($source, $row, $old_pk, $new_pk)

t/AI/reconnect_clear.t  view on Meta::CPAN

    my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
    $dbh->do('CREATE TABLE users (user_id INTEGER PRIMARY KEY, name TEXT NOT NULL)');
    $dbh->disconnect;
}

my $con = DBIx::QuickORM->quick(credentials => {dsn => $dsn});

# Stand-ins for surviving statement handles. clear_async/clear_aside/clear_fork
# only do registry bookkeeping (a lookup/compare and a delete); they never call
# methods on the handle, so a bare blessed ref is enough. Strong refs are held
# so the weakened registry entries do not vanish before reconnect.
my $async = bless {}, 'My::Surviving::Handle';
my $aside = bless {}, 'My::Surviving::Handle';
my $fork  = bless {}, 'My::Surviving::Handle';

$con->set_async($async);
$con->add_aside($aside);
$con->add_fork($fork);

$con->reconnect;

t/handle/first.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

t/handle/first.t  view on Meta::CPAN

    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    is($row->field('id'), 1, "Got generated primary key");

    my $row_clone = $h->first({id => 1});
    ref_is($row_clone, $row, "Got the same ref using first({id => 1})");

    my $row_clone2 = $h->first(id => 1);
    ref_is($row_clone2, $row, "Got the same ref using first(id => 1)");

    my $weak = $row;
    weaken($weak);
    $row        = undef;
    $row_clone  = undef;
    $row_clone2 = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");

    $row = $h->first({name => 'a'});
    is($row->field('id'), 1, "Got the right ID");

    my $data = $h->data_only->first({id => 1});
    ref_ok($data, 'HASH', "Got a hashref");

t/handle/one.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

t/handle/one.t  view on Meta::CPAN

    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    is($row->field('id'), 1, "Got generated primary key");

    my $row_clone = $h->one({id => 1});
    ref_is($row_clone, $row, "Got the same ref using one({id => 1})");

    my $row_clone2 = $h->one(id => 1);
    ref_is($row_clone2, $row, "Got the same ref using one(id => 1)");

    my $weak = $row;
    weaken($weak);
    $row        = undef;
    $row_clone  = undef;
    $row_clone2 = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");

    $row = $h->one({name => 'a'});
    is($row->field('id'), 1, "Got the right ID");

    my $data = $h->data_only->one({id => 1});
    ref_ok($data, 'HASH', "Got a hashref");

t/handle/update.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

t/handle/update.t  view on Meta::CPAN


    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    ref_is($h->one({id => 1}), $row, "Can fetch row");
    is($row->field('id'), 1, "Got generated primary key");
    ok($row->in_storage, "stored");

    $row->update({name => 'b'});
    is($row->field('name'), 'b', "Got new value");

    my $weak = $row;
    weaken($weak);
    $row = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");
    $row = $h->one({id => 1});
    is($row->field('name'), 'b', "Got new value");

    $row = undef;

    $h->handle(where => {name => 'b'})->update({name => 'c'});
    $row = $h->one({id => 1});
    is($row->field('name'), 'c', "Got new value");

t/omit.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {
        dialect curdialect();
        db_name 'quickdb';

t/omit.t  view on Meta::CPAN

    };

    ok(my $orm = orm('my_orm')->connect, "Got a connection");
    ok(my $row = $orm->handle('example')->insert({name => 'a', data => {foo => 'bar'}}), "Inserted a row");
    ok($orm->schema->{tables}->{example}->{columns}->{data}->{omit}, "omit was merged into the autofill schema");
    $row = undef; $row = $orm->handle('example')->one(name => 'a');
    ok(!exists($row->row_data->{stored}->{data}), "did not fetch data");

    is($row->field('data'), {foo => 'bar'}, "Can fetch data");
    my $weak = $row;
    weaken($weak);
    $row = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");
    $row = $orm->handle('example')->one({name => 'a'});

    ok($row, "got row");
    ok(!exists($row->row_data->{stored}->{data}), "did not fetch data");

    $row = undef;

    $row = $orm->handle('example')->omit(['name'])->one({name => 'a'});

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/confess croak carp/;
use Scalar::Util qw/blessed weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Handle;
use DBIx::QuickORM::Connection::Transaction;

use Object::HashBase qw{
    <orm
    <dbh
    <dialect
    <pid

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

        # move a blessed manager to a new connection.
        if (my $other = $manager->connection) {
            croak "This row_manager instance is already in use by another live connection; one row_manager cannot be shared across connections. Pass a class name (each connection builds its own manager), pass a fresh instance per connection, or disco...
                if $other != $self && $other->manager && $other->manager == $manager && $other->connected;
        }

        $manager->set_connection($self);

        # The HashBase setter stores a strong reference, which would create a
        # connection <-> manager cycle; the manager holds its connection weakly.
        weaken($manager->{DBIx::QuickORM::RowManager::CONNECTION()});

        $manager->set_transactions($txns);
    }
    else {
        my $class = load_class($manager) or die $@;
        $self->{+MANAGER} = $class->new(transactions => $txns, connection => $self);
    }

    if (my $autofill = $orm->autofill) {
        # Tables asserted to have no volatile columns (so the introspection

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN


=cut

sub set_async {
    my $self = shift;
    my ($async) = @_;

    croak "There is already an async query in progress" if $self->{+IN_ASYNC} && !$self->{+IN_ASYNC}->done;

    $self->{+IN_ASYNC} = $async;
    weaken($self->{+IN_ASYNC});

    return $async;
}

sub add_aside {
    my $self = shift;
    my ($aside) = @_;

    $self->{+ASIDES}->{$aside} = $aside;
    weaken($self->{+ASIDES}->{$aside});

    return $aside;
}

sub add_fork {
    my $self = shift;
    my ($fork) = @_;

    $self->{+FORKS}->{$fork} = $fork;
    weaken($self->{+FORKS}->{$fork});

    return $fork;
}

sub clear_async {
    my $self = shift;
    my ($async) = @_;

    # A reconnect drops the async registry; a handle that survived it (it ran on
    # the now-dead handle) can still try to clear itself as it finalizes. Treat a

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

        savepoint     => $sp,
        trace         => \@caller,
        on_fail       => $params{on_fail},
        on_success    => $params{on_success},
        on_completion => $params{on_completion},
    );

    $self->_txn_attach_relative_callbacks($txn, \%params);

    push @{$txns} => $txn;
    weaken($txns->[-1]);

    my $finalize = $self->_txn_finalizer($sp);

    unless($cb) {
        $txn->set_no_last(1);
        $txn->set_finalize($finalize);
        return $txn;
    }

    local $@;

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection::Transaction;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/croak confess/;
use Scalar::Util qw/weaken/;

use Object::HashBase qw{
    <id
    +connection
    +savepoint

    +on_success
    +on_fail
    +on_completion

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN

normalizes the callback queues. Not called directly.

=cut

sub init {
    my $self = shift;

    croak "A transaction ID is required" unless $self->{+ID};

    # Hold the connection weakly. The connection holds its transactions weakly in
    # turn, so this back-reference does not create a strong cycle; weakening it
    # keeps a transaction from pinning its connection alive and from dragging the
    # whole connection into a dump or deep comparison of the txn.
    weaken($self->{+CONNECTION}) if $self->{+CONNECTION};

    $self->{+RESULT} = undef;

    $self->{+ON_SUCCESS}    = [$self->{+ON_SUCCESS}]    if 'CODE' eq ref($self->{+ON_SUCCESS});
    $self->{+ON_FAIL}       = [$self->{+ON_FAIL}]       if 'CODE' eq ref($self->{+ON_FAIL});
    $self->{+ON_COMPLETION} = [$self->{+ON_COMPLETION}] if 'CODE' eq ref($self->{+ON_COMPLETION});
}

=pod

worktrees/audit-fixes-master/lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/carp confess croak/;
use Scalar::Util qw/weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Connection::RowData qw{
    STORED
    PENDING
    DESYNC
    TRANSACTION
    ROW_DATA
};

worktrees/audit-fixes-master/lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

=back

=cut

sub init {
    my $self = shift;

    my $con = $self->{+CONNECTION} or croak "Connection was not provided";
    $self->{+TRANSACTIONS} //= $con->transactions;

    weaken($self->{+CONNECTION});
}

=pod

=head1 PUBLIC METHODS

=over 4

=item $bool = $mgr->does_cache

worktrees/audit-fixes-master/lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager::Cached;
use strict;
use warnings;

our $VERSION = '0.000028';

use Scalar::Util qw/weaken/;

use parent 'DBIx::QuickORM::RowManager';
use Object::HashBase qw {
    +cache
    +sweep
};

use constant SWEEP_FLOOR => 8;

=pod

worktrees/audit-fixes-master/lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

        my $old_key = $self->cache_key($old_pk);
        delete $scache->{$old_key} if defined $old_key;
    }

    $new_pk //= [$row->primary_key_value_list];
    my $new_key = $self->cache_key($new_pk) // return $row;

    $self->_purge_dead($scache) if exists $scache->{$new_key} && !defined $scache->{$new_key};

    $scache->{$new_key} = $row;
    weaken($scache->{$new_key});

    $self->_maybe_sweep($source, $scache);

    return $row;
}

=pod

=item $row = $mgr->uncache($source, $row, $old_pk, $new_pk)

worktrees/audit-fixes-master/t/AI/reconnect_clear.t  view on Meta::CPAN

    my $dbh = DBI->connect($dsn, '', '', {RaiseError => 1, PrintError => 0});
    $dbh->do('CREATE TABLE users (user_id INTEGER PRIMARY KEY, name TEXT NOT NULL)');
    $dbh->disconnect;
}

my $con = DBIx::QuickORM->quick(credentials => {dsn => $dsn});

# Stand-ins for surviving statement handles. clear_async/clear_aside/clear_fork
# only do registry bookkeeping (a lookup/compare and a delete); they never call
# methods on the handle, so a bare blessed ref is enough. Strong refs are held
# so the weakened registry entries do not vanish before reconnect.
my $async = bless {}, 'My::Surviving::Handle';
my $aside = bless {}, 'My::Surviving::Handle';
my $fork  = bless {}, 'My::Surviving::Handle';

$con->set_async($async);
$con->add_aside($aside);
$con->add_fork($fork);

$con->reconnect;

worktrees/audit-fixes-master/t/handle/first.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

worktrees/audit-fixes-master/t/handle/first.t  view on Meta::CPAN

    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    is($row->field('id'), 1, "Got generated primary key");

    my $row_clone = $h->first({id => 1});
    ref_is($row_clone, $row, "Got the same ref using first({id => 1})");

    my $row_clone2 = $h->first(id => 1);
    ref_is($row_clone2, $row, "Got the same ref using first(id => 1)");

    my $weak = $row;
    weaken($weak);
    $row        = undef;
    $row_clone  = undef;
    $row_clone2 = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");

    $row = $h->first({name => 'a'});
    is($row->field('id'), 1, "Got the right ID");

    my $data = $h->data_only->first({id => 1});
    ref_ok($data, 'HASH', "Got a hashref");

worktrees/audit-fixes-master/t/handle/one.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

worktrees/audit-fixes-master/t/handle/one.t  view on Meta::CPAN

    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    is($row->field('id'), 1, "Got generated primary key");

    my $row_clone = $h->one({id => 1});
    ref_is($row_clone, $row, "Got the same ref using one({id => 1})");

    my $row_clone2 = $h->one(id => 1);
    ref_is($row_clone2, $row, "Got the same ref using one(id => 1)");

    my $weak = $row;
    weaken($weak);
    $row        = undef;
    $row_clone  = undef;
    $row_clone2 = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");

    $row = $h->one({name => 'a'});
    is($row->field('id'), 1, "Got the right ID");

    my $data = $h->data_only->one({id => 1});
    ref_ok($data, 'HASH', "Got a hashref");

worktrees/audit-fixes-master/t/handle/update.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

sub SCHEMA_DIR { 't/handle/schema' }

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {

worktrees/audit-fixes-master/t/handle/update.t  view on Meta::CPAN


    ok(my $row = $h->insert({name => 'a'}), "Inserted a row");
    ref_is($h->one({id => 1}), $row, "Can fetch row");
    is($row->field('id'), 1, "Got generated primary key");
    ok($row->in_storage, "stored");

    $row->update({name => 'b'});
    is($row->field('name'), 'b', "Got new value");

    my $weak = $row;
    weaken($weak);
    $row = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");
    $row = $h->one({id => 1});
    is($row->field('name'), 'b', "Got new value");

    $row = undef;

    $h->handle(where => {name => 'b'})->update({name => 'c'});
    $row = $h->one({id => 1});
    is($row->field('name'), 'c', "Got new value");

worktrees/audit-fixes-master/t/omit.t  view on Meta::CPAN

use Test2::V0 -target => 'DBIx::QuickORM', '!meta', '!pass';
use DBIx::QuickORM;

use Scalar::Util qw/weaken/;

use lib 't/lib';
use DBIx::QuickORM::Test;

do_for_all_dbs {
    my $db = shift;

    db mydb => sub {
        dialect curdialect();
        db_name 'quickdb';

worktrees/audit-fixes-master/t/omit.t  view on Meta::CPAN

    };

    ok(my $orm = orm('my_orm')->connect, "Got a connection");
    ok(my $row = $orm->handle('example')->insert({name => 'a', data => {foo => 'bar'}}), "Inserted a row");
    ok($orm->schema->{tables}->{example}->{columns}->{data}->{omit}, "omit was merged into the autofill schema");
    $row = undef; $row = $orm->handle('example')->one(name => 'a');
    ok(!exists($row->row_data->{stored}->{data}), "did not fetch data");

    is($row->field('data'), {foo => 'bar'}, "Can fetch data");
    my $weak = $row;
    weaken($weak);
    $row = undef;
    ok(!defined($weak), "Previous row expired once all references were cleared");
    $row = $orm->handle('example')->one({name => 'a'});

    ok($row, "got row");
    ok(!exists($row->row_data->{stored}->{data}), "did not fetch data");

    $row = undef;

    $row = $orm->handle('example')->omit(['name'])->one({name => 'a'});

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/confess croak carp/;
use Scalar::Util qw/blessed weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Handle;
use DBIx::QuickORM::Connection::Transaction;

use Object::HashBase qw{
    <orm
    <dbh
    <dialect
    <pid

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

    my $txns = $self->{+TRANSACTIONS} = [];
    my $manager = $self->{+MANAGER} // 'DBIx::QuickORM::RowManager::Cached';
    if (blessed($manager)) {
        croak "Manager '$manager' does not subclass 'DBIx::QuickORM::RowManager'"
            unless $manager->DOES('DBIx::QuickORM::RowManager');

        $manager->set_connection($self);

        # The HashBase setter stores a strong reference, which would create a
        # connection <-> manager cycle; the manager holds its connection weakly.
        weaken($manager->{DBIx::QuickORM::RowManager::CONNECTION()});

        $manager->set_transactions($txns);
    }
    else {
        my $class = load_class($manager) or die $@;
        $self->{+MANAGER} = $class->new(transactions => $txns, connection => $self);
    }

    if (my $autofill = $orm->autofill) {
        my $schema = $self->{+DIALECT}->build_schema_from_db(autofill => $autofill);

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN


=cut

sub set_async {
    my $self = shift;
    my ($async) = @_;

    croak "There is already an async query in progress" if $self->{+IN_ASYNC} && !$self->{+IN_ASYNC}->done;

    $self->{+IN_ASYNC} = $async;
    weaken($self->{+IN_ASYNC});

    return $async;
}

sub add_aside {
    my $self = shift;
    my ($aside) = @_;

    $self->{+ASIDES}->{$aside} = $aside;
    weaken($self->{+ASIDES}->{$aside});

    return $aside;
}

sub add_fork {
    my $self = shift;
    my ($fork) = @_;

    $self->{+FORKS}->{$fork} = $fork;
    weaken($self->{+FORKS}->{$fork});

    return $fork;
}

sub clear_async {
    my $self = shift;
    my ($async) = @_;

    croak "Not currently running an async query" unless $self->{+IN_ASYNC};

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/Connection.pm  view on Meta::CPAN

        savepoint     => $sp,
        trace         => \@caller,
        on_fail       => $params{on_fail},
        on_success    => $params{on_success},
        on_completion => $params{on_completion},
    );

    $self->_txn_attach_relative_callbacks($txn, \%params);

    push @{$txns} => $txn;
    weaken($txns->[-1]);

    my $finalize = $self->_txn_finalizer($sp);

    unless($cb) {
        $txn->set_no_last(1);
        $txn->set_finalize($finalize);
        return $txn;
    }

    local $@;

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/carp confess croak/;
use Scalar::Util qw/weaken/;
use DBIx::QuickORM::Util qw/load_class/;

use DBIx::QuickORM::Affinity();

use DBIx::QuickORM::Connection::RowData qw{
    STORED
    PENDING
    DESYNC
    TRANSACTION
    ROW_DATA

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/RowManager.pm  view on Meta::CPAN

=back

=cut

sub init {
    my $self = shift;

    my $con = $self->{+CONNECTION} or croak "Connection was not provided";
    $self->{+TRANSACTIONS} //= $con->transactions;

    weaken($self->{+CONNECTION});
}

=pod

=head1 PUBLIC METHODS

=over 4

=item $bool = $mgr->does_cache

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

package DBIx::QuickORM::RowManager::Cached;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/croak/;
use Scalar::Util qw/weaken/;

use DBIx::QuickORM::Affinity();

use parent 'DBIx::QuickORM::RowManager';
use Object::HashBase qw {
    +cache
};

=pod

worktrees/dbic-compat-native-features/lib/DBIx/QuickORM/RowManager/Cached.pm  view on Meta::CPAN

        my $old_key = $self->cache_key($old_pk);
        delete $scache->{$old_key} if defined $old_key;
    }

    $new_pk //= [$row->primary_key_value_list];
    my $new_key = $self->cache_key($new_pk) // return $row;

    $self->_purge_dead($scache) if exists $scache->{$new_key} && !defined $scache->{$new_key};

    $scache->{$new_key} = $row;
    weaken($scache->{$new_key});
    return $row;
}

=pod

=item $row = $mgr->uncache($source, $row, $old_pk, $new_pk)

Remove and return the cached row for the given source and primary key. The
primary key is taken from the supplied keys, or from the row itself when
none are given.



( run in 2.246 seconds using v1.01-cache-2.11-cpan-600a1bdf6e4 )