statement_parameters.hxx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /** Common implementation for statement parameter lists.
  2. *
  3. * These are used for both prepared statements and parameterized statements.
  4. *
  5. * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you.
  6. *
  7. * Copyright (c) 2000-2022, Jeroen T. Vermeulen.
  8. *
  9. * See COPYING for copyright license. If you did not receive a file called
  10. * COPYING with this source code, please notify the distributor of this
  11. * mistake, or contact the author.
  12. */
  13. #ifndef PQXX_H_STATEMENT_PARAMETER
  14. #define PQXX_H_STATEMENT_PARAMETER
  15. #include <cstring>
  16. #include <functional>
  17. #include <iterator>
  18. #include <string>
  19. #include <vector>
  20. #include "pqxx/binarystring.hxx"
  21. #include "pqxx/strconv.hxx"
  22. #include "pqxx/util.hxx"
  23. namespace pqxx::internal
  24. {
  25. template<typename ITERATOR>
  26. constexpr inline auto const iterator_identity{
  27. [](decltype(*std::declval<ITERATOR>()) x) { return x; }};
  28. /// Marker type: pass a dynamically-determined number of statement parameters.
  29. /** @deprecated Use @ref params instead.
  30. *
  31. * Normally when invoking a prepared or parameterised statement, the number
  32. * of parameters is known at compile time. For instance,
  33. * `t.exec_prepared("foo", 1, "x");` executes statement `foo` with two
  34. * parameters, an `int` and a C string.
  35. *
  36. * But sometimes you may want to pass a number of parameters known only at run
  37. * time. In those cases, a @ref dynamic_params encodes a dynamically
  38. * determined number of parameters. You can mix these with regular, static
  39. * parameter lists, and you can re-use them for multiple statement invocations.
  40. *
  41. * A dynamic_params object does not store copies of its parameters, so make
  42. * sure they remain accessible until you've executed the statement.
  43. *
  44. * The ACCESSOR is an optional callable (such as a lambda). If you pass an
  45. * accessor `a`, then each parameter `p` goes into your statement as `a(p)`.
  46. */
  47. template<typename IT, typename ACCESSOR = decltype(iterator_identity<IT>)>
  48. class dynamic_params
  49. {
  50. public:
  51. /// Wrap a sequence of pointers or iterators.
  52. constexpr dynamic_params(IT begin, IT end) :
  53. m_begin(begin), m_end(end), m_accessor(iterator_identity<IT>)
  54. {}
  55. /// Wrap a sequence of pointers or iterators.
  56. /** This version takes an accessor callable. If you pass an accessor `acc`,
  57. * then any parameter `p` will go into the statement's parameter list as
  58. * `acc(p)`.
  59. */
  60. constexpr dynamic_params(IT begin, IT end, ACCESSOR &acc) :
  61. m_begin(begin), m_end(end), m_accessor(acc)
  62. {}
  63. /// Wrap a container.
  64. template<typename C>
  65. explicit constexpr dynamic_params(C &container) :
  66. dynamic_params(std::begin(container), std::end(container))
  67. {}
  68. /// Wrap a container.
  69. /** This version takes an accessor callable. If you pass an accessor `acc`,
  70. * then any parameter `p` will go into the statement's parameter list as
  71. * `acc(p)`.
  72. */
  73. template<typename C>
  74. explicit constexpr dynamic_params(C &container, ACCESSOR &acc) :
  75. dynamic_params(std::begin(container), std::end(container), acc)
  76. {}
  77. constexpr IT begin() const noexcept { return m_begin; }
  78. constexpr IT end() const noexcept { return m_end; }
  79. constexpr auto access(decltype(*std::declval<IT>()) value) const
  80. -> decltype(std::declval<ACCESSOR>()(value))
  81. {
  82. return m_accessor(value);
  83. }
  84. private:
  85. IT const m_begin, m_end;
  86. ACCESSOR m_accessor = iterator_identity<IT>;
  87. };
  88. /// Internal type: encode statement parameters.
  89. /** Compiles arguments for prepared statements and parameterised queries into
  90. * a format that can be passed into libpq.
  91. *
  92. * Objects of this type are meant to be short-lived: a `c_params` lives and
  93. * dies entirely within the call to execute. So, for example, if you pass in a
  94. * non-null pointer as a parameter, @ref params may simply use that pointer as
  95. * a parameter value, without arranging longer-term storage for the data to
  96. * which it points. All values referenced by parameters must remain "live"
  97. * until the parameterised or prepared statement has been executed.
  98. */
  99. struct PQXX_LIBEXPORT c_params
  100. {
  101. c_params() = default;
  102. /// Copying these objects is pointless and expensive. Don't do it.
  103. c_params(c_params const &) = delete;
  104. c_params(c_params &&) = default;
  105. /// Pre-allocate storage for `n` parameters.
  106. void reserve(std::size_t n) &;
  107. /// As used by libpq: pointers to parameter values.
  108. std::vector<char const *> values;
  109. /// As used by libpq: lengths of non-null arguments, in bytes.
  110. std::vector<int> lengths;
  111. /// As used by libpq: effectively boolean "is this a binary parameter?"
  112. std::vector<format> formats;
  113. };
  114. } // namespace pqxx::internal
  115. #endif