sql_cursor.hxx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /** Internal wrapper for SQL cursors. Supports higher-level cursor classes.
  2. *
  3. * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you.
  4. *
  5. * Copyright (c) 2000-2022, Jeroen T. Vermeulen.
  6. *
  7. * See COPYING for copyright license. If you did not receive a file called
  8. * COPYING with this source code, please notify the distributor of this
  9. * mistake, or contact the author.
  10. */
  11. #ifndef PQXX_H_SQL_CURSOR
  12. #define PQXX_H_SQL_CURSOR
  13. namespace pqxx::internal
  14. {
  15. /// Cursor with SQL positioning semantics.
  16. /** Thin wrapper around an SQL cursor, with SQL's ideas of positioning.
  17. *
  18. * SQL cursors have pre-increment/pre-decrement semantics, with on either end
  19. * of the result set a special position that does not repesent a row. This
  20. * class models SQL cursors for the purpose of implementing more C++-like
  21. * semantics on top.
  22. *
  23. * Positions of actual rows are numbered starting at 1. Position 0 exists but
  24. * does not refer to a row. There is a similar non-row position at the end of
  25. * the result set.
  26. *
  27. * Don't use this at home. You deserve better. Use the stateles_cursor
  28. * instead.
  29. */
  30. class PQXX_LIBEXPORT sql_cursor : public cursor_base
  31. {
  32. public:
  33. sql_cursor(
  34. transaction_base &t, std::string_view query, std::string_view cname,
  35. cursor_base::access_policy ap, cursor_base::update_policy up,
  36. cursor_base::ownership_policy op, bool hold);
  37. sql_cursor(
  38. transaction_base &t, std::string_view cname,
  39. cursor_base::ownership_policy op);
  40. ~sql_cursor() noexcept { close(); }
  41. result fetch(difference_type rows, difference_type &displacement);
  42. result fetch(difference_type rows)
  43. {
  44. difference_type d = 0;
  45. return fetch(rows, d);
  46. }
  47. difference_type move(difference_type rows, difference_type &displacement);
  48. difference_type move(difference_type rows)
  49. {
  50. difference_type d = 0;
  51. return move(rows, d);
  52. }
  53. /// Current position, or -1 for unknown
  54. /**
  55. * The starting position, just before the first row, counts as position zero.
  56. *
  57. * Position may be unknown if (and only if) this cursor was adopted, and has
  58. * never hit its starting position (position zero).
  59. */
  60. difference_type pos() const noexcept { return m_pos; }
  61. /// End position, or -1 for unknown
  62. /**
  63. * Returns the final position, just after the last row in the result set. The
  64. * starting position, just before the first row, counts as position zero.
  65. *
  66. * End position is unknown until it is encountered during use.
  67. */
  68. difference_type endpos() const noexcept { return m_endpos; }
  69. /// Return zero-row result for this cursor.
  70. result const &empty_result() const noexcept { return m_empty_result; }
  71. void close() noexcept;
  72. private:
  73. difference_type adjust(difference_type hoped, difference_type actual);
  74. static std::string stridestring(difference_type);
  75. /// Initialize cached empty result. Call only at beginning or end!
  76. void init_empty_result(transaction_base &);
  77. /// Connection in which this cursor lives.
  78. connection &m_home;
  79. /// Zero-row result from this cursor (or plain empty one if cursor is
  80. /// adopted)
  81. result m_empty_result;
  82. result m_cached_current_row;
  83. /// Is this cursor adopted (as opposed to created by this cursor object)?
  84. bool m_adopted;
  85. /// Will this cursor object destroy its SQL cursor when it dies?
  86. cursor_base::ownership_policy m_ownership;
  87. /// At starting position (-1), somewhere in the middle (0), or past end (1)
  88. int m_at_end;
  89. /// Position, or -1 for unknown
  90. difference_type m_pos;
  91. /// End position, or -1 for unknown
  92. difference_type m_endpos = -1;
  93. };
  94. PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &);
  95. PQXX_LIBEXPORT result stateless_cursor_retrieve(
  96. sql_cursor &, result::difference_type size,
  97. result::difference_type begin_pos, result::difference_type end_pos);
  98. } // namespace pqxx::internal
  99. #endif