9 my ($create_sql, $dsn, $user, $pass);
11 if (exists $ENV{DBICTEST_PG_DSN}) {
12 ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
14 $create_sql = "CREATE TABLE artist (artistid serial PRIMARY KEY, name VARCHAR(100), charfield CHAR(10))";
15 } elsif (exists $ENV{DBICTEST_MYSQL_DSN}) {
16 ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/};
18 $create_sql = "CREATE TABLE artist (artistid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), charfield CHAR(10)) ENGINE=InnoDB";
20 plan skip_all => 'Set DBICTEST_(PG|MYSQL)_DSN _USER and _PASS if you want to run savepoint tests';
25 my $schema = DBICTest::Schema->connect ($dsn,$user,$pass,{ auto_savepoint => 1 });
27 my $stats = DBICTest::Stats->new;
29 $schema->storage->debugobj($stats);
31 $schema->storage->debug(1);
33 $schema->storage->dbh->do ($create_sql);
35 $schema->resultset('Artist')->create({ name => 'foo' });
39 my $arty = $schema->resultset('Artist')->find(1);
41 my $name = $arty->name;
43 # First off, test a generated savepoint name
46 cmp_ok($stats->{'SVP_BEGIN'}, '==', 1, 'Statistics svp_begin tickled');
48 $arty->update({ name => 'Jheephizzy' });
50 $arty->discard_changes;
52 cmp_ok($arty->name, 'eq', 'Jheephizzy', 'Name changed');
54 # Rollback the generated name
56 $schema->svp_rollback;
58 cmp_ok($stats->{'SVP_ROLLBACK'}, '==', 1, 'Statistics svp_rollback tickled');
60 $arty->discard_changes;
62 cmp_ok($arty->name, 'eq', $name, 'Name rolled back');
64 $arty->update({ name => 'Jheephizzy'});
67 $schema->svp_begin('testing1');
69 $arty->update({ name => 'yourmom' });
72 $schema->svp_begin('testing2');
74 $arty->update({ name => 'gphat' });
75 $arty->discard_changes;
76 cmp_ok($arty->name, 'eq', 'gphat', 'name changed');
78 # Rollback doesn't DESTROY the savepoint, it just rolls back to the value
80 $schema->svp_rollback('testing2');
81 $arty->discard_changes;
82 cmp_ok($arty->name, 'eq', 'yourmom', 'testing2 reverted');
85 $schema->svp_begin('testing3');
86 $arty->update({ name => 'coryg' });
88 $schema->svp_begin('testing4');
89 $arty->update({ name => 'watson' });
91 # Release 3, which implicitly releases 4
93 $schema->svp_release('testing3');
94 $arty->discard_changes;
95 cmp_ok($arty->name, 'eq', 'watson', 'release left data');
96 # This rolls back savepoint 2
98 $schema->svp_rollback;
99 $arty->discard_changes;
100 cmp_ok($arty->name, 'eq', 'yourmom', 'rolled back to 2');
102 # Rollback the original savepoint, taking us back to the beginning, implicitly
103 # rolling back savepoint 1 and 2
104 $schema->svp_rollback('savepoint_0');
105 $arty->discard_changes;
106 cmp_ok($arty->name, 'eq', 'foo', 'rolled back to start');
110 # And now to see if txn_do will behave correctly
112 $schema->txn_do (sub {
113 $schema->txn_do (sub {
114 $arty->name ('Muff');
120 $schema->txn_do (sub {
121 $arty->name ('Moff');
125 $arty->discard_changes;
127 is($arty->name,'Moff','Value updated in nested transaction');
129 $schema->storage->dbh->do ("GUARANTEED TO PHAIL");
133 ok ($@,'Nested transaction failed (good)');
135 $arty->discard_changes;
137 is($arty->name,'Muff','auto_savepoint rollback worked');
139 $arty->name ('Miff');
144 $arty->discard_changes;
146 is($arty->name,'Miff','auto_savepoint worked');
148 cmp_ok($stats->{'SVP_BEGIN'},'==',7,'Correct number of savepoints created');
150 cmp_ok($stats->{'SVP_RELEASE'},'==',3,'Correct number of savepoints released');
152 cmp_ok($stats->{'SVP_ROLLBACK'},'==',5,'Correct number of savepoint rollbacks');
154 END { $schema->storage->dbh->do ("DROP TABLE artist") if defined $schema }