test13.cxx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <pqxx/transaction>
  2. #include <pqxx/transactor>
  3. #include "test_helpers.hxx"
  4. using namespace pqxx;
  5. // Test program for libpqxx. Verify abort behaviour of transactor.
  6. //
  7. // The program will attempt to add an entry to a table called "pqxxevents",
  8. // with a key column called "year"--and then abort the change.
  9. //
  10. // Note for the superstitious: the numbering for this test program is pure
  11. // coincidence.
  12. namespace
  13. {
  14. // Let's take a boring year that is not going to be in the "pqxxevents" table
  15. constexpr unsigned int BoringYear = 1977;
  16. // Count events and specifically events occurring in Boring Year, leaving the
  17. // former count in the result pair's first member, and the latter in second.
  18. std::pair<int, int> count_events(connection &conn, std::string const &table)
  19. {
  20. work tx{conn};
  21. std::string const count_query{"SELECT count(*) FROM " + table};
  22. return std::make_pair(
  23. tx.query_value<int>(count_query),
  24. tx.query_value<int>(count_query + " WHERE year=" + to_string(BoringYear)));
  25. }
  26. struct deliberate_error : std::exception
  27. {};
  28. void failed_insert(connection &C, std::string const &table)
  29. {
  30. work tx(C);
  31. result R = tx.exec0(
  32. "INSERT INTO " + table + " VALUES (" + to_string(BoringYear) +
  33. ", "
  34. "'yawn')");
  35. PQXX_CHECK_EQUAL(R.affected_rows(), 1, "Bad affected_rows().");
  36. throw deliberate_error();
  37. }
  38. void test_013()
  39. {
  40. connection conn;
  41. {
  42. work tx{conn};
  43. test::create_pqxxevents(tx);
  44. tx.commit();
  45. }
  46. std::string const Table{"pqxxevents"};
  47. auto const Before{
  48. perform([&conn, &Table] { return count_events(conn, Table); })};
  49. PQXX_CHECK_EQUAL(
  50. Before.second, 0,
  51. "Already have event for " + to_string(BoringYear) + "--can't test.");
  52. quiet_errorhandler d(conn);
  53. PQXX_CHECK_THROWS(
  54. perform([&conn, &Table] { failed_insert(conn, Table); }), deliberate_error,
  55. "Failing transactor failed to throw correct exception.");
  56. auto const After{
  57. perform([&conn, &Table] { return count_events(conn, Table); })};
  58. PQXX_CHECK_EQUAL(
  59. After.first, Before.first, "abort() didn't reset event count.");
  60. PQXX_CHECK_EQUAL(
  61. After.second, Before.second,
  62. "abort() didn't reset event count for " + to_string(BoringYear));
  63. }
  64. PQXX_REGISTER_TEST(test_013);
  65. } // namespace