use strict;
use warnings;
use Test::More;
use DBI;
use DBD::MariaDB;
use lib 't', '.';
require 'lib.pl';
$|= 1;
use vars qw($test_dsn $test_user $test_password);
my $dbh = DbiTestConnect($test_dsn, $test_user, $test_password,
{ RaiseError => 1, PrintError => 0, AutoCommit => 0,
mariadb_multi_statements => 1 });
plan tests => 77;
ok (defined $dbh, "Connected to database with multi statement support");
$dbh->{mariadb_server_prepare}= 0;
ok($dbh->do("SET SQL_MODE=''"),"init connection SQL_MODE non strict");
ok($dbh->do("DROP TABLE IF EXISTS dbd_mysql_t76multi"), "clean up");
ok($dbh->do("CREATE TABLE dbd_mysql_t76multi (a INT)"), "create table");
ok($dbh->do("INSERT INTO dbd_mysql_t76multi VALUES (1); INSERT INTO dbd_mysql_t76multi VALUES (2);"), "2 inserts");
# Check that a second do() doesn't fail with an 'Out of sync' error
ok($dbh->do("INSERT INTO dbd_mysql_t76multi VALUES (3); INSERT INTO dbd_mysql_t76multi VALUES (4);"), "2 more inserts");
# Check that more_results works for non-SELECT results too
my $sth;
ok($sth = $dbh->prepare("UPDATE dbd_mysql_t76multi SET a=5 WHERE a=1; UPDATE dbd_mysql_t76multi SET a='6suffix' WHERE a<4"));
is($sth->rows, -1);
ok($sth->execute(), "Execute updates");
is($sth->rows, 1, "First update affected 1 row");
is($sth->{mariadb_warning_count}, 0, "First update had no warnings");
ok($sth->{Active}, "Statement handle is Active");
ok($sth->more_results());
is($sth->rows, 2, "Second update affected 2 rows");
is($sth->{mariadb_warning_count}, 2, "Second update had 2 warnings");
ok(not $sth->more_results());
# Now run it again without calling more_results().
ok($sth->execute(), "Execute updates again");
ok($sth->finish());
# Check that do() doesn't fail with an 'Out of sync' error
is($dbh->do("DELETE FROM dbd_mysql_t76multi"), 4, "Delete all rows");
# Test that do() reports errors from all result sets
ok(!eval { $dbh->do("INSERT INTO dbd_mysql_t76multi VALUES (1); INSERT INTO bad_dbd_mysql_t76multi VALUES (2);") }, "do() reports errors");
# Test that execute() reports errors from only the first result set
ok($sth = $dbh->prepare("UPDATE dbd_mysql_t76multi SET a=2; UPDATE bad_dbd_mysql_t76multi SET a=3"));
ok($sth->execute(), "Execute updates");
ok(!$sth->err(), "Err was not set after execute");
ok(!eval { $sth->more_results(); 1 });
ok($sth->err(), "Err was set after more_results");
ok $dbh->do("DROP TABLE dbd_mysql_t76multi");
# Check that last_insert_id works for more_results too
ok($dbh->do("CREATE TEMPORARY TABLE dbd_mysql_t76multi2 (a INT AUTO_INCREMENT PRIMARY KEY)"));
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(); INSERT INTO dbd_mysql_t76multi2 VALUES();"));
ok($sth->execute());
is($sth->last_insert_id(), 1);
is($dbh->last_insert_id(undef, undef, undef, undef), 1);
ok($sth->more_results());
is($sth->last_insert_id(), 2);
is($dbh->last_insert_id(undef, undef, undef, undef), 2);
ok(not $sth->more_results());
# Check that $dbh->last_insert_id works after $dbh->do with multi statements
ok($dbh->do("INSERT INTO dbd_mysql_t76multi2 VALUES(3); INSERT INTO dbd_mysql_t76multi2 VALUES(4);"));
is($dbh->last_insert_id(undef, undef, undef, undef), 4, '$dbh->last_insert_id is correct after $dbh->do with multi statements');
# Check that $dbh->last_insert_id works after prepare, execute and finish but without more_results
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(5); INSERT INTO dbd_mysql_t76multi2 VALUES(6);"));
ok($sth->execute());
ok($sth->finish());
is($dbh->last_insert_id(undef, undef, undef, undef), 6, '$dbh->last_insert_id is correct after multi statement prepare, execute and finish');
# Check that $dbh->last_insert_id works after prepare and execute, but without more_results; after preparing new statement
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(7); INSERT INTO dbd_mysql_t76multi2 VALUES(8);"));
ok($sth->execute());
ok($sth = $dbh->prepare("SELECT 1"));
is($dbh->last_insert_id(undef, undef, undef, undef), 8, '$dbh->last_insert_id is correct after multi statement prepare and execute without finish followed by new prepare');
# Check that $dbh->last_insert_id works after prepare and execute, but without more_results; after calling $dbh->do which do not modify last_insert_id
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(9); INSERT INTO dbd_mysql_t76multi2 VALUES(10);"));
ok($sth->execute());
ok($dbh->do("SELECT 1"));
is($dbh->last_insert_id(undef, undef, undef, undef), 10, '$dbh->last_insert_id is correct after multi statement prepare and execute without finish followed by $dbh->do');
ok($sth->finish());
# Check that statement attributes are correct after calling more_results
ok($dbh->do("CREATE TEMPORARY TABLE dbd_mysql_t76multi3 (name_id1 INT, name_id2 INT)"));
ok($sth = $dbh->prepare("SELECT name_id1 FROM dbd_mysql_t76multi3; INSERT INTO dbd_mysql_t76multi2 VALUES(11); SELECT name_id1, name_id2 FROM dbd_mysql_t76multi3; SYNTAX ERROR"));
is($sth->rows, -1);
ok($sth->execute());
is($sth->{NUM_OF_FIELDS}, 1);
is($sth->{NUM_OF_PARAMS}, 0);
is($sth->rows, 0);
is_deeply($sth->{NAME}, [ 'name_id1' ]);
is_deeply($sth->{mariadb_type}, [ DBD::MariaDB::TYPE_LONG ]);
ok($sth->more_results());
is($sth->{NUM_OF_FIELDS}, 0);
is($sth->{NUM_OF_PARAMS}, 0);
is($sth->rows, 1);
ok(!eval { $sth->{NAME} });
ok(!eval { $sth->{mariadb_type} });
ok($sth->more_results());
is($sth->{NUM_OF_FIELDS}, 2);
is($sth->{NUM_OF_PARAMS}, 0);
is($sth->rows, 0);
is_deeply($sth->{NAME}, [ 'name_id1', 'name_id2' ]);
is_deeply($sth->{mariadb_type}, [ DBD::MariaDB::TYPE_LONG, DBD::MariaDB::TYPE_LONG ]);
ok(!eval { $sth->more_results() });
is($sth->{NUM_OF_FIELDS}, 0);
is($sth->{NUM_OF_PARAMS}, 0);
ok(!eval { $sth->{NAME} });
ok(!eval { $sth->{mariadb_type} });
is($sth->rows, -1);
$dbh->disconnect();