From a6f8fa82a159b1225c6f9084c319cdd6f55f99df Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 11:35:14 +0100 Subject: [PATCH 1/7] Add git-repo url to meta-data This saves people hunting around github on the offchange that there's a git-repo of the project. Now it's in the meta data and should be a lot easier for people to find. --- Build.PL | 6 ++++++ Changes | 3 +++ 2 files changed, 9 insertions(+) diff --git a/Build.PL b/Build.PL index 339089a..4bcb401 100644 --- a/Build.PL +++ b/Build.PL @@ -20,6 +20,12 @@ my $build = Module::Build->new( create_makefile_pl => 'traditional', recursive_test_files => 1, add_to_cleanup => [ '*.bak', ], + + meta_merge => { + resources => { + repository => 'https://github.com/bluescreen10/dbd-mock', + }, + }, ); $build->create_build_script; diff --git a/Changes b/Changes index c731d95..b271cc7 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Revision history for Perl extension DBD::Mock. +{{NEXT}} + - Add git-repo url to meta-data + 1.43 - Segregated into different packages - Removed code coverage from POD From c9d7bd7fbb1e496d35cff018bb2809ee82bc1d44 Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 11:52:07 +0100 Subject: [PATCH 2/7] Add failing test for execute_array() This is something we've tried using, and hence mocking in tests at $work recently. This script fails with the same error we're seeing, so is a good starting point for adding the functionality: $ prove -lv t/030_st_execute_array.t t/030_st_execute_array.t .. ok 1 - use DBD::Mock; ok 2 - use DBI; DBD::Mock::st execute_array failed: 3 bind values supplied but 0 expected at t/030_st_execute_array.t line 28. not ok 3 - Called execute_array() ok # Failed test 'Called execute_array() ok' # at t/030_st_execute_array.t line 30. 1..3 # Looks like you failed 1 test of 3. Dubious, test returned 1 (wstat 256, 0x100) Failed 1/3 subtests --- t/030_st_execute_array.t | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 t/030_st_execute_array.t diff --git a/t/030_st_execute_array.t b/t/030_st_execute_array.t new file mode 100644 index 0000000..596e5b9 --- /dev/null +++ b/t/030_st_execute_array.t @@ -0,0 +1,33 @@ +use strict; +use warnings; + +use Test::More; + +# test style cribbed from t/013_st_execute_bound_params.t + +BEGIN { + use_ok('DBD::Mock'); + use_ok('DBI'); +} + +my $sql = 'INSERT INTO staff (first_name, last_name, dept) VALUES(?, ?, ?)'; + +{ + my $dbh = DBI->connect( 'DBI:Mock:', '', '' ); + my $sth = eval { $dbh->prepare( $sql ) }; + + # taken from: https://metacpan.org/module/DBI#Statement-Handle-Methods + $dbh->{RaiseError} = 1; # save having to check each method call + $sth = $dbh->prepare($sql); + + $sth->bind_param_array(1, [ 'John', 'Mary', 'Tim' ]); + $sth->bind_param_array(2, [ 'Booth', 'Todd', 'Robinson' ]); + $sth->bind_param_array(3, "SALES"); # scalar will be reused for each row + + eval { + $sth->execute_array( { ArrayTupleStatus => \my @tuple_status } ); + }; + ok( ! $@, 'Called execute_array() ok' ); +} + +done_testing; From 62e4f4a4afe23f6e3c22c3f418263d81fc134d8b Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 11:53:33 +0100 Subject: [PATCH 3/7] git: ignore vi* swap files --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09ed293 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*\.sw? From c51ed6e8a134bd0128fedb3b543932750c8c747e Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 14:39:34 +0100 Subject: [PATCH 4/7] execute_array(): don't test single scalar value --- t/030_st_execute_array.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/030_st_execute_array.t b/t/030_st_execute_array.t index 596e5b9..e4d4a7c 100644 --- a/t/030_st_execute_array.t +++ b/t/030_st_execute_array.t @@ -22,7 +22,7 @@ my $sql = 'INSERT INTO staff (first_name, last_name, dept) VALUES(?, ?, ?)'; $sth->bind_param_array(1, [ 'John', 'Mary', 'Tim' ]); $sth->bind_param_array(2, [ 'Booth', 'Todd', 'Robinson' ]); - $sth->bind_param_array(3, "SALES"); # scalar will be reused for each row + # TODO: $sth->bind_param_array(3, "SALES"); # scalar will be reused for each row eval { $sth->execute_array( { ArrayTupleStatus => \my @tuple_status } ); From 9c5a03a57ddd89d32cbe3071b6b5361058354d93 Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 14:40:13 +0100 Subject: [PATCH 5/7] execute_array(): diag any errors in test --- t/030_st_execute_array.t | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/030_st_execute_array.t b/t/030_st_execute_array.t index e4d4a7c..2249878 100644 --- a/t/030_st_execute_array.t +++ b/t/030_st_execute_array.t @@ -27,7 +27,8 @@ my $sql = 'INSERT INTO staff (first_name, last_name, dept) VALUES(?, ?, ?)'; eval { $sth->execute_array( { ArrayTupleStatus => \my @tuple_status } ); }; - ok( ! $@, 'Called execute_array() ok' ); + ok( ! $@, 'Called execute_array() ok' ) + or diag $@; } done_testing; From 09e5fb9c9924dbd44393f5c2bd9ff42f5e5477e4 Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 14:40:49 +0100 Subject: [PATCH 6/7] Add bind_param_array() method This seems to behave the same as bind_param() in our mocked world, so we just pass the call on. --- lib/DBD/Mock/st.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/DBD/Mock/st.pm b/lib/DBD/Mock/st.pm index afcaf2b..5730696 100644 --- a/lib/DBD/Mock/st.pm +++ b/lib/DBD/Mock/st.pm @@ -20,6 +20,10 @@ sub bind_param { return 1; } +sub bind_param_array { + bind_param(@_); +} + sub bind_param_inout { my ( $sth, $param_num, $val, $max_len ) = @_; From 87292259f380cc5046e01a06b37777dd0c777c75 Mon Sep 17 00:00:00 2001 From: Chisel Date: Thu, 27 Sep 2012 14:41:52 +0100 Subject: [PATCH 7/7] Add execute_array() method to DBD::Mock::st This is an early prototype that no longer dies when we call execute_array() on a mocked $dbh - but the testing doesn't yet have very high coverage to prove that it behaves as expected. --- lib/DBD/Mock/st.pm | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/DBD/Mock/st.pm b/lib/DBD/Mock/st.pm index 5730696..ef714d7 100644 --- a/lib/DBD/Mock/st.pm +++ b/lib/DBD/Mock/st.pm @@ -41,6 +41,38 @@ sub bind_param_inout { return 1; } +sub execute_array { + my ( $sth, $attr, @bind_values ) = @_; + + # no bind values means we're relying on prior calls to bind_param_array() + # for our data + my $tracker = $sth->FETCH('mock_my_history'); + # don't use a reference; there's some magic attached to it somewhere + # so make it a lovely, simple array as soon as possible + my @bound = @{ $tracker->bound_params() }; + foreach my $p (@bound) { + my $result = $sth->execute( @$p ); + # store the result from execute() if ArrayTupleStatus attribute is + # passed + push @{ $attr->{ArrayTupleStatus} }, $result + if (exists $attr->{ArrayTupleStatus}); + } + + # TODO: the docs say: + # When called in scalar context the execute_array() method returns the + # number of tuples executed, or undef if an error occurred. Like + # execute(), a successful execute_array() always returns true regardless + # of the number of tuples executed, even if it's zero. If there were any + # errors the ArrayTupleStatus array can be used to discover which tuples + # failed and with what errors. + # When called in list context the execute_array() method returns two + # scalars; $tuples is the same as calling execute_array() in scalar + # context and $rows is the number of rows affected for each tuple, if + # available or -1 if the driver cannot determine this. + # We have glossed over this... + return scalar @bound; +} + sub execute { my ( $sth, @params ) = @_; my $dbh = $sth->{Database};