Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

execute_array() #2

Merged
merged 7 commits into from

4 participants

@chiselwright

We've recently started using DBI's execute_array() at work.

Out testing used DBD::Mock which doesn't support execute_array().

This set of commits adds the failing test, then implements execute_array() in DBD::Mock.

The testing is a bit sparse, but should be easy enough to extend as and when other users of the module require it.

Behaviour is as we (currently) expect from our test suite with this addition.

chiselwright added some commits
@chiselwright chiselwright 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.
a6f8fa8
@chiselwright chiselwright 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
c9d7bd7
@chiselwright chiselwright git: ignore vi* swap files 62e4f4a
@chiselwright chiselwright execute_array(): don't test single scalar value c51ed6e
@chiselwright chiselwright execute_array(): diag any errors in test 9c5a03a
@chiselwright chiselwright 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.
09e5fb9
@chiselwright chiselwright 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.
8729225
@ginesr
Collaborator

@bluescreen10 i'm merging this change, looks good to me!

@ginesr ginesr merged commit efc9492 into bluescreen10:master
@bluescreen10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 27, 2012
  1. @chiselwright

    Add git-repo url to meta-data

    chiselwright authored
    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.
  2. @chiselwright

    Add failing test for execute_array()

    chiselwright authored
    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
  3. @chiselwright
  4. @chiselwright
  5. @chiselwright
  6. @chiselwright

    Add bind_param_array() method

    chiselwright authored
    This seems to behave the same as bind_param() in our mocked world, so we just
    pass the call on.
  7. @chiselwright

    Add execute_array() method to DBD::Mock::st

    chiselwright authored
    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.
This page is out of date. Refresh to see the latest.
View
1  .gitignore
@@ -0,0 +1 @@
+*\.sw?
View
6 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;
View
3  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
View
36 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 ) = @_;
@@ -37,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};
View
34 t/030_st_execute_array.t
@@ -0,0 +1,34 @@
+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' ]);
+ # TODO: $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' )
+ or diag $@;
+}
+
+done_testing;
Something went wrong with that request. Please try again.