test70.cxx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <pqxx/pipeline>
  2. #include <pqxx/transaction>
  3. #include "test_helpers.hxx"
  4. using namespace pqxx;
  5. namespace
  6. {
  7. void TestPipeline(pipeline &P, int numqueries)
  8. {
  9. std::string const Q{"SELECT * FROM generate_series(1, 10)"};
  10. result const Empty;
  11. PQXX_CHECK(std::empty(Empty), "Default-constructed result is not empty.");
  12. PQXX_CHECK(
  13. std::empty(Empty.query()), "Default-constructed result has query");
  14. P.retain();
  15. for (int i{numqueries}; i > 0; --i) P.insert(Q);
  16. P.resume();
  17. PQXX_CHECK(
  18. (numqueries == 0) || not std::empty(P), "pipeline::empty() is broken.");
  19. int res{0};
  20. result Prev;
  21. PQXX_CHECK_EQUAL(Prev, Empty, "Default-constructed results are not equal.");
  22. for (int i{numqueries}; i > 0; --i)
  23. {
  24. PQXX_CHECK(not std::empty(P), "Got no results from pipeline.");
  25. auto R{P.retrieve()};
  26. PQXX_CHECK_NOT_EQUAL(R.second, Empty, "Got empty result.");
  27. if (Prev != Empty)
  28. PQXX_CHECK_EQUAL(R.second, Prev, "Results to same query are different.");
  29. Prev = R.second;
  30. PQXX_CHECK_EQUAL(Prev, R.second, "Assignment breaks result equality.");
  31. PQXX_CHECK_EQUAL(R.second.query(), Q, "Result is for unexpected query.");
  32. if (res != 0)
  33. PQXX_CHECK_EQUAL(Prev[0][0].as<int>(), res, "Bad result from pipeline.");
  34. res = Prev[0][0].as<int>();
  35. }
  36. PQXX_CHECK(std::empty(P), "Pipeline was not empty after retrieval.");
  37. }
  38. // Test program for libpqxx. Issue a query repeatedly through a pipeline, and
  39. // compare results. Use retain() and resume() for performance.
  40. void test_070()
  41. {
  42. connection conn;
  43. work tx{conn};
  44. pipeline P(tx);
  45. PQXX_CHECK(std::empty(P), "Pipeline is not empty initially.");
  46. // Try to confuse the pipeline by feeding it a query and flushing
  47. P.retain();
  48. std::string const Q{"SELECT * FROM pg_tables"};
  49. P.insert(Q);
  50. P.flush();
  51. PQXX_CHECK(std::empty(P), "Pipeline was not empty after flush().");
  52. // See if complete() breaks retain() as it should
  53. P.retain();
  54. P.insert(Q);
  55. PQXX_CHECK(not std::empty(P), "Pipeline was empty after insert().");
  56. P.complete();
  57. PQXX_CHECK(not std::empty(P), "complete() emptied pipeline.");
  58. PQXX_CHECK_EQUAL(
  59. P.retrieve().second.query(), Q, "Result is for wrong query.");
  60. PQXX_CHECK(std::empty(P), "Pipeline not empty after retrieve().");
  61. // See if retrieve() breaks retain() when it needs to
  62. P.retain();
  63. P.insert(Q);
  64. PQXX_CHECK_EQUAL(
  65. P.retrieve().second.query(), Q, "Got result for wrong query.");
  66. // See if regular retain()/resume() works
  67. for (int i{0}; i < 5; ++i) TestPipeline(P, i);
  68. // See if retrieve() fails on an empty pipeline, as it should
  69. quiet_errorhandler d(conn);
  70. PQXX_CHECK_THROWS_EXCEPTION(
  71. P.retrieve(), "Empty pipeline allows retrieve().");
  72. }
  73. } // namespace
  74. PQXX_REGISTER_TEST(test_070);