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 | |
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 | |
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 | |
33 | $schema->storage->dbh->do ($create_sql); |
34 | |
35 | $schema->resultset('Artist')->create({ name => 'foo' }); |
36 | |
37 | $schema->txn_begin; |
38 | |
39 | my $arty = $schema->resultset('Artist')->find(1); |
40 | |
41 | my $name = $arty->name; |
42 | |
43 | # First off, test a generated savepoint name |
44 | $schema->svp_begin; |
45 | |
46 | cmp_ok($stats->{'SVP_BEGIN'}, '==', 1, 'Statistics svp_begin tickled'); |
47 | |
48 | $arty->update({ name => 'Jheephizzy' }); |
49 | |
50 | $arty->discard_changes; |
51 | |
52 | cmp_ok($arty->name, 'eq', 'Jheephizzy', 'Name changed'); |
53 | |
54 | # Rollback the generated name |
55 | # Active: 0 |
56 | $schema->svp_rollback; |
57 | |
58 | cmp_ok($stats->{'SVP_ROLLBACK'}, '==', 1, 'Statistics svp_rollback tickled'); |
59 | |
60 | $arty->discard_changes; |
61 | |
62 | cmp_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; |
76 | cmp_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; |
82 | cmp_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; |
95 | cmp_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; |
100 | cmp_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; |
106 | cmp_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 | |
146 | is($arty->name,'Miff','auto_savepoint worked'); |
147 | |
148 | cmp_ok($stats->{'SVP_BEGIN'},'==',7,'Correct number of savepoints created'); |
149 | |
150 | cmp_ok($stats->{'SVP_RELEASE'},'==',3,'Correct number of savepoints released'); |
151 | |
152 | cmp_ok($stats->{'SVP_ROLLBACK'},'==',5,'Correct number of savepoint rollbacks'); |
153 | |
154 | END { $schema->storage->dbh->do ("DROP TABLE artist") if defined $schema } |
155 | |