DBIx-ResultSet

 view release on metacpan or  search on metacpan

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

Some tips and tricks are recorded in the L<cookbook|DBIx::ResultSet::Cookbook>.

=cut

use Clone qw( clone );
use List::MoreUtils qw( uniq );
use Carp qw( croak );
use Data::Page;
use DBIx::ResultSet::Connector;

=head1 CONNECTING

In order to start using this module you must first configure the connection to your
database.  This is done using the connect() class method:

    # Same arguments as DBI and DBIx::Connector.
    my $connector = DBIx::ResultSet->connect(
        $dsn, $user, $pass,
        $attr, #optional
    );

The connect() class method is a shortcut for creating a L<DBIx::ResultSet::Connector>
object.  When created this way, the AutoCommit DBI attribute will default to 1.
This is done per the strong recommendations by L<DBIx::Connector/new>.

By default the underlying L<DBIx::Connector> object will be called with mode('fixup').
While not recommended, you can change the default connection mode by specifying the
ConnectionMode attribute, as in:

    my $connector = DBIx::ResultSet->connect(
        $dsn, $user, $pass,
        { ConnectionMode => 'ping' },
    );

Alternatively you could create a L<DBIx::ResultSet::Connector> object directly and
pass your own custom-rolled L<DBIx::Connector> object.  For example:

    my $dbix_connector = DBIx::Connector->new(
        $dsn, $username, $password,
        { AutoCommit => 1 },
    );
    my $connector = DBIx::ResultSet::Connector->new(
        dbix_connector => $dbix_connector,
    );

=cut

sub connect {
    my $self = shift;
    return DBIx::ResultSet::Connector->connect( @_ );
}

=head1 SEARCH METHODS

=head2 search

    my $old_rs = $connector->resultset('users')->search({ status => 0 });
    my $new_rs = $old_rs->search({ age > 18 });
    print 'Disabled adults: ' . $new_rs->count() . "\n";

Returns a new result set object that overlays the passed in where clause
on top of the old where clause, creating a new result set.  The original
result set's where clause is left unmodified.

search() never executes SQL queries.  You can call search() as many times
as you like and iteratively build a resultset as much as you want, but no
SQL will be issued until you call one of the L<manipulation|MANIPULATION METHODS>
or L<retrieval|RETRIEVAL METHODS> methods.

=cut

sub search {
    my ($self, $where, $clauses) = @_;

    $where ||= {};
    my $new_where = clone( $self->where() );
    map { $new_where->{$_} = $where->{$_} } keys %$where;

    my $new_clauses = {};
    foreach my $clause (uniq sort (keys %$clauses, keys %{$self->clauses()})) {
        if (exists $clauses->{$clause}) {
            $new_clauses->{$clause} = clone( $clauses->{$clause} );
        }
        else {
            $new_clauses->{$clause} = clone( $self->clauses->{$clause} );
        }
    }

    return ref($self)->new(
        connector => $self->connector(),
        table     => $self->table(),
        where     => $new_where,
        clauses   => $new_clauses,
    );
}

sub _dbi_execute {
    my ($self, $dbh_method, $sql, $bind, $dbh_attrs) = @_;

    return $self->connector->run(sub{
        my ($dbh) = @_;
        my $sth = $dbh->prepare_cached( $sql );
        if ($dbh_method eq 'do') {
            $sth->execute( @$bind );
        }
        else {
            return $dbh->$dbh_method( $sth, $dbh_attrs, @$bind );
        }
        return;
    });
}

sub _dbi_prepare {
    my ($self, $sql) = @_;

    return $self->connector->run(sub{
        my ($dbh) = @_;
        return $dbh->prepare_cached( $sql );
    });
}



( run in 1.404 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )