Skip to content

Commit

Permalink
add lookup_pk
Browse files Browse the repository at this point in the history
  • Loading branch information
nihen committed Sep 17, 2012
1 parent 976036f commit 28bbb91
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bench/lookup_vs_single.pl
Expand Up @@ -9,6 +9,7 @@
package Bench;
use parent 'Teng';
__PACKAGE__->load_plugin('Lookup');
__PACKAGE__->load_plugin('LookupPK', {pk => 'id'});
__PACKAGE__->load_plugin('SingleBySQL');

package Bench::Schema;
Expand Down Expand Up @@ -42,6 +43,7 @@
single_by_sql => sub {$db->single_by_sql('SELECT id,name,age FROM user WHERE id = ?', [1], 'user')},
lookup => sub {$db->lookup('user', +{id => 1})},
lookup_arrayref => sub {$db->lookup('user', [id => 1])},
lookup_pk => sub {$db->lookup_pk('user', 1)},
}, 'all');

__END__
Expand Down
77 changes: 77 additions & 0 deletions lib/Teng/Plugin/LookupPK.pm
@@ -0,0 +1,77 @@
package Teng::Plugin::LookupPK;
use strict;
use warnings;
use utf8;

sub init {
my ( $class, $teng, $opt ) = @_;

my $pk_name = defined $opt && exists $opt->{pk} ? $opt->{pk} : 'id';

no strict 'refs';
*{$teng . '::lookup_pk'} = sub {
my ($self, $table_name, $pk, $opt) = @_;

my $table = $self->{schema}->get_table( $table_name );
Carp::croak("No such table $table_name") unless $table;

my $sql = sprintf('SELECT * FROM %s WHERE %s = ? LIMIT 1 %s',
$table_name,
$pk_name,
$opt->{for_update} ? 'FOR UPDATE' : '',
);

my $sth = $self->_execute($sql, [$pk]);
my $row = $sth->fetchrow_hashref($self->{fields_case});

return unless $row;
return $row if $self->{suppress_row_objects};

$table->{row_class}->new(
{
sql => $sql,
row_data => $row,
teng => $self,
table => $table,
table_name => $table_name,
}
);
};
}


1;
__END__
=head1 NAME
Teng::Plugin::LookupPK - lookup by single primary key.
=head1 NAME
package MyDB;
use parent qw/Teng/;
__PACKAGE__->load_plugin('LookupPK');
# same as
# __PACKAGE__->load_plugin('LookupPK', { pk => 'id' });
package main;
my $db = MyDB->new(...);
$db->lookup_pk('user' => 1); # => get single row
=head1 DESCRIPTION
This plugin provides fast lookup row .
=head1 METHODS
=over 4
=item $row = $db->lookup_pk($table_name, $pk, [\%attr]);
lookup single row records.
Teng#single is heavy.
=back
46 changes: 46 additions & 0 deletions t/001_basic/034_lookup_pk.t
@@ -0,0 +1,46 @@
use t::Utils;
use Mock::Basic;
use Test::More;

my $dbh = t::Utils->setup_dbh;
my $db_basic = Mock::Basic->new({dbh => $dbh});
$db_basic->setup_test_db;

subtest 'lookup_pk default' => sub {
Mock::Basic->load_plugin('LookupPK');
$db_basic->insert('mock_basic', => +{
id => 1,
name => 'perl',
});

my $row = $db_basic->lookup_pk('mock_basic', 1);
isa_ok $row, 'Mock::Basic::Row::MockBasic';
is_deeply $row->get_columns, +{
id => 1,
name => 'perl',
delete_fg => 0,
};
undef &Mock::Basic::lookup_pk;
};

subtest 'lookup_pk specify pk_name' => sub {
Mock::Basic->load_plugin('LookupPK', {pk => 'name'});

$db_basic->insert('mock_basic', => +{
id => 2,
name => 'ruby',
});

my $row = $db_basic->lookup_pk('mock_basic', 'ruby');
isa_ok $row, 'Mock::Basic::Row::MockBasic';
is_deeply $row->get_columns, +{
id => 2,
name => 'ruby',
delete_fg => 0,
};

undef &Mock::Basic::lookup_pk;
};

done_testing;

0 comments on commit 28bbb91

Please sign in to comment.