Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix bug with bind_columns and a little refactoring

  • Loading branch information...
commit 25bed2bd0feca1f5579a1cf8f2fb295a76ea633d 1 parent 9d56a25
@bluescreen10 authored
View
141 lib/DBD/Mock/Session.pm
@@ -7,32 +7,48 @@ my $INSTANCE_COUNT = 1;
sub new {
my $class = shift;
- (@_) || die "You must specify at least one session state";
- my $session_name;
- if ( ref( $_[0] ) ) {
- $session_name = 'Session ' . $INSTANCE_COUNT;
- }
- else {
- $session_name = shift;
- }
- my @session_states = @_;
- (@session_states)
- || die "You must specify at least one session state";
- ( ref($_) eq 'HASH' )
- || die "You must specify session states as HASH refs"
- foreach @session_states;
+ my $name = ref( $_[0] ) ? "Session $INSTANCE_COUNT" : shift;
+
+ $class->_verify_states( $name, @_ );
+
$INSTANCE_COUNT++;
- return bless {
- name => $session_name,
- states => \@session_states,
+ bless {
+ name => $name,
+ states => \@_,
state_index => 0
- } => $class;
+ }, $class;
}
sub name { (shift)->{name} }
sub reset { (shift)->{state_index} = 0 }
sub num_states { scalar( @{ (shift)->{states} } ) }
+sub _verify_states {
+ my ( $class, $name, @states ) = @_;
+
+ my $index = 0;
+
+ die "You must specify at least one session state"
+ if not scalar(@states);
+
+ foreach (@states) {
+ die "You must specify session states as HASH refs"
+ if ref($_) ne 'HASH';
+
+ die "Bad state '$index' in DBD::Mock::Session ($name)"
+ if not exists $_->{statement}
+ or not exists $_->{results};
+
+ die
+"Bad 'statement' value '$_->{statement}' in DBD::Mock::Session ($name)"
+ if ref( $_->{statement} ) ne ''
+ and ref( $_->{statement} ) ne 'CODE'
+ and ref( $_->{statement} ) ne 'Regexp';
+
+ }
+
+}
+
sub current_state {
my $self = shift;
my $idx = $self->{state_index};
@@ -44,61 +60,68 @@ sub has_states_left {
return $self->{state_index} < scalar( @{ $self->{states} } );
}
+sub _remaining_states {
+ my $self = shift;
+ my $start_index = $self->{state_index};
+ my $end_index = $self->num_states - 1;
+ @{ $self->{states} }[ $start_index .. $end_index ];
+}
+
+sub _find_state_for {
+ my ( $self, $statement ) = @_;
+
+ foreach ( $self->_remaining_states ) {
+ my $stmt = $_->{statement};
+ my $ref = ref($stmt);
+
+ return $_ if ( $ref eq 'Regexp' and $statement =~ /$stmt/ );
+ return $_ if ( $ref eq 'CODE' and $stmt->( $statement, $_ ) );
+ return $_ if ( not $ref and $stmt eq $statement );
+ }
+
+ die "Bad 'statement' value '$statement' in session ($self->{name})";
+}
+
sub verify_statement {
- my ( $self, $dbh, $statement ) = @_;
+ my ( $self, $statement ) = @_;
- ( $self->has_states_left )
- || die "Session states exhausted, only '"
+ die "Session states exhausted, only '"
. scalar( @{ $self->{states} } )
- . "' in DBD::Mock::Session ("
- . $self->{name} . ")";
+ . "' in DBD::Mock::Session ($self->{name})"
+ unless $self->has_states_left;
- my $current_state = $self->current_state;
+ my $stmt = $self->current_state->{statement};
+ my $ref = ref($stmt);
- # make sure our state is good
- ( exists ${$current_state}{statement} && exists ${$current_state}{results} )
- || die "Bad state '"
- . $self->{state_index}
- . "' in DBD::Mock::Session ("
- . $self->{name} . ")";
-
- # try the SQL
- my $SQL = $current_state->{statement};
- unless ( ref($SQL) ) {
- ( $SQL eq $statement )
- || die
- "Statement does not match current state in DBD::Mock::Session ("
- . $self->{name} . ")\n"
- . " got: $statement\n"
- . " expected: $SQL";
- }
- elsif ( ref($SQL) eq 'Regexp' ) {
- ( $statement =~ /$SQL/ )
- || die
-"Statement does not match current state (with Regexp) in DBD::Mock::Session ("
- . $self->{name} . ")\n"
+ if ( $ref eq 'Regexp' and $statement !~ /$stmt/ ) {
+ die
+"Statement does not match current state (with Regexp) in DBD::Mock::Session ($self->{name})\n"
. " got: $statement\n"
- . " expected: $SQL";
+ . " expected: $stmt";
}
- elsif ( ref($SQL) eq 'CODE' ) {
- ( $SQL->( $statement, $current_state ) )
- || die
-"Statement does not match current state (with CODE ref) in DBD::Mock::Session ("
- . $self->{name} . ")";
+
+ if ( $ref eq 'CODE' and not $stmt->( $statement, $_ ) ) {
+ die
+"Statement does not match current state (with CODE ref) in DBD::Mock::Session ($self->{name})";
+
}
- else {
+
+ if ( not $ref and $stmt ne $statement ) {
die
-"Bad 'statement' value '$SQL' in current state in DBD::Mock::Session ("
- . $self->{name} . ")";
+"Statement does not match current state in DBD::Mock::Session ($self->{name})\n"
+ . " got: $statement\n"
+ . " expected: $stmt";
}
- # copy the result sets so that
- # we can re-use the session
- $dbh->STORE( 'mock_add_resultset' => [ @{ $current_state->{results} } ] );
+}
+
+sub results_for {
+ my ( $self, $statment ) = @_;
+ $self->_find_state_for($statment)->{results};
}
sub verify_bound_params {
- my ( $self, $dbh, $params ) = @_;
+ my ( $self, $params ) = @_;
my $current_state = $self->current_state;
if ( exists ${$current_state}{bound_params} ) {
View
64 lib/DBD/Mock/db.pm
@@ -55,37 +55,59 @@ sub prepare {
}
my $sth = DBI::_new_sth( $dbh, { Statement => $statement } );
-
$sth->trace_msg( "Preparing statement '${statement}'\n", 1 );
-
my %track_params = ( statement => $statement );
- # If we have available resultsets seed the tracker with one
+ if ( my $session = $dbh->{mock_session} ) {
+ eval {
+ my $rs = $session->results_for($statement);
+ if ( ref($rs) eq 'ARRAY' && scalar( @{$rs} ) > 0 ) {
+ my $fields = @{$rs}[0];
+ $track_params{return_data} = $rs;
+ $track_params{fields} = $fields;
+ $sth->STORE( NAME => $fields );
+ $sth->STORE( NUM_OF_FIELDS => scalar @{$fields} );
+ }
+ else {
+ $sth->trace_msg( "No return data set in DBH\n", 1 );
+ }
+ };
- my $rs;
- if ( my $all_rs = $dbh->{mock_rs} ) {
- if ( my $by_name = $all_rs->{named}{$statement} ) {
+ if ($@) {
+ $dbh->DBI::set_err( 1, "Session Error: $@. Statement: $statement" );
+ }
- # We want to copy this, because it is meant to be reusable
- $rs = [ @{ $by_name->{results} } ];
- if ( exists $by_name->{failure} ) {
- $track_params{failure} = [ @{ $by_name->{failure} } ];
+ }
+
+ else {
+ # If we have available resultsets seed the tracker with one
+
+ my $rs;
+ if ( my $all_rs = $dbh->{mock_rs} ) {
+ if ( my $by_name = $all_rs->{named}{$statement} ) {
+
+ # We want to copy this, because it is meant to be reusable
+ $rs = [ @{ $by_name->{results} } ];
+ if ( exists $by_name->{failure} ) {
+ $track_params{failure} = [ @{ $by_name->{failure} } ];
+ }
+ }
+ else {
+ $rs = shift @{ $all_rs->{ordered} };
}
}
+
+ if ( ref($rs) eq 'ARRAY' && scalar( @{$rs} ) > 0 ) {
+ my $fields = shift @{$rs};
+ $track_params{return_data} = $rs;
+ $track_params{fields} = $fields;
+ $sth->STORE( NAME => $fields );
+ $sth->STORE( NUM_OF_FIELDS => scalar @{$fields} );
+ }
else {
- $rs = shift @{ $all_rs->{ordered} };
+ $sth->trace_msg( "No return data set in DBH\n", 1 );
}
- }
- if ( ref($rs) eq 'ARRAY' && scalar( @{$rs} ) > 0 ) {
- my $fields = shift @{$rs};
- $track_params{return_data} = $rs;
- $track_params{fields} = $fields;
- $sth->STORE( NAME => $fields );
- $sth->STORE( NUM_OF_FIELDS => scalar @{$fields} );
- }
- else {
- $sth->trace_msg( "No return data set in DBH\n", 1 );
}
# do not allow a statement handle to be created if there is no
View
4 lib/DBD/Mock/st.pm
@@ -65,8 +65,8 @@ sub execute {
if ( my $session = $dbh->{mock_session} ) {
eval {
my $state = $session->current_state;
- $session->verify_statement( $dbh, $sth->{Statement} );
- $session->verify_bound_params( $dbh, $tracker->bound_params() );
+ $session->verify_statement( $sth->{Statement});
+ $session->verify_bound_params( $tracker->bound_params() );
# Load a copy of the results to return (minus the field
# names) into the tracker
View
34 t/021_DBD_Mock_Session.t
@@ -1,6 +1,6 @@
use strict;
-use Test::More tests => 59;
+use Test::More tests => 55;
BEGIN {
use_ok('DBD::Mock');
@@ -51,7 +51,7 @@ use DBI;
{
my $dbh = DBI->connect('dbi:Mock:', '', '', { RaiseError => 1, PrintError => 0 });
- my $session = DBD::Mock::Session->new({});
+ my $session = DBD::Mock::Session->new({ statement => '', results => []});
isa_ok($session, 'DBD::Mock::Session');
is($session->name(), 'Session 1', '... got the first default session name');
@@ -64,7 +64,7 @@ use DBI;
$dbh->{mock_session} = undef;
ok(!defined($dbh->{mock_session}), '... we no longer have a session in there');
- my $session2 = DBD::Mock::Session->new({});
+ my $session2 = DBD::Mock::Session->new({ statement => '', results => []});
isa_ok($session2, 'DBD::Mock::Session');
is($session2->name(), 'Session 2', '... got the second default session name');
@@ -232,7 +232,7 @@ use DBI;
like($@, qr/^You must specify session states as HASH refs/, '... got the error we expected');
eval {
- DBD::Mock::Session->new('session', {}, [])
+ DBD::Mock::Session->new('session', { statement => '', results => [] }, [])
};
ok(defined($@), '... got an error, as expected');
like($@, qr/^You must specify session states as HASH refs/, '... got the error we expected');
@@ -240,10 +240,8 @@ use DBI;
}
{
- my $session = DBD::Mock::Session->new('session' => {});
- isa_ok($session, 'DBD::Mock::Session');
-
eval {
+ my $session = DBD::Mock::Session->new('session' => {});
$session->verify_statement(DBI->connect('dbi:Mock:', '', ''), 'SELECT foo FROM bar');
};
ok(defined($@), '... got an error, as expected');
@@ -252,10 +250,8 @@ use DBI;
}
{
- my $session = DBD::Mock::Session->new('session' => { statement => "" });
- isa_ok($session, 'DBD::Mock::Session');
-
eval {
+ my $session = DBD::Mock::Session->new('session' => { statement => "" });
$session->verify_statement(DBI->connect('dbi:Mock:', '', ''), 'SELECT foo FROM bar');
};
ok(defined($@), '... got an error, as expected');
@@ -264,11 +260,9 @@ use DBI;
}
{
- my $session = DBD::Mock::Session->new('session' => { results => [] });
- isa_ok($session, 'DBD::Mock::Session');
-
eval {
- $session->verify_statement(DBI->connect('dbi:Mock:', '', ''), 'SELECT foo FROM bar');
+ my $session = DBD::Mock::Session->new('session' => { results => [] });
+ $session->verify_statement(DBI->connect('dbi:Mock:', '', ''), 'SELECT foo FROM bar');
};
ok(defined($@), '... got an error, as expected');
like($@, qr/^Bad state \'0\' in DBD::Mock::Session \(session\)/, '... got the error we expected');
@@ -276,19 +270,15 @@ use DBI;
}
{
- my $session = DBD::Mock::Session->new('session' =>
- {
+ eval {
+ my $session = DBD::Mock::Session->new('session' => {
statement => [],
results => []
- }
- );
- isa_ok($session, 'DBD::Mock::Session');
-
- eval {
+ });
$session->verify_statement(DBI->connect('dbi:Mock:', '', ''), 'SELECT foo FROM bar');
};
ok(defined($@), '... got an error, as expected');
- like($@, qr/^Bad \'statement\' value \'ARRAY\(0x[a-f0-9]+\)\' in current state in DBD::Mock::Session \(session\)/, '... got the error we expected');
+ like($@, qr/^Bad \'statement\' value \'ARRAY\(0x[a-f0-9]+\)\' in DBD::Mock::Session \(session\)/, '... got the error we expected');
}
Please sign in to comment.
Something went wrong with that request. Please try again.