Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #76 from nihen/single_named

add single_named()
  • Loading branch information...
commit cebd6c99749a65573be1319b6c8190e0b0405d1d 2 parents 75c3ff7 + 1308def
@nekokak authored
View
27 bench/lookup_vs_single.pl
@@ -9,7 +9,6 @@
package Bench;
use parent 'Teng';
__PACKAGE__->load_plugin('Lookup');
- __PACKAGE__->load_plugin('SingleBySQL');
package Bench::Schema;
use Teng::Schema::Declare;
@@ -40,18 +39,24 @@
dbi => sub {$dbh->selectrow_hashref('SELECT id,name,age FROM user where id = ?', undef, 1)},
single => sub {$db->single('user', +{id => 1})},
single_by_sql => sub {$db->single_by_sql('SELECT id,name,age FROM user WHERE id = ?', [1], 'user')},
+ single_named => sub {$db->single_named('SELECT id,name,age FROM user WHERE id = :id', {id => 1}, 'user')},
lookup => sub {$db->lookup('user', +{id => 1})},
lookup_arrayref => sub {$db->lookup('user', [id => 1])},
}, 'all');
__END__
-Benchmark: timing 10000 iterations of dbi, lookup, single, single_by_sql...
- dbi: 0.543471 wallclock secs ( 0.50 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.51 CPU) @ 19607.84/s (n=10000)
- lookup: 0.808071 wallclock secs ( 0.78 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.78 CPU) @ 12820.51/s (n=10000)
- single: 1.67938 wallclock secs ( 1.57 usr 0.00 sys + 0.00 cusr 0.00 csys = 1.57 CPU) @ 6369.43/s (n=10000)
-single_by_sql: 0.769787 wallclock secs ( 0.74 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.74 CPU) @ 13513.51/s (n=10000)
- Rate single lookup single_by_sql dbi
-single 6369/s -- -50% -53% -68%
-lookup 12821/s 101% -- -5% -35%
-single_by_sql 13514/s 112% 5% -- -31%
-dbi 19608/s 208% 53% 45% --
+
+Benchmark: timing 10000 iterations of dbi, lookup, lookup_arrayref, single, single_by_sql, single_named...
+ dbi: 0.681385 wallclock secs ( 0.50 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.50 CPU) @ 20000.00/s (n=10000)
+ lookup: 1.53734 wallclock secs ( 1.04 usr 0.00 sys + 0.00 cusr 0.00 csys = 1.04 CPU) @ 9615.38/s (n=10000)
+lookup_arrayref: 1.40989 wallclock secs ( 1.02 usr 0.00 sys + 0.00 cusr 0.00 csys = 1.02 CPU) @ 9803.92/s (n=10000)
+ single: 2.49036 wallclock secs ( 1.57 usr 0.01 sys + 0.00 cusr 0.00 csys = 1.58 CPU) @ 6329.11/s (n=10000)
+single_by_sql: 1.09325 wallclock secs ( 0.76 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.76 CPU) @ 13157.89/s (n=10000)
+single_named: 1.23624 wallclock secs ( 0.86 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.86 CPU) @ 11627.91/s (n=10000)
+ Rate single lookup lookup_arrayref single_named single_by_sql dbi
+single 6329/s -- -34% -35% -46% -52% -68%
+lookup 9615/s 52% -- -2% -17% -27% -52%
+lookup_arrayref 9804/s 55% 2% -- -16% -25% -51%
+single_named 11628/s 84% 21% 19% -- -12% -42%
+single_by_sql 13158/s 108% 37% 34% 13% -- -34%
+dbi 20000/s 216% 108% 104% 72% 52% --
View
41 lib/Teng.pm
@@ -474,24 +474,29 @@ sub search {
$self->search_by_sql($sql, \@binds, $table_name);
}
-sub search_named {
- my ($self, $sql, $args, $table_name) = @_;
+sub _bind_named {
+ my ($self, $sql, $args ) = @_;
- my %named_bind = %{$args};
my @bind;
$sql =~ s{:([A-Za-z_][A-Za-z0-9_]*)}{
- Carp::croak("'$1' does not exist in bind hash") if !exists $named_bind{$1};
- if ( ref $named_bind{$1} && ref $named_bind{$1} eq "ARRAY" ) {
- push @bind, @{ $named_bind{$1} };
- my $tmp = join ',', map { '?' } @{ $named_bind{$1} };
+ Carp::croak("'$1' does not exist in bind hash") if !exists $args->{$1};
+ if ( ref $args->{$1} && ref $args->{$1} eq "ARRAY" ) {
+ push @bind, @{ $args->{$1} };
+ my $tmp = join ',', map { '?' } @{ $args->{$1} };
"( $tmp )";
} else {
- push @bind, $named_bind{$1};
+ push @bind, $args->{$1};
'?'
}
}ge;
- $self->search_by_sql($sql, \@bind, $table_name);
+ return ($sql, \@bind);
+}
+
+sub search_named {
+ my ($self, $sql, $args, $table_name) = @_;
+
+ $self->search_by_sql($self->_bind_named($sql, $args), $table_name);
}
sub single {
@@ -566,6 +571,12 @@ sub single_by_sql {
);
}
+sub single_named {
+ my ($self, $sql, $args, $table_name) = @_;
+
+ $self->single_by_sql($self->_bind_named($sql, $args), $table_name);
+}
+
sub _guess_table_name {
my ($class, $sql) = @_;
@@ -920,6 +931,18 @@ This is a shortcut for
But optimized implementation.
+=item $row = $teng->single_named($sql, [\%bind_values, [$table_name]])
+
+get one record from execute named query
+
+ my $row = $teng->single_named(q{SELECT id,name FROM user WHERE id = :id LIMIT 1}, {id => 1}, 'user');
+
+This is a shortcut for
+
+ my $row = $teng->search_named(q{SELECT id,name FROM user WHERE id = :id LIMIT 1}, {id => 1}, 'user')->next;
+
+But optimized implementation.
+
=item $teng->txn_scope
Creates a new transaction scope guard object.
View
2  t/001_basic/029_single_by_sql.t → t/002_common/026_single_by_sql.t
@@ -11,7 +11,7 @@ $db->insert('mock_basic',{
name => 'perl',
});
-subtest 'single' => sub {
+subtest 'single_by_sql' => sub {
my $row = $db->single_by_sql('SELECT * from mock_basic where id = ?', [1], 'mock_basic');
isa_ok $row, 'Teng::Row';
is $row->id, 1;
View
21 t/002_common/027_single_named.t
@@ -0,0 +1,21 @@
+use t::Utils;
+use Mock::Basic;
+use Test::More;
+
+my $dbh = t::Utils->setup_dbh;
+my $db = Mock::Basic->new({dbh => $dbh});
+$db->setup_test_db;
+
+$db->insert('mock_basic',{
+ id => 1,
+ name => 'perl',
+});
+
+subtest 'single_named' => sub {
+ my $row = $db->single_named('SELECT * from mock_basic where id = :id', {id => 1}, 'mock_basic');
+ isa_ok $row, 'Teng::Row';
+ is $row->id, 1;
+ is $row->name, 'perl';
+};
+
+done_testing;
Please sign in to comment.
Something went wrong with that request. Please try again.