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