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