Merge 'trunk' into 'replication_dedux'
[dbsrgits/DBIx-Class.git] / t / 98savepoints.t
CommitLineData
ddf66ced 1use strict;
2use warnings;
3
4use Test::More;
5use lib qw(t/lib);
6use DBICTest;
7use DBICTest::Stats;
8
9my ($create_sql, $dsn, $user, $pass);
10
11if (exists $ENV{DBICTEST_PG_DSN}) {
12 ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
13
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/};
17
18 $create_sql = "CREATE TABLE artist (artistid INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), charfield CHAR(10)) ENGINE=InnoDB";
19} else {
20 plan skip_all => 'Set DBICTEST_(PG|MYSQL)_DSN _USER and _PASS if you want to run savepoint tests';
21}
22
23plan tests => 16;
24
25my $schema = DBICTest::Schema->connect ($dsn,$user,$pass,{ auto_savepoint => 1 });
26
27my $stats = DBICTest::Stats->new;
28
29$schema->storage->debugobj($stats);
30
31$schema->storage->debug(1);
32
33$schema->storage->dbh->do ($create_sql);
34
35$schema->resultset('Artist')->create({ name => 'foo' });
36
37$schema->txn_begin;
38
39my $arty = $schema->resultset('Artist')->find(1);
40
41my $name = $arty->name;
42
43# First off, test a generated savepoint name
44$schema->svp_begin;
45
46cmp_ok($stats->{'SVP_BEGIN'}, '==', 1, 'Statistics svp_begin tickled');
47
48$arty->update({ name => 'Jheephizzy' });
49
50$arty->discard_changes;
51
52cmp_ok($arty->name, 'eq', 'Jheephizzy', 'Name changed');
53
54# Rollback the generated name
55# Active: 0
56$schema->svp_rollback;
57
58cmp_ok($stats->{'SVP_ROLLBACK'}, '==', 1, 'Statistics svp_rollback tickled');
59
60$arty->discard_changes;
61
62cmp_ok($arty->name, 'eq', $name, 'Name rolled back');
63
64$arty->update({ name => 'Jheephizzy'});
65
66# Active: 0 1
67$schema->svp_begin('testing1');
68
69$arty->update({ name => 'yourmom' });
70
71# Active: 0 1 2
72$schema->svp_begin('testing2');
73
74$arty->update({ name => 'gphat' });
75$arty->discard_changes;
76cmp_ok($arty->name, 'eq', 'gphat', 'name changed');
77# Active: 0 1 2
78# Rollback doesn't DESTROY the savepoint, it just rolls back to the value
79# at it's conception
80$schema->svp_rollback('testing2');
81$arty->discard_changes;
82cmp_ok($arty->name, 'eq', 'yourmom', 'testing2 reverted');
83
84# Active: 0 1 2 3
85$schema->svp_begin('testing3');
86$arty->update({ name => 'coryg' });
87# Active: 0 1 2 3 4
88$schema->svp_begin('testing4');
89$arty->update({ name => 'watson' });
90
91# Release 3, which implicitly releases 4
92# Active: 0 1 2
93$schema->svp_release('testing3');
94$arty->discard_changes;
95cmp_ok($arty->name, 'eq', 'watson', 'release left data');
96# This rolls back savepoint 2
97# Active: 0 1 2
98$schema->svp_rollback;
99$arty->discard_changes;
100cmp_ok($arty->name, 'eq', 'yourmom', 'rolled back to 2');
101
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;
106cmp_ok($arty->name, 'eq', 'foo', 'rolled back to start');
107
108$schema->txn_commit;
109
110# And now to see if txn_do will behave correctly
111
112$schema->txn_do (sub {
113 $schema->txn_do (sub {
114 $arty->name ('Muff');
115
116 $arty->update;
117 });
118
119 eval {
120 $schema->txn_do (sub {
121 $arty->name ('Moff');
122
123 $arty->update;
124
125 $arty->discard_changes;
126
127 is($arty->name,'Moff','Value updated in nested transaction');
128
129 $schema->storage->dbh->do ("GUARANTEED TO PHAIL");
130 });
131 };
132
133 ok ($@,'Nested transaction failed (good)');
134
135 $arty->discard_changes;
136
137 is($arty->name,'Muff','auto_savepoint rollback worked');
138
139 $arty->name ('Miff');
140
141 $arty->update;
142 });
143
144$arty->discard_changes;
145
146is($arty->name,'Miff','auto_savepoint worked');
147
148cmp_ok($stats->{'SVP_BEGIN'},'==',7,'Correct number of savepoints created');
149
150cmp_ok($stats->{'SVP_RELEASE'},'==',3,'Correct number of savepoints released');
151
152cmp_ok($stats->{'SVP_ROLLBACK'},'==',5,'Correct number of savepoint rollbacks');
153
154END { $schema->storage->dbh->do ("DROP TABLE artist") if defined $schema }
155