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