1use strict; 2use warnings; 3 4use DBI; 5use Test::More; 6use lib 't', '.'; 7require 'lib.pl'; 8 9use vars qw($have_transactions $got_warning $test_dsn $test_user $test_password); 10 11my $dbh; 12eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password, 13 { RaiseError => 1, PrintError => 1, AutoCommit => 0 });}; 14if ($@) { 15 plan skip_all => "no database connection"; 16} 17 18sub catch_warning ($) { 19 $got_warning = 1; 20} 21 22sub num_rows($$$) { 23 my($dbh, $table, $num) = @_; 24 my($sth, $got); 25 26 if (!($sth = $dbh->prepare("SELECT * FROM dbd_mysql_t50commit"))) { 27 return "Failed to prepare: err " . $dbh->err . ", errstr " 28 . $dbh->errstr; 29 } 30 if (!$sth->execute) { 31 return "Failed to execute: err " . $dbh->err . ", errstr " 32 . $dbh->errstr; 33 } 34 $got = 0; 35 while ($sth->fetchrow_arrayref) { 36 ++$got; 37 } 38 if ($got ne $num) { 39 return "Wrong result: Expected $num rows, got $got.\n"; 40 } 41 return ''; 42} 43 44$have_transactions = have_transactions($dbh); 45my $engine= $have_transactions ? 'InnoDB' : 'MyISAM'; 46 47if ($have_transactions) { 48 plan tests => 22; 49 50 ok $dbh->do("DROP TABLE IF EXISTS dbd_mysql_t50commit"), "drop table if exists dbd_mysql_t50commit"; 51 my $create =<<EOT; 52CREATE TABLE dbd_mysql_t50commit ( 53 id INT(4) NOT NULL default 0, 54 name VARCHAR(64) NOT NULL default '' 55) ENGINE=$engine 56EOT 57 58 ok $dbh->do($create), 'create dbd_mysql_t50commit'; 59 60 ok !$dbh->{AutoCommit}, "\$dbh->{AutoCommit} not defined |$dbh->{AutoCommit}|"; 61 62 $dbh->{AutoCommit} = 0; 63 ok !$dbh->err; 64 ok !$dbh->errstr; 65 ok !$dbh->{AutoCommit}; 66 67 ok $dbh->do("INSERT INTO dbd_mysql_t50commit VALUES (1, 'Jochen')"), 68 "insert into dbd_mysql_t50commit (1, 'Jochen')"; 69 70 my $msg; 71 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 1); 72 ok !$msg; 73 74 ok $dbh->rollback, 'rollback'; 75 76 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 0); 77 ok !$msg; 78 79 ok $dbh->do("DELETE FROM dbd_mysql_t50commit WHERE id = 1"), "delete from dbd_mysql_t50commit where id = 1"; 80 81 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 0); 82 ok !$msg; 83 ok $dbh->commit, 'commit'; 84 85 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 0); 86 ok !$msg; 87 88 # Check auto rollback after disconnect 89 ok $dbh->do("INSERT INTO dbd_mysql_t50commit VALUES (1, 'Jochen')"); 90 91 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 1); 92 ok !$msg; 93 94 ok $dbh->disconnect; 95 96 ok ($dbh = DBI->connect($test_dsn, $test_user, $test_password)); 97 98 ok $dbh, "connected"; 99 100 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 0); 101 ok !$msg; 102 103 ok $dbh->{AutoCommit}, "\$dbh->{AutoCommit} $dbh->{AutoCommit}"; 104 ok $dbh->do("DROP TABLE dbd_mysql_t50commit"); 105 106} 107else { 108 plan tests => 13; 109 110 ok $dbh->do("DROP TABLE IF EXISTS dbd_mysql_t50commit"), "drop table if exists dbd_mysql_t50commit"; 111 my $create =<<EOT; 112 CREATE TABLE dbd_mysql_t50commit ( 113 id INT(4) NOT NULL default 0, 114 name VARCHAR(64) NOT NULL default '' 115 ) ENGINE=$engine 116EOT 117 118 ok $dbh->do($create), 'create dbd_mysql_t50commit'; 119 120 # Tests for databases that don't support transactions 121 # Check whether AutoCommit mode works. 122 123 ok $dbh->do("INSERT INTO dbd_mysql_t50commit VALUES (1, 'Jochen')"); 124 my $msg = num_rows($dbh, 'dbd_mysql_t50commit', 1); 125 ok !$msg; 126 127 ok $dbh->disconnect; 128 129 ok ($dbh = DBI->connect($test_dsn, $test_user, $test_password)); 130 131 $msg = num_rows($dbh, 'dbd_mysql_t50commit', 1); 132 ok !$msg; 133 134 ok $dbh->do("INSERT INTO dbd_mysql_t50commit VALUES (2, 'Tim')"); 135 136 my $result; 137 $@ = ''; 138 139 $SIG{__WARN__} = \&catch_warning; 140 141 $got_warning = 0; 142 143 eval { $result = $dbh->commit; }; 144 145 $SIG{__WARN__} = 'DEFAULT'; 146 147 ok $got_warning; 148 149# Check whether rollback issues a warning in AutoCommit mode 150# We accept error messages as being legal, because the DBI 151# requirement of just issuing a warning seems scary. 152 ok $dbh->do("INSERT INTO dbd_mysql_t50commit VALUES (3, 'Alligator')"); 153 154 $@ = ''; 155 $SIG{__WARN__} = \&catch_warning; 156 $got_warning = 0; 157 eval { $result = $dbh->rollback; }; 158 $SIG{__WARN__} = 'DEFAULT'; 159 160 ok $got_warning, "Should be warning defined upon rollback of non-trx table"; 161 162 ok $dbh->do("DROP TABLE dbd_mysql_t50commit"); 163 ok $dbh->disconnect(); 164} 165