5 use DBIx::Class::Optional::Dependencies ();
7 my ($create_sql, $dsn, $user, $pass);
9 if ($ENV{DBICTEST_PG_DSN}) {
10 plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('rdbms_pg')
11 unless DBIx::Class::Optional::Dependencies->req_ok_for ('rdbms_pg');
13 ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
15 $create_sql = "CREATE TABLE artist (artistid serial PRIMARY KEY, name VARCHAR(100), rank INTEGER NOT NULL DEFAULT '13', charfield CHAR(10))";
16 } elsif ($ENV{DBICTEST_MYSQL_DSN}) {
17 plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_mysql')
18 unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_mysql');
20 ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/};
22 $create_sql = "CREATE TABLE artist (artistid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), rank INTEGER NOT NULL DEFAULT '13', charfield CHAR(10)) ENGINE=InnoDB";
24 plan skip_all => 'Set DBICTEST_(PG|MYSQL)_DSN _USER and _PASS if you want to run savepoint tests';
33 my $schema = DBICTest::Schema->connect ($dsn,$user,$pass,{ auto_savepoint => 1 });
35 my $stats = DBICTest::Stats->new;
37 $schema->storage->debugobj($stats);
39 $schema->storage->debug(1);
42 local $SIG{__WARN__} = sub {};
43 $schema->storage->dbh->do ('DROP TABLE IF EXISTS artist');
44 $schema->storage->dbh->do ($create_sql);
47 $schema->resultset('Artist')->create({ name => 'foo' });
51 my $arty = $schema->resultset('Artist')->find(1);
53 my $name = $arty->name;
55 # First off, test a generated savepoint name
58 cmp_ok($stats->{'SVP_BEGIN'}, '==', 1, 'Statistics svp_begin tickled');
60 $arty->update({ name => 'Jheephizzy' });
62 $arty->discard_changes;
64 cmp_ok($arty->name, 'eq', 'Jheephizzy', 'Name changed');
66 # Rollback the generated name
68 $schema->svp_rollback;
70 cmp_ok($stats->{'SVP_ROLLBACK'}, '==', 1, 'Statistics svp_rollback tickled');
72 $arty->discard_changes;
74 cmp_ok($arty->name, 'eq', $name, 'Name rolled back');
76 $arty->update({ name => 'Jheephizzy'});
79 $schema->svp_begin('testing1');
81 $arty->update({ name => 'yourmom' });
84 $schema->svp_begin('testing2');
86 $arty->update({ name => 'gphat' });
87 $arty->discard_changes;
88 cmp_ok($arty->name, 'eq', 'gphat', 'name changed');
90 # Rollback doesn't DESTROY the savepoint, it just rolls back to the value
92 $schema->svp_rollback('testing2');
93 $arty->discard_changes;
94 cmp_ok($arty->name, 'eq', 'yourmom', 'testing2 reverted');
97 $schema->svp_begin('testing3');
98 $arty->update({ name => 'coryg' });
100 $schema->svp_begin('testing4');
101 $arty->update({ name => 'watson' });
103 # Release 3, which implicitly releases 4
105 $schema->svp_release('testing3');
106 $arty->discard_changes;
107 cmp_ok($arty->name, 'eq', 'watson', 'release left data');
108 # This rolls back savepoint 2
110 $schema->svp_rollback;
111 $arty->discard_changes;
112 cmp_ok($arty->name, 'eq', 'yourmom', 'rolled back to 2');
114 # Rollback the original savepoint, taking us back to the beginning, implicitly
115 # rolling back savepoint 1 and 2
116 $schema->svp_rollback('savepoint_0');
117 $arty->discard_changes;
118 cmp_ok($arty->name, 'eq', 'foo', 'rolled back to start');
122 # And now to see if txn_do will behave correctly
124 $schema->txn_do (sub {
125 $schema->txn_do (sub {
126 $arty->name ('Muff');
132 $schema->txn_do (sub {
133 $arty->name ('Moff');
137 $arty->discard_changes;
139 is($arty->name,'Moff','Value updated in nested transaction');
141 $schema->storage->dbh->do ("GUARANTEED TO PHAIL");
145 ok ($@,'Nested transaction failed (good)');
147 $arty->discard_changes;
149 is($arty->name,'Muff','auto_savepoint rollback worked');
151 $arty->name ('Miff');
156 $arty->discard_changes;
158 is($arty->name,'Miff','auto_savepoint worked');
160 cmp_ok($stats->{'SVP_BEGIN'},'==',7,'Correct number of savepoints created');
162 cmp_ok($stats->{'SVP_RELEASE'},'==',3,'Correct number of savepoints released');
164 cmp_ok($stats->{'SVP_ROLLBACK'},'==',5,'Correct number of savepoint rollbacks');
166 END { $schema->storage->dbh->do ("DROP TABLE artist") if defined $schema }