1 #include <pqxx/nontransaction>
2 #include <pqxx/robusttransaction>
3
4 #include "../test_helpers.hxx"
5
6
7 namespace
8 {
test_nontransaction_continues_after_error()9 void test_nontransaction_continues_after_error()
10 {
11 pqxx::connection c;
12 pqxx::nontransaction tx{c};
13
14 PQXX_CHECK_EQUAL(
15 tx.query_value<int>("SELECT 9"), 9, "Simple query went wrong.");
16 PQXX_CHECK_THROWS(
17 tx.exec("SELECT 1/0"), pqxx::sql_error, "Expected error did not happen.");
18
19 PQXX_CHECK_EQUAL(
20 tx.query_value<int>("SELECT 5"), 5, "Wrong result after error.");
21 }
22
23
24 std::string const table{"pqxx_test_transaction"};
25
26
delete_temp_table(pqxx::transaction_base & tx)27 void delete_temp_table(pqxx::transaction_base &tx)
28 {
29 tx.exec0("DROP TABLE IF EXISTS " + table);
30 }
31
32
create_temp_table(pqxx::transaction_base & tx)33 void create_temp_table(pqxx::transaction_base &tx)
34 {
35 tx.exec0("CREATE TEMP TABLE " + table + " (x integer)");
36 }
37
38
insert_temp_table(pqxx::transaction_base & tx,int value)39 void insert_temp_table(pqxx::transaction_base &tx, int value)
40 {
41 tx.exec0(
42 "INSERT INTO " + table + " (x) VALUES (" + pqxx::to_string(value) + ")");
43 }
44
count_temp_table(pqxx::transaction_base & tx)45 int count_temp_table(pqxx::transaction_base &tx)
46 {
47 return tx.query_value<int>("SELECT count(*) FROM " + table);
48 }
49
50
test_db_transaction_rolls_back()51 template<typename TX> void test_db_transaction_rolls_back()
52 {
53 pqxx::connection c;
54 pqxx::nontransaction tx1{c};
55 delete_temp_table(tx1);
56 create_temp_table(tx1);
57 tx1.commit();
58
59 TX tx2{c};
60 insert_temp_table(tx2, 32);
61 tx2.abort();
62
63 pqxx::nontransaction tx3{c};
64 PQXX_CHECK_EQUAL(
65 count_temp_table(tx3), 0,
66 "Abort on " + tx3.classname() + " did not roll back.");
67 delete_temp_table(tx3);
68 }
69
70
test_nontransaction_autocommits()71 void test_nontransaction_autocommits()
72 {
73 pqxx::connection c;
74
75 pqxx::nontransaction tx1{c};
76 delete_temp_table(tx1);
77 create_temp_table(tx1);
78 tx1.commit();
79
80 pqxx::nontransaction tx2{c};
81 insert_temp_table(tx2, 4);
82 tx2.abort();
83
84 pqxx::nontransaction tx3{c};
85 PQXX_CHECK_EQUAL(
86 count_temp_table(tx3), 1,
87 "Did not keep effect of aborted nontransaction.");
88 delete_temp_table(tx3);
89 }
90
91
test_double_close()92 template<typename TX> void test_double_close()
93 {
94 pqxx::connection c;
95
96 TX tx1{c};
97 tx1.exec1("SELECT 1");
98 tx1.commit();
99 tx1.commit();
100
101 TX tx2{c};
102 tx2.exec1("SELECT 2");
103 tx2.abort();
104 tx2.abort();
105
106 TX tx3{c};
107 tx3.exec1("SELECT 3");
108 tx3.commit();
109 PQXX_CHECK_THROWS(
110 tx3.abort(), pqxx::usage_error, "Abort after commit not caught.");
111 ;
112
113 TX tx4{c};
114 tx4.exec1("SELECT 4");
115 tx4.abort();
116 PQXX_CHECK_THROWS(
117 tx4.commit(), pqxx::usage_error, "Commit after abort not caught.");
118 }
119
120
test_transaction()121 void test_transaction()
122 {
123 test_nontransaction_continues_after_error();
124 test_nontransaction_autocommits();
125 test_double_close<pqxx::transaction<>>();
126 test_double_close<pqxx::read_transaction>();
127 test_double_close<pqxx::nontransaction>();
128 test_double_close<pqxx::robusttransaction<>>();
129 }
130
131
132 PQXX_REGISTER_TEST(test_transaction);
133 } // namespace
134