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