aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libpqxx/include/pqxx/internal
diff options
context:
space:
mode:
authorgalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 11:26:33 +0300
committergalaxycrab <UgnineSirdis@ydb.tech>2023-11-23 12:01:57 +0300
commit44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch)
treecb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /contrib/libs/libpqxx/include/pqxx/internal
parent0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff)
downloadydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz
YQ Connector:test INNER JOIN
Diffstat (limited to 'contrib/libs/libpqxx/include/pqxx/internal')
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/callgate.hxx79
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/encoding_group.hxx46
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/encodings.hxx99
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-dbtransaction.hxx22
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-errorhandler.hxx25
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-largeobject.hxx35
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-notification_receiver.hxx27
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-parameterized_invocation.hxx37
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-pipeline.hxx27
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-prepare-invocation.hxx45
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-reactivation_avoidance_exemption.hxx24
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-sql_cursor.hxx25
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/connection-transaction.hxx77
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/errorhandler-connection.hxx19
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx28
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx30
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/result-connection.hxx20
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/result-creation.hxx28
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/result-row.hxx22
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-sql_cursor.hxx16
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_from.hxx23
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_to.hxx27
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-subtransaction.hxx20
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablereader.hxx23
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablewriter.hxx27
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-transactionfocus.hxx23
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-post.hxx6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-pre.hxx19
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/libpq-forward.hxx34
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/sql_cursor.hxx122
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/statement_parameters.hxx227
-rw-r--r--contrib/libs/libpqxx/include/pqxx/internal/type_utils.hxx211
32 files changed, 1493 insertions, 0 deletions
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/callgate.hxx b/contrib/libs/libpqxx/include/pqxx/internal/callgate.hxx
new file mode 100644
index 0000000000..02ac152636
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/callgate.hxx
@@ -0,0 +1,79 @@
+#ifndef PQXX_H_CALLGATE
+#define PQXX_H_CALLGATE
+
+/*
+Here's what a typical gate class definition looks like:
+
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE @gateclass@ : callgate<@host@>
+{
+ friend class @client@;
+
+ @gateclass@(reference x) : super(x) {}
+
+ // Methods here. Use home() to access the host-class object.
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
+*/
+
+namespace pqxx
+{
+namespace internal
+{
+/// Base class for call gates.
+/**
+ * A call gate defines a limited, private interface on the host class that
+ * specified client classes can access.
+ *
+ * The metaphor works as follows: the gate stands in front of a "home," which is
+ * really a class, and only lets specific friends in.
+ *
+ * To implement a call gate that gives client C access to host H,
+ * - derive a gate class from callgate<H>;
+ * - make the gate class a friend of H;
+ * - make C a friend of the gate class; and
+ * - implement "stuff C can do with H" as private members in the gate class.
+ *
+ * This special kind of "gated" friendship gives C private access to H, but only
+ * through an expressly limited interface. The gate class can access its host
+ * object as home().
+ *
+ * Keep gate classes entirely stateless. They should be ultra-lightweight
+ * wrappers for their host classes, and be optimized away as much as possible by
+ * the compiler. Once you start adding state, you're on a slippery slope away
+ * from the pure, clean, limited interface pattern that gate classes are meant
+ * to implement.
+ *
+ * Ideally, all member functions of the gate class should be one-liners passing
+ * calls straight on to the host class. It can be useful however to break this
+ * rule temporarily during inter-class refactoring.
+ */
+template<typename HOME> class PQXX_PRIVATE callgate
+{
+protected:
+ /// This class, to keep constructors easy.
+ using super = callgate<HOME>;
+ /// A reference to the host class. Helps keep constructors easy.
+ using reference = HOME &;
+
+ callgate(reference x) : m_home(x) {}
+
+ /// The home object. The gate class has full "private" access.
+ reference home() const noexcept { return m_home; }
+
+private:
+ reference m_home;
+};
+} // namespace pqxx::internal
+} // namespace pqxx
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/encoding_group.hxx b/contrib/libs/libpqxx/include/pqxx/internal/encoding_group.hxx
new file mode 100644
index 0000000000..be31d083b4
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/encoding_group.hxx
@@ -0,0 +1,46 @@
+/** Enum type for supporting encodings in libpqxx
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+#ifndef PQXX_H_ENCODING_GROUP
+#define PQXX_H_ENCODING_GROUP
+
+
+namespace pqxx
+{
+namespace internal
+{
+
+// Types of encodings supported by PostgreSQL, see
+// https://www.postgresql.org/docs/current/static/multibyte.html#CHARSET-TABLE
+enum class encoding_group
+{
+ // Handles all single-byte fixed-width encodings
+ MONOBYTE,
+
+ // Multibyte encodings
+ BIG5,
+ EUC_CN,
+ EUC_JP,
+ EUC_JIS_2004,
+ EUC_KR,
+ EUC_TW,
+ GB18030,
+ GBK,
+ JOHAB,
+ MULE_INTERNAL,
+ SJIS,
+ SHIFT_JIS_2004,
+ UHC,
+ UTF8
+};
+
+} // namespace pqxx::internal
+} // namespace pqxx
+
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/encodings.hxx b/contrib/libs/libpqxx/include/pqxx/internal/encodings.hxx
new file mode 100644
index 0000000000..01ca223d48
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/encodings.hxx
@@ -0,0 +1,99 @@
+/** Internal string encodings support for libpqxx
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+#ifndef PQXX_H_ENCODINGS
+#define PQXX_H_ENCODINGS
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/internal/encoding_group.hxx"
+
+#include <string>
+
+
+namespace pqxx
+{
+namespace internal
+{
+const char *name_encoding(int encoding_id);
+
+/// Convert libpq encoding enum or encoding name to its libpqxx group.
+encoding_group enc_group(int /* libpq encoding ID */);
+encoding_group enc_group(const std::string&);
+
+
+/// Function type: "find the end of the current glyph."
+/** This type of function takes a text buffer, and a location in that buffer,
+ * and returns the location one byte past the end of the current glyph.
+ *
+ * The start offset marks the beginning of the current glyph. It must fall
+ * within the buffer.
+ *
+ * There are multiple different glyph scnaner implementations, for different
+ * kinds of encodings.
+ */
+using glyph_scanner_func =
+ std::string::size_type(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start);
+
+
+/// Look up the glyph scanner function for a given encoding group.
+/** To identify the glyph boundaries in a buffer, call this to obtain the
+ * scanner function appropriate for the buffer's encoding. Then, repeatedly
+ * call the scanner function to find the glyphs.
+ */
+PQXX_LIBEXPORT glyph_scanner_func *get_glyph_scanner(encoding_group);
+
+
+/// Find a single-byte "needle" character in a "haystack" text buffer.
+std::string::size_type find_with_encoding(
+ encoding_group enc,
+ const std::string& haystack,
+ char needle,
+ std::string::size_type start = 0
+);
+
+
+PQXX_LIBEXPORT std::string::size_type find_with_encoding(
+ encoding_group enc,
+ const std::string& haystack,
+ const std::string& needle,
+ std::string::size_type start = 0
+);
+
+
+/// Iterate over the glyphs in a buffer.
+/** Scans the glyphs in the buffer, and for each, passes its begin and its
+ * one-past-end pointers to @c callback.
+ */
+template<typename CALLABLE> PQXX_LIBEXPORT inline void for_glyphs(
+ encoding_group enc,
+ CALLABLE callback,
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start = 0
+)
+{
+ const auto scan = get_glyph_scanner(enc);
+ for (
+ std::string::size_type here = start, next;
+ here < buffer_len;
+ here = next
+ )
+ {
+ next = scan(buffer, buffer_len, here);
+ callback(buffer + here, buffer + next);
+ }
+}
+} // namespace pqxx::internal
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-dbtransaction.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-dbtransaction.hxx
new file mode 100644
index 0000000000..8ef2e4744f
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-dbtransaction.hxx
@@ -0,0 +1,22 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+class dbtransaction;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_dbtransaction : callgate<connection_base>
+{
+ friend class pqxx::dbtransaction;
+
+ connection_dbtransaction(reference x) : super(x) {}
+
+ int get_reactivation_avoidance_count() const noexcept
+ { return home().m_reactivation_avoidance.get(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-errorhandler.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-errorhandler.hxx
new file mode 100644
index 0000000000..9c62704dbe
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-errorhandler.hxx
@@ -0,0 +1,25 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+class connection_base;
+class errorhandler;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_errorhandler : callgate<connection_base>
+{
+ friend class pqxx::errorhandler;
+
+ connection_errorhandler(reference x) : super(x) {}
+
+ void register_errorhandler(errorhandler *h)
+ { home().register_errorhandler(h); }
+ void unregister_errorhandler(errorhandler *h)
+ { home().unregister_errorhandler(h); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-largeobject.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-largeobject.hxx
new file mode 100644
index 0000000000..e4f3b28fcc
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-largeobject.hxx
@@ -0,0 +1,35 @@
+#include <string>
+
+#include <pqxx/internal/callgate.hxx>
+#include <pqxx/internal/libpq-forward.hxx>
+
+namespace pqxx
+{
+class largeobject;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_largeobject : callgate<connection_base>
+{
+ friend class pqxx::largeobject;
+
+ connection_largeobject(reference x) : super(x) {}
+
+ pq::PGconn *raw_connection() const { return home().raw_connection(); }
+};
+
+
+class PQXX_PRIVATE const_connection_largeobject :
+ callgate<const connection_base>
+{
+ friend class pqxx::largeobject;
+
+ const_connection_largeobject(reference x) : super(x) {}
+
+ std::string error_message() const { return home().err_msg(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-notification_receiver.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-notification_receiver.hxx
new file mode 100644
index 0000000000..d03f048f37
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-notification_receiver.hxx
@@ -0,0 +1,27 @@
+#include <pqxx/internal/callgate.hxx>
+
+#include <pqxx/connection_base>
+
+
+namespace pqxx
+{
+class notification_receiver;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_notification_receiver : callgate<connection_base>
+{
+ friend class pqxx::notification_receiver;
+
+ connection_notification_receiver(reference x) : super(x) {}
+
+ void add_receiver(notification_receiver *receiver)
+ { home().add_receiver(receiver); }
+ void remove_receiver(notification_receiver *receiver) noexcept
+ { home().remove_receiver(receiver); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-parameterized_invocation.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-parameterized_invocation.hxx
new file mode 100644
index 0000000000..364c5b6dac
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-parameterized_invocation.hxx
@@ -0,0 +1,37 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+class connection_base;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_parameterized_invocation :
+ callgate<connection_base>
+{
+ friend class pqxx::internal::parameterized_invocation;
+
+ connection_parameterized_invocation(reference x) : super(x) {}
+
+ result parameterized_exec(
+ const std::string &query,
+ const char *const params[],
+ const int paramlengths[],
+ const int binaries[],
+ int nparams)
+ {
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ return home().parameterized_exec(
+ query,
+ params,
+ paramlengths,
+ binaries,
+ nparams);
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-pipeline.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-pipeline.hxx
new file mode 100644
index 0000000000..d7d42ef981
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-pipeline.hxx
@@ -0,0 +1,27 @@
+#include <pqxx/internal/callgate.hxx>
+#include "pqxx/internal/libpq-forward.hxx"
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_pipeline : callgate<connection_base>
+{
+ friend class pqxx::pipeline;
+
+ connection_pipeline(reference x) : super(x) {}
+
+ void start_exec(const std::string &query) { home().start_exec(query); }
+ pqxx::internal::pq::PGresult *get_result() { return home().get_result(); }
+ void cancel_query() { home().cancel_query(); }
+
+ bool consume_input() noexcept { return home().consume_input(); }
+ bool is_busy() const noexcept { return home().is_busy(); }
+
+ int encoding_id() { return home().encoding_id(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-prepare-invocation.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-prepare-invocation.hxx
new file mode 100644
index 0000000000..c1c29583cc
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-prepare-invocation.hxx
@@ -0,0 +1,45 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace prepare
+{
+class invocation;
+} // namespace pqxx::prepare
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_prepare_invocation : callgate<connection_base>
+{
+ friend class pqxx::prepare::invocation;
+
+ connection_prepare_invocation(reference x) : super(x) {}
+
+ /// @deprecated To be replaced by exec_prepared.
+ result prepared_exec(
+ const std::string &statement,
+ const char *const params[],
+ const int paramlengths[],
+ const int binary[],
+ int nparams,
+ result_format format)
+ {
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ return home().prepared_exec(
+ statement,
+ params,
+ paramlengths,
+ binary,
+ nparams,
+ format);
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ }
+
+ bool prepared_exists(const std::string &statement) const
+ { return home().prepared_exists(statement); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-reactivation_avoidance_exemption.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-reactivation_avoidance_exemption.hxx
new file mode 100644
index 0000000000..48ef89a46e
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-reactivation_avoidance_exemption.hxx
@@ -0,0 +1,24 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+class reactivation_avoidance_exemption;
+
+namespace gate
+{
+class PQXX_PRIVATE connection_reactivation_avoidance_exemption :
+ callgate<connection_base>
+{
+ friend class pqxx::internal::reactivation_avoidance_exemption;
+
+ connection_reactivation_avoidance_exemption(reference x) : super(x) {}
+
+ int get_counter() const { return home().m_reactivation_avoidance.get(); }
+ void add_counter(int x) const { home().m_reactivation_avoidance.add(x); }
+ void clear_counter() { home().m_reactivation_avoidance.clear(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-sql_cursor.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-sql_cursor.hxx
new file mode 100644
index 0000000000..bb2cfee177
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-sql_cursor.hxx
@@ -0,0 +1,25 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+class sql_cursor;
+
+namespace gate
+{
+class PQXX_PRIVATE connection_sql_cursor : callgate<connection_base>
+{
+ friend class pqxx::internal::sql_cursor;
+
+ connection_sql_cursor(reference x) : super(x) {}
+
+ result exec(const char query[], int retries)
+ { return home().exec(query, retries); }
+
+ void add_reactivation_avoidance_count(int n)
+ { home().add_reactivation_avoidance_count(n); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-transaction.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-transaction.hxx
new file mode 100644
index 0000000000..f2aaac07f7
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/connection-transaction.hxx
@@ -0,0 +1,77 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+class connection_base;
+
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE connection_transaction : callgate<connection_base>
+{
+ friend class pqxx::transaction_base;
+
+ connection_transaction(reference x) : super(x) {}
+
+ result exec(const char query[], int retries)
+ { return home().exec(query, retries); }
+ void register_transaction(transaction_base *t)
+ { home().register_transaction(t); }
+ void unregister_transaction(transaction_base *t) noexcept
+ { home().unregister_transaction(t); }
+
+ bool read_copy_line(std::string &line)
+ { return home().read_copy_line(line); }
+ void write_copy_line(const std::string &line)
+ { home().write_copy_line(line); }
+ void end_copy_write() { home().end_copy_write(); }
+
+ std::string raw_get_var(const std::string &var)
+ { return home().raw_get_var(var); }
+ void raw_set_var(const std::string &var, const std::string &value)
+ { home().raw_set_var(var, value); }
+ void add_variables(const std::map<std::string, std::string> &vars)
+ { home().add_variables(vars); }
+
+ /// @deprecated To be replaced by exec_prepared.
+ result prepared_exec(
+ const std::string &statement,
+ const char *const params[],
+ const int paramlengths[],
+ const int binaries[],
+ int nparams)
+ {
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ return home().prepared_exec(
+ statement,
+ params,
+ paramlengths,
+ binaries,
+ nparams,
+ result_format::text);
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ }
+
+ result exec_prepared(
+ const std::string &statement,
+ const internal::params &args,
+ result_format format)
+ {
+ return home().exec_prepared(statement, args, format);
+ }
+
+ result exec_params(const std::string &query, const internal::params &args)
+ {
+ return home().exec_params(query, args);
+ }
+
+ bool prepared_exists(const std::string &statement) const
+ { return home().prepared_exists(statement); }
+
+ void take_reactivation_avoidance(int counter)
+ { home().m_reactivation_avoidance.add(counter); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/errorhandler-connection.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/errorhandler-connection.hxx
new file mode 100644
index 0000000000..1b118e5610
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/errorhandler-connection.hxx
@@ -0,0 +1,19 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE errorhandler_connection_base : callgate<errorhandler>
+{
+ friend class pqxx::connection_base;
+
+ errorhandler_connection_base(reference x) : super(x) {}
+
+ void unregister() noexcept { home().unregister(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx
new file mode 100644
index 0000000000..9c17cf2916
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/icursor_iterator-icursorstream.hxx
@@ -0,0 +1,28 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE icursor_iterator_icursorstream : callgate<icursor_iterator>
+{
+ friend class pqxx::icursorstream;
+
+ icursor_iterator_icursorstream(reference x) : super(x) {}
+
+ icursor_iterator::difference_type pos() const noexcept
+ { return home().pos(); }
+
+ icursor_iterator *get_prev() { return home().m_prev; }
+ void set_prev(icursor_iterator *i) { home().m_prev = i; }
+
+ icursor_iterator *get_next() { return home().m_next; }
+ void set_next(icursor_iterator *i) { home().m_next = i; }
+
+ void fill(const result &r) { home().fill(r); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx
new file mode 100644
index 0000000000..8f28336bb5
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/icursorstream-icursor_iterator.hxx
@@ -0,0 +1,30 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE icursorstream_icursor_iterator : callgate<icursorstream>
+{
+ friend class pqxx::icursor_iterator;
+
+ icursorstream_icursor_iterator(reference x) : super(x) {}
+
+ void insert_iterator(icursor_iterator *i) noexcept
+ { home().insert_iterator(i); }
+
+ void remove_iterator(icursor_iterator *i) const noexcept
+ { home().remove_iterator(i); }
+
+ icursorstream::size_type forward() { return home().forward(); }
+ icursorstream::size_type forward(icursorstream::size_type n)
+ { return home().forward(n); }
+
+ void service_iterators(icursorstream::difference_type p)
+ { home().service_iterators(p); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/result-connection.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-connection.hxx
new file mode 100644
index 0000000000..76c8e7a1f1
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-connection.hxx
@@ -0,0 +1,20 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE result_connection : callgate<const result>
+{
+ friend class pqxx::connection_base;
+
+ result_connection(reference x) : super(x) {}
+
+ operator bool() const { return bool(home()); }
+ bool operator!() const { return not home(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/result-creation.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-creation.hxx
new file mode 100644
index 0000000000..6d5671c529
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-creation.hxx
@@ -0,0 +1,28 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE result_creation : callgate<const result>
+{
+ friend class pqxx::connection_base;
+ friend class pqxx::pipeline;
+
+ result_creation(reference x) : super(x) {}
+
+ static result create(
+ internal::pq::PGresult *rhs,
+ const std::string &query,
+ encoding_group enc)
+ {
+ return result(rhs, query, enc);
+ }
+
+ void check_status() const { return home().check_status(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/result-row.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-row.hxx
new file mode 100644
index 0000000000..692d3b5f5b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/result-row.hxx
@@ -0,0 +1,22 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+class row;
+
+namespace gate
+{
+class PQXX_PRIVATE result_row : callgate<result>
+{
+ friend class pqxx::row;
+
+ result_row(reference x) : super(x) {}
+
+ operator bool()
+ { return bool(home()); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-sql_cursor.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-sql_cursor.hxx
new file mode 100644
index 0000000000..878b171b95
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-sql_cursor.hxx
@@ -0,0 +1,16 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_sql_cursor : callgate<transaction_base>
+{
+ friend class pqxx::internal::sql_cursor;
+ transaction_sql_cursor(reference x) : super(x) {}
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_from.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_from.hxx
new file mode 100644
index 0000000000..6345543dda
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_from.hxx
@@ -0,0 +1,23 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_stream_from : callgate<transaction_base>
+{
+ friend class pqxx::stream_from;
+
+ transaction_stream_from(reference x) : super(x) {}
+
+ void BeginCopyRead(const std::string &table, const std::string &columns)
+ { home().BeginCopyRead(table, columns); }
+
+ bool read_copy_line(std::string &line)
+ { return home().read_copy_line(line); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_to.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_to.hxx
new file mode 100644
index 0000000000..6ee9e9b7d6
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-stream_to.hxx
@@ -0,0 +1,27 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_stream_to : callgate<transaction_base>
+{
+ friend class pqxx::stream_to;
+
+ transaction_stream_to(reference x) : super(x) {}
+
+ void BeginCopyWrite(
+ const std::string &table,
+ const std::string &columns = std::string{})
+ { home().BeginCopyWrite(table, columns); }
+
+ void write_copy_line(const std::string &line)
+ { home().write_copy_line(line); }
+
+ void end_copy_write() { home().end_copy_write(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-subtransaction.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-subtransaction.hxx
new file mode 100644
index 0000000000..243f47a798
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-subtransaction.hxx
@@ -0,0 +1,20 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_subtransaction : callgate<transaction_base>
+{
+ friend class pqxx::subtransaction;
+
+ transaction_subtransaction(reference x) : super(x) {}
+
+ void add_reactivation_avoidance_count(int n)
+ { home().m_reactivation_avoidance.add(n); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablereader.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablereader.hxx
new file mode 100644
index 0000000000..6946d36391
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablereader.hxx
@@ -0,0 +1,23 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_tablereader : callgate<transaction_base>
+{
+ friend class pqxx::tablereader;
+
+ transaction_tablereader(reference x) : super(x) {}
+
+ void BeginCopyRead(const std::string &table, const std::string &columns)
+ { home().BeginCopyRead(table, columns); }
+
+ bool read_copy_line(std::string &line)
+ { return home().read_copy_line(line); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablewriter.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablewriter.hxx
new file mode 100644
index 0000000000..3256090a2f
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-tablewriter.hxx
@@ -0,0 +1,27 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_tablewriter : callgate<transaction_base>
+{
+ friend class pqxx::tablewriter;
+
+ transaction_tablewriter(reference x) : super(x) {}
+
+ void BeginCopyWrite(
+ const std::string &table,
+ const std::string &columns = std::string{})
+ { home().BeginCopyWrite(table, columns); }
+
+ void write_copy_line(const std::string &line)
+ { home().write_copy_line(line); }
+
+ void end_copy_write() { home().end_copy_write(); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-transactionfocus.hxx b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-transactionfocus.hxx
new file mode 100644
index 0000000000..9ea117a2ea
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/gates/transaction-transactionfocus.hxx
@@ -0,0 +1,23 @@
+#include <pqxx/internal/callgate.hxx>
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class PQXX_PRIVATE transaction_transactionfocus : callgate<transaction_base>
+{
+ friend class pqxx::internal::transactionfocus;
+
+ transaction_transactionfocus(reference x) : super(x) {}
+
+ void register_focus(transactionfocus *focus) { home().register_focus(focus); }
+ void unregister_focus(transactionfocus *focus) noexcept
+ { home().unregister_focus(focus); }
+ void register_pending_error(const std::string &error)
+ { home().register_pending_error(error); }
+};
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-post.hxx b/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-post.hxx
new file mode 100644
index 0000000000..32a84b2751
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-post.hxx
@@ -0,0 +1,6 @@
+/// End a code block started by "ignore-deprecated-pre.hxx".
+#if defined(__GNUC__)
+
+#pragma GCC diagnostic pop
+
+#endif // __GNUC__
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-pre.hxx b/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-pre.hxx
new file mode 100644
index 0000000000..9ada1b7205
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/ignore-deprecated-pre.hxx
@@ -0,0 +1,19 @@
+/** Start a block of deprecated code which may call other deprecated code.
+ *
+ * Most compilers will emit warnings when deprecated code is invoked from
+ * non-deprecated code. But some compilers (notably gcc) will always emit the
+ * warning, even when the calling code is also deprecated.
+ *
+ * This header starts a block where those warnings are suppressed. It can be
+ * included inside a code block.
+ *
+ * Always match the #include with a closing #include of
+ * "ignore-deprecated-post.hxx". To avoid mistakes, keep the enclosed area as
+ * small as possible.
+ */
+#if defined(__GNUC__)
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#endif // __GNUC__
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/libpq-forward.hxx b/contrib/libs/libpqxx/include/pqxx/internal/libpq-forward.hxx
new file mode 100644
index 0000000000..394f3068b2
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/libpq-forward.hxx
@@ -0,0 +1,34 @@
+/** Minimal forward declarations of libpq types needed in libpqxx headers.
+ *
+ * DO NOT INCLUDE THIS FILE when building client programs.
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+extern "C"
+{
+struct pg_conn;
+struct pg_result;
+struct pgNotify;
+}
+
+namespace pqxx
+{
+namespace internal
+{
+/// Forward declarations of libpq types as needed in libpqxx headers
+namespace pq
+{
+using PGconn = pg_conn;
+using PGresult = pg_result;
+using PGnotify = pgNotify;
+using PQnoticeProcessor = void (*)(void *, const char *);
+}
+}
+
+/// PostgreSQL database row identifier
+using oid = unsigned int;
+} // extern "C"
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/sql_cursor.hxx b/contrib/libs/libpqxx/include/pqxx/internal/sql_cursor.hxx
new file mode 100644
index 0000000000..828f9d3e6e
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/sql_cursor.hxx
@@ -0,0 +1,122 @@
+/** Internal wrapper for SQL cursors. Supports higher-level cursor classes.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you.
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this
+ * mistake, or contact the author.
+ */
+#ifndef PQXX_H_SQL_CURSOR
+#define PQXX_H_SQL_CURSOR
+
+namespace pqxx
+{
+namespace internal
+{
+/// Cursor with SQL positioning semantics.
+/** Thin wrapper around an SQL cursor, with SQL's ideas of positioning.
+ *
+ * SQL cursors have pre-increment/pre-decrement semantics, with on either end of
+ * the result set a special position that does not repesent a row. This class
+ * models SQL cursors for the purpose of implementing more C++-like semantics on
+ * top.
+ *
+ * Positions of actual rows are numbered starting at 1. Position 0 exists but
+ * does not refer to a row. There is a similar non-row position at the end of
+ * the result set.
+ *
+ * Don't use this at home. You deserve better. Use the stateles_cursor
+ * instead.
+ */
+class PQXX_LIBEXPORT sql_cursor : public cursor_base
+{
+public:
+ sql_cursor(
+ transaction_base &t,
+ const std::string &query,
+ const std::string &cname,
+ cursor_base::accesspolicy ap,
+ cursor_base::updatepolicy up,
+ cursor_base::ownershippolicy op,
+ bool hold,
+ result_format format = result_format::text);
+
+ sql_cursor(
+ transaction_base &t,
+ const std::string &cname,
+ cursor_base::ownershippolicy op);
+
+ ~sql_cursor() noexcept { close(); }
+
+ result fetch(difference_type rows, difference_type &displacement);
+ result fetch(difference_type rows)
+ { difference_type d=0; return fetch(rows, d); }
+ difference_type move(difference_type rows, difference_type &displacement);
+ difference_type move(difference_type rows)
+ { difference_type d=0; return move(rows, d); }
+
+ /// Current position, or -1 for unknown
+ /**
+ * The starting position, just before the first row, counts as position zero.
+ *
+ * Position may be unknown if (and only if) this cursor was adopted, and has
+ * never hit its starting position (position zero).
+ */
+ difference_type pos() const noexcept { return m_pos; }
+
+ /// End position, or -1 for unknown
+ /**
+ * Returns the final position, just after the last row in the result set. The
+ * starting position, just before the first row, counts as position zero.
+ *
+ * End position is unknown until it is encountered during use.
+ */
+ difference_type endpos() const noexcept { return m_endpos; }
+
+ /// Return zero-row result for this cursor
+ const result &empty_result() const noexcept { return m_empty_result; }
+
+ void close() noexcept;
+
+private:
+ difference_type adjust(difference_type hoped, difference_type actual);
+ static std::string stridestring(difference_type);
+ /// Initialize cached empty result. Call only at beginning or end!
+ void init_empty_result(transaction_base &);
+
+ /// Connection this cursor lives in
+ connection_base &m_home;
+
+ /// Zero-row result from this cursor (or plain empty one if cursor is adopted)
+ result m_empty_result;
+
+ result m_cached_current_row;
+
+ /// Is this cursor adopted (as opposed to created by this cursor object)?
+ bool m_adopted;
+
+ /// Will this cursor object destroy its SQL cursor when it dies?
+ cursor_base::ownershippolicy m_ownership;
+
+ /// At starting position (-1), somewhere in the middle (0), or past end (1)
+ int m_at_end;
+
+ /// Position, or -1 for unknown
+ difference_type m_pos;
+
+ /// End position, or -1 for unknown
+ difference_type m_endpos = -1;
+};
+
+
+PQXX_LIBEXPORT result_size_type obtain_stateless_cursor_size(sql_cursor &);
+PQXX_LIBEXPORT result stateless_cursor_retrieve(
+ sql_cursor &,
+ result::difference_type size,
+ result::difference_type begin_pos,
+ result::difference_type end_pos);
+} // namespace internal
+} // namespace pqxx
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/statement_parameters.hxx b/contrib/libs/libpqxx/include/pqxx/internal/statement_parameters.hxx
new file mode 100644
index 0000000000..8c80f6df48
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/statement_parameters.hxx
@@ -0,0 +1,227 @@
+/** Common implementation for statement parameter lists.
+ *
+ * These are used for both prepared statements and parameterized statements.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY. Other headers include it for you.
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+#ifndef PQXX_H_STATEMENT_PARAMETER
+#define PQXX_H_STATEMENT_PARAMETER
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <cstring>
+#include <iterator>
+#include <string>
+#include <vector>
+
+#include "pqxx/binarystring"
+#include "pqxx/strconv"
+#include "pqxx/util"
+
+#include "pqxx/internal/type_utils.hxx"
+
+
+namespace pqxx
+{
+namespace internal
+{
+/// Marker type: pass a dynamically-determined number of statement parameters.
+/** Normally when invoking a prepared or parameterised statement, the number
+ * of parameters is known at compile time. For instance,
+ * @c t.exec_prepared("foo", 1, "x"); executes statement @c foo with two
+ * parameters, an @c int and a C string.
+ *
+ * But sometimes you may want to pass a number of parameters known only at run
+ * time. In those cases, a @c dynamic_params encodes a dynamically
+ * determined number of parameters.
+ */
+template<typename IT> class dynamic_params
+{
+public:
+ /// Wrap a sequence of pointers or iterators.
+ dynamic_params(IT begin, IT end) : m_begin(begin), m_end(end) {}
+
+ /// Wrap a container.
+ template<typename C> explicit dynamic_params(const C &container) :
+ m_begin(std::begin(container)),
+ m_end(std::end(container))
+ {}
+
+ IT begin() const { return m_begin; }
+ IT end() const { return m_end; }
+
+private:
+ const IT m_begin, m_end;
+};
+
+
+class PQXX_LIBEXPORT statement_parameters
+{
+protected:
+ statement_parameters() =default;
+ statement_parameters &operator=(const statement_parameters &) =delete;
+
+ void add_param() { this->add_checked_param("", false, false); }
+ template<typename T> void add_param(const T &v, bool nonnull)
+ {
+ nonnull = (nonnull && not pqxx::string_traits<T>::is_null(v));
+ this->add_checked_param(
+ (nonnull ? pqxx::to_string(v) : ""),
+ nonnull,
+ false);
+ }
+ void add_binary_param(const binarystring &b, bool nonnull)
+ { this->add_checked_param(b.str(), nonnull, true); }
+
+ /// Marshall parameter values into C-compatible arrays for passing to libpq.
+ int marshall(
+ std::vector<const char *> &values,
+ std::vector<int> &lengths,
+ std::vector<int> &binaries) const;
+
+private:
+ void add_checked_param(const std::string &value, bool nonnull, bool binary);
+
+ std::vector<std::string> m_values;
+ std::vector<bool> m_nonnull;
+ std::vector<bool> m_binary;
+};
+
+
+/// Internal type: encode statement parameters.
+/** Compiles arguments for prepared statements and parameterised queries into
+ * a format that can be passed into libpq.
+ *
+ * Objects of this type are meant to be short-lived. If you pass in a non-null
+ * pointer as a parameter, it may simply use that pointer as a parameter value.
+ */
+struct params
+{
+ /// Construct directly from a series of statement arguments.
+ /** The arrays all default to zero, null, and empty strings.
+ */
+ template<typename ...Args> params(Args && ... args)
+ {
+ strings.reserve(sizeof...(args));
+ lengths.reserve(sizeof...(args));
+ nonnulls.reserve(sizeof...(args));
+ binaries.reserve(sizeof...(args));
+
+ // Start recursively storing parameters.
+ add_fields(std::forward<Args>(args)...);
+ }
+
+ /// Compose a vector of pointers to parameter string values.
+ std::vector<const char *> get_pointers() const
+ {
+ const std::size_t num_fields = lengths.size();
+ std::size_t cur_string = 0, cur_bin_string = 0;
+ std::vector<const char *> pointers(num_fields);
+ for (std::size_t index = 0; index < num_fields; index++)
+ {
+ const char *value;
+ if (binaries[index])
+ {
+ value = bin_strings[cur_bin_string].get();
+ cur_bin_string++;
+ }
+ else if (nonnulls[index])
+ {
+ value = strings[cur_string].c_str();
+ cur_string++;
+ }
+ else
+ {
+ value = nullptr;
+ }
+ pointers[index] = value;
+ }
+ return pointers;
+ }
+
+ /// String values, for string parameters.
+ std::vector<std::string> strings;
+ /// As used by libpq: lengths of non-null arguments, in bytes.
+ std::vector<int> lengths;
+ /// As used by libpq: boolean "is this parameter non-null?"
+ std::vector<int> nonnulls;
+ /// As used by libpq: boolean "is this parameter in binary format?"
+ std::vector<int> binaries;
+ /// Binary string values, for binary parameters.
+ std::vector<pqxx::binarystring> bin_strings;
+
+private:
+ /// Add a non-null string field.
+ void add_field(std::string str)
+ {
+ lengths.push_back(int(str.size()));
+ nonnulls.push_back(1);
+ binaries.push_back(0);
+ strings.emplace_back(std::move(str));
+ }
+
+ /// Compile one argument (specialised for null pointer, a null value).
+ void add_field(std::nullptr_t)
+ {
+ lengths.push_back(0);
+ nonnulls.push_back(0);
+ binaries.push_back(0);
+ }
+
+ /// Compile one argument (specialised for binarystring).
+ void add_field(const binarystring &arg)
+ {
+ lengths.push_back(int(arg.size()));
+ nonnulls.push_back(1);
+ binaries.push_back(1);
+ bin_strings.push_back(arg);
+ }
+
+ /// Compile one argument (default, generic implementation).
+ /** Uses string_traits to represent the argument as a std::string.
+ */
+ template<typename Arg> void add_field(const Arg &arg)
+ {
+ if (string_traits<Arg>::is_null(arg)) add_field(nullptr);
+ else add_field(to_string(arg));
+ }
+
+ /// Compile a dynamic_params object into a dynamic number of parameters.
+ template<typename IT> void add_field(const dynamic_params<IT> &parameters)
+ {
+ for (auto param: parameters) add_field(param);
+ }
+
+ /// Compile argument list.
+ /** This recursively "peels off" the next remaining element, compiles its
+ * information into its final form, and calls itself for the rest of the
+ * list.
+ *
+ * @param arg Current argument to be compiled.
+ * @param args Optional remaining arguments, to be compiled recursively.
+ */
+ template<typename Arg, typename ...More>
+ void add_fields(Arg &&arg, More && ... args)
+ {
+ add_field(std::forward<Arg>(arg));
+ // Compile remaining arguments, if any.
+ add_fields(std::forward<More>(args)...);
+ }
+
+ /// Terminating version of add_fields, at the end of the list.
+ /** Recursion in add_fields ends with this call.
+ */
+ void add_fields() {}
+};
+} // namespace pqxx::internal
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/internal/type_utils.hxx b/contrib/libs/libpqxx/include/pqxx/internal/type_utils.hxx
new file mode 100644
index 0000000000..7bf5528018
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/internal/type_utils.hxx
@@ -0,0 +1,211 @@
+/** Type/template metaprogramming utilities for use internally in libpqxx
+ *
+ * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
+ *
+ * See COPYING for copyright license. If you did not receive a file called
+ * COPYING with this source code, please notify the distributor of this mistake,
+ * or contact the author.
+ */
+#ifndef PQXX_H_TYPE_UTILS
+#define PQXX_H_TYPE_UTILS
+
+#include <memory>
+#include <type_traits>
+
+#if defined(PQXX_HAVE_OPTIONAL)
+#include <optional>
+#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
+#error #include <experimental/optional>
+#endif
+
+#include "pqxx/strconv"
+
+namespace pqxx
+{
+namespace internal
+{
+
+/// Replicate std::void_t<> (available in C++17).
+template<typename... T> using void_t = void;
+
+/// Extract the content type held by an `optional`-like wrapper type.
+/* Replace nested `std::remove_*`s with `std::remove_cvref` in C++20 */
+template<typename T> using inner_type = typename std::remove_cv<
+ typename std::remove_reference<
+ decltype(*std::declval<T>())
+ >::type
+>::type;
+
+/// Does the given type have an `operator *()`?
+template<typename T, typename = void> struct is_derefable : std::false_type {};
+template<typename T> struct is_derefable<T, void_t<
+ // Disable for arrays so they don't erroneously decay to pointers.
+ inner_type<typename std::enable_if<not std::is_array<T>::value, T>::type>
+>> : std::true_type {};
+
+/// Should the given type be treated as an optional-value wrapper type?
+template<typename T, typename = void> struct is_optional : std::false_type {};
+template<typename T> struct is_optional<T, typename std::enable_if<(
+ is_derefable<T>::value
+ // Check if an `explicit operator bool` exists for this type
+ && std::is_constructible<bool, T>::value
+)>::type> : std::true_type {};
+
+/// Can `nullopt_t` implicitly convert to type T?
+template<
+ typename T,
+ typename = void
+> struct takes_std_nullopt : std::false_type {};
+#if defined(PQXX_HAVE_OPTIONAL)
+template<typename T> struct takes_std_nullopt<
+ T,
+ typename std::enable_if<std::is_assignable<T, std::nullopt_t>::value>::type
+> : std::true_type {};
+#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
+template<typename T> struct takes_std_nullopt<
+ T,
+ typename std::enable_if<
+ std::is_assignable<T, std::experimental::nullopt_t>::value
+ >::type
+> : std::true_type {};
+#endif
+
+/// Is type T a `std::tuple<>`?
+template<typename T, typename = void> struct is_tuple : std::false_type {};
+template<typename T> struct is_tuple<
+ T,
+ typename std::enable_if<(std::tuple_size<T>::value >= 0)>::type
+> : std::true_type {};
+
+/// Is type T an iterable container?
+template<typename T, typename = void> struct is_container : std::false_type {};
+template<typename T> struct is_container<
+ T,
+ void_t<
+ decltype(std::begin(std::declval<T>())),
+ decltype(std::end(std::declval<T>())),
+ // Some people might implement a `std::tuple<>` specialization that is
+ // iterable when all the contained types are the same ;)
+ typename std::enable_if<not is_tuple<T>::value>::type
+ >
+> : std::true_type {};
+
+/// Get an appropriate null value for the given type.
+/**
+ * pointer types `nullptr`
+ * `std::optional<>`-like `std::nullopt`
+ * `std::experimental::optional<>`-like `std::experimental::nullopt`
+ * other types `pqxx::string_traits<>::null()`
+ * Users may add support for their own wrapper types following this pattern.
+ */
+template<typename T> constexpr auto null_value()
+ -> typename std::enable_if<
+ (
+ is_optional<T>::value
+ && not takes_std_nullopt<T>::value
+ && std::is_assignable<T, std::nullptr_t>::value
+ ),
+ std::nullptr_t
+ >::type
+{ return nullptr; }
+template<typename T> constexpr auto null_value()
+ -> typename std::enable_if<
+ (not is_optional<T>::value && not takes_std_nullopt<T>::value),
+ decltype(pqxx::string_traits<T>::null())
+ >::type
+{ return pqxx::string_traits<T>::null(); }
+#if defined(PQXX_HAVE_OPTIONAL)
+template<typename T> constexpr auto null_value()
+ -> typename std::enable_if<
+ takes_std_nullopt<T>::value,
+ std::nullopt_t
+ >::type
+{ return std::nullopt; }
+#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
+template<typename T> constexpr auto null_value()
+ -> typename std::enable_if<
+ takes_std_nullopt<T>::value,
+ std::experimental::nullopt_t
+ >::type
+{ return std::experimental::nullopt; }
+#endif
+
+/// Construct an optional-like type from the stored type.
+/**
+ * While these may seem redundant, they are necessary to support smart pointers
+ * as optional storage types in a generic manner. It is suggested NOT to
+ * provide a version for `inner_type<T>*` as that will almost certainly leak
+ * memory.
+ * Users may add support for their own wrapper types following this pattern.
+ */
+// Enabled if the wrapper type can be directly constructed from the wrapped type
+// (e.g. `std::optional<>`); explicitly disabled for raw pointers in case the
+// inner type is convertible to a pointer (e.g. `int`)
+template<typename T, typename V> constexpr auto make_optional(V&& v)
+ -> typename std::enable_if<
+ not std::is_same<T, inner_type<T>*>::value,
+ decltype(T(std::forward<V>(v)))
+ >::type
+{ return T(std::forward<V>(v)); }
+// Enabled if T is a specialization of `std::unique_ptr<>`.
+template<typename T, typename V> constexpr auto make_optional(V&& v)
+ -> typename std::enable_if<
+ std::is_same<T, std::unique_ptr<inner_type<T>>>::value,
+ std::unique_ptr<inner_type<T>>
+ >::type
+{
+ return std::unique_ptr<inner_type<T>>(new inner_type<T>(std::forward<V>(v)));
+}
+// Enabled if T is a specialization of `std::shared_ptr<>`.
+template<typename T, typename V> constexpr auto make_optional(V&& v)
+ -> typename std::enable_if<
+ std::is_same<T, std::shared_ptr<inner_type<T>>>::value,
+ std::shared_ptr<inner_type<T>>
+ >::type
+{ return std::make_shared<inner_type<T>>(std::forward<V>(v)); }
+
+} // namespace pqxx::internal
+} // namespace pqxx
+
+
+// TODO: Move?
+namespace pqxx
+{
+
+/// Meta `pqxx::string_traits` for std::optional-like types.
+template<typename T> struct string_traits<
+ T,
+ typename std::enable_if<internal::is_optional<T>::value>::type
+>
+{
+private:
+ using I = internal::inner_type<T>;
+public:
+ static constexpr const char *name() noexcept
+ { return string_traits<I>::name(); }
+ static constexpr bool has_null() noexcept { return true; }
+ static bool is_null(const T& v)
+ { return (not v || string_traits<I>::is_null(*v)); }
+ static constexpr T null() { return internal::null_value<T>(); }
+ static void from_string(const char Str[], T &Obj)
+ {
+ if (not Str) Obj = null();
+ else
+ {
+ I inner;
+ string_traits<I>::from_string(Str, inner);
+ // Utilize existing memory if possible (e.g. for pointer types).
+ if (Obj) *Obj = inner;
+ // Important to assign to set valid flag for smart optional types.
+ else Obj = internal::make_optional<T>(inner);
+ }
+ }
+ static std::string to_string(const T& Obj)
+ {
+ if (is_null(Obj)) internal::throw_null_conversion(name());
+ return string_traits<I>::to_string(*Obj);
+ }
+};
+
+} // namespace pqxx
+#endif