test26.cxx 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <iostream>
  2. #include <map>
  3. #include <pqxx/nontransaction>
  4. #include <pqxx/transaction>
  5. #include <pqxx/transactor>
  6. #include "test_helpers.hxx"
  7. using namespace pqxx;
  8. // Example program for libpqxx. Modify the database, retaining transactional
  9. // integrity using the transactor framework.
  10. namespace
  11. {
  12. // Convert year to 4-digit format.
  13. int To4Digits(int Y)
  14. {
  15. int Result{Y};
  16. PQXX_CHECK(Y >= 0, "Negative year: " + to_string(Y));
  17. if (Y < 70)
  18. Result += 2000;
  19. else if (Y < 100)
  20. Result += 1900;
  21. else
  22. PQXX_CHECK(Y >= 1970, "Unexpected year: " + to_string(Y));
  23. return Result;
  24. }
  25. // Transaction definition for year-field update. Returns conversions done.
  26. std::map<int, int> update_years(connection &C)
  27. {
  28. std::map<int, int> conversions;
  29. work tx{C};
  30. // Note all different years currently occurring in the table, writing them
  31. // and their correct mappings to m_conversions
  32. for (auto const &[y] :
  33. tx.stream<std::optional<int>>("SELECT year FROM pqxxevents"))
  34. {
  35. // Read year, and if it is non-null, note its converted value
  36. if (bool(y))
  37. conversions[y.value()] = To4Digits(y.value());
  38. }
  39. // For each occurring year, write converted date back to whereever it may
  40. // occur in the table. Since we're in a transaction, any changes made by
  41. // others at the same time will not affect us.
  42. for (auto const &c : conversions)
  43. tx.exec0(
  44. "UPDATE pqxxevents "
  45. "SET year=" +
  46. to_string(c.second) +
  47. " "
  48. "WHERE year=" +
  49. to_string(c.first));
  50. tx.commit();
  51. return conversions;
  52. }
  53. void test_026()
  54. {
  55. connection conn;
  56. {
  57. nontransaction tx{conn};
  58. test::create_pqxxevents(tx);
  59. tx.commit();
  60. }
  61. // Perform (an instantiation of) the UpdateYears transactor we've defined
  62. // in the code above. This is where the work gets done.
  63. auto const conversions{perform([&conn] { return update_years(conn); })};
  64. PQXX_CHECK(not std::empty(conversions), "No conversions done!");
  65. }
  66. PQXX_REGISTER_TEST(test_026);
  67. } // namespace