aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libpqxx
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
parent0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff)
downloadydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz
YQ Connector:test INNER JOIN
Diffstat (limited to 'contrib/libs/libpqxx')
-rw-r--r--contrib/libs/libpqxx/AUTHORS4
-rw-r--r--contrib/libs/libpqxx/CMakeLists.darwin-arm64.txt59
-rw-r--r--contrib/libs/libpqxx/CMakeLists.darwin-x86_64.txt59
-rw-r--r--contrib/libs/libpqxx/CMakeLists.linux-aarch64.txt60
-rw-r--r--contrib/libs/libpqxx/CMakeLists.linux-x86_64.txt60
-rw-r--r--contrib/libs/libpqxx/CMakeLists.txt17
-rwxr-xr-xcontrib/libs/libpqxx/COPYING27
-rwxr-xr-xcontrib/libs/libpqxx/INSTALL212
-rw-r--r--contrib/libs/libpqxx/NEWS750
-rw-r--r--contrib/libs/libpqxx/README-UPGRADE11
-rw-r--r--contrib/libs/libpqxx/README.md489
-rw-r--r--contrib/libs/libpqxx/include/pqxx/array4
-rw-r--r--contrib/libs/libpqxx/include/pqxx/array.hxx101
-rw-r--r--contrib/libs/libpqxx/include/pqxx/basic_connection.hxx107
-rw-r--r--contrib/libs/libpqxx/include/pqxx/binarystring4
-rw-r--r--contrib/libs/libpqxx/include/pqxx/binarystring.hxx157
-rw-r--r--contrib/libs/libpqxx/include/pqxx/compiler-internal-post.hxx21
-rw-r--r--contrib/libs/libpqxx/include/pqxx/compiler-internal-pre.hxx35
-rw-r--r--contrib/libs/libpqxx/include/pqxx/compiler-internal.hxx42
-rw-r--r--contrib/libs/libpqxx/include/pqxx/compiler-public.hxx122
-rw-r--r--contrib/libs/libpqxx/include/pqxx/config-internal-compiler.h14
-rw-r--r--contrib/libs/libpqxx/include/pqxx/config-public-compiler.h11
-rw-r--r--contrib/libs/libpqxx/include/pqxx/connection6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/connection.hxx170
-rw-r--r--contrib/libs/libpqxx/include/pqxx/connection_base6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/connection_base.hxx940
-rw-r--r--contrib/libs/libpqxx/include/pqxx/connectionpolicy.hxx59
-rw-r--r--contrib/libs/libpqxx/include/pqxx/cursor6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/cursor.hxx437
-rw-r--r--contrib/libs/libpqxx/include/pqxx/dbtransaction6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/dbtransaction.hxx109
-rw-r--r--contrib/libs/libpqxx/include/pqxx/errorhandler6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/errorhandler.hxx96
-rw-r--r--contrib/libs/libpqxx/include/pqxx/except6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/except.hxx532
-rw-r--r--contrib/libs/libpqxx/include/pqxx/field6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/field.hxx373
-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
-rw-r--r--contrib/libs/libpqxx/include/pqxx/isolation.hxx87
-rw-r--r--contrib/libs/libpqxx/include/pqxx/largeobject6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/largeobject.hxx672
-rw-r--r--contrib/libs/libpqxx/include/pqxx/nontransaction6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/nontransaction.hxx80
-rw-r--r--contrib/libs/libpqxx/include/pqxx/notification6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/notification.hxx91
-rw-r--r--contrib/libs/libpqxx/include/pqxx/pipeline6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/pipeline.hxx210
-rw-r--r--contrib/libs/libpqxx/include/pqxx/pqxx19
-rw-r--r--contrib/libs/libpqxx/include/pqxx/prepared_statement6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/prepared_statement.hxx177
-rw-r--r--contrib/libs/libpqxx/include/pqxx/result11
-rw-r--r--contrib/libs/libpqxx/include/pqxx/result.hxx249
-rw-r--r--contrib/libs/libpqxx/include/pqxx/result_iterator.hxx245
-rw-r--r--contrib/libs/libpqxx/include/pqxx/robusttransaction6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx168
-rw-r--r--contrib/libs/libpqxx/include/pqxx/row.hxx403
-rw-r--r--contrib/libs/libpqxx/include/pqxx/strconv4
-rw-r--r--contrib/libs/libpqxx/include/pqxx/strconv.hxx341
-rw-r--r--contrib/libs/libpqxx/include/pqxx/stream_base.hxx62
-rw-r--r--contrib/libs/libpqxx/include/pqxx/stream_from6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/stream_from.hxx210
-rw-r--r--contrib/libs/libpqxx/include/pqxx/stream_to6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/stream_to.hxx192
-rw-r--r--contrib/libs/libpqxx/include/pqxx/subtransaction6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/subtransaction.hxx105
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablereader6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablereader.hxx118
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablestream6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablestream.hxx59
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablewriter6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/tablewriter.hxx209
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transaction6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transaction.hxx116
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transaction_base7
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transaction_base.hxx664
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transactor6
-rw-r--r--contrib/libs/libpqxx/include/pqxx/transactor.hxx274
-rw-r--r--contrib/libs/libpqxx/include/pqxx/types.hxx57
-rw-r--r--contrib/libs/libpqxx/include/pqxx/util5
-rw-r--r--contrib/libs/libpqxx/include/pqxx/util.hxx309
-rw-r--r--contrib/libs/libpqxx/include/pqxx/version4
-rw-r--r--contrib/libs/libpqxx/include/pqxx/version.hxx57
-rw-r--r--contrib/libs/libpqxx/src/array.cxx312
-rw-r--r--contrib/libs/libpqxx/src/binarystring.cxx150
-rw-r--r--contrib/libs/libpqxx/src/connection.cxx182
-rw-r--r--contrib/libs/libpqxx/src/connection_base.cxx1475
-rw-r--r--contrib/libs/libpqxx/src/cursor.cxx321
-rw-r--r--contrib/libs/libpqxx/src/dbtransaction.cxx99
-rw-r--r--contrib/libs/libpqxx/src/encodings.cxx826
-rw-r--r--contrib/libs/libpqxx/src/errorhandler.cxx44
-rw-r--r--contrib/libs/libpqxx/src/except.cxx124
-rw-r--r--contrib/libs/libpqxx/src/field.cxx77
-rw-r--r--contrib/libs/libpqxx/src/largeobject.cxx313
-rw-r--r--contrib/libs/libpqxx/src/nontransaction.cxx25
-rw-r--r--contrib/libs/libpqxx/src/notification.cxx36
-rw-r--r--contrib/libs/libpqxx/src/pipeline.cxx413
-rw-r--r--contrib/libs/libpqxx/src/prepared_statement.cxx69
-rw-r--r--contrib/libs/libpqxx/src/result.cxx454
-rw-r--r--contrib/libs/libpqxx/src/robusttransaction.cxx317
-rw-r--r--contrib/libs/libpqxx/src/row.cxx276
-rw-r--r--contrib/libs/libpqxx/src/sql_cursor.cxx309
-rw-r--r--contrib/libs/libpqxx/src/statement_parameters.cxx58
-rw-r--r--contrib/libs/libpqxx/src/strconv.cxx724
-rw-r--r--contrib/libs/libpqxx/src/stream_base.cxx43
-rw-r--r--contrib/libs/libpqxx/src/stream_from.cxx261
-rw-r--r--contrib/libs/libpqxx/src/stream_to.cxx142
-rw-r--r--contrib/libs/libpqxx/src/subtransaction.cxx74
-rw-r--r--contrib/libs/libpqxx/src/tablereader.cxx227
-rw-r--r--contrib/libs/libpqxx/src/tablestream.cxx38
-rw-r--r--contrib/libs/libpqxx/src/tablewriter.cxx160
-rw-r--r--contrib/libs/libpqxx/src/transaction.cxx72
-rw-r--r--contrib/libs/libpqxx/src/transaction_base.cxx577
-rw-r--r--contrib/libs/libpqxx/src/util.cxx121
-rw-r--r--contrib/libs/libpqxx/src/version.cxx18
-rw-r--r--contrib/libs/libpqxx/ya.make66
146 files changed, 20309 insertions, 0 deletions
diff --git a/contrib/libs/libpqxx/AUTHORS b/contrib/libs/libpqxx/AUTHORS
new file mode 100644
index 0000000000..6a922e950c
--- /dev/null
+++ b/contrib/libs/libpqxx/AUTHORS
@@ -0,0 +1,4 @@
+Jeroen T. Vermeulen. Wrote the code.
+Ray Dassen. Did most of the autoconf etc. stuff.
+
+Lots of others helped with various other contributions.
diff --git a/contrib/libs/libpqxx/CMakeLists.darwin-arm64.txt b/contrib/libs/libpqxx/CMakeLists.darwin-arm64.txt
new file mode 100644
index 0000000000..14c39564ee
--- /dev/null
+++ b/contrib/libs/libpqxx/CMakeLists.darwin-arm64.txt
@@ -0,0 +1,59 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(contrib-libs-libpqxx)
+target_compile_options(contrib-libs-libpqxx PRIVATE
+ -DHAVE_CONFIG_H
+ $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything>
+)
+target_include_directories(contrib-libs-libpqxx PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/include
+)
+target_include_directories(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq/src/interfaces/libpq
+)
+target_link_libraries(contrib-libs-libpqxx PUBLIC
+ contrib-libs-cxxsupp
+ contrib-libs-libpq
+)
+target_sources(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/array.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/binarystring.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/dbtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/encodings.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/errorhandler.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/except.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/field.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/largeobject.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/nontransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/notification.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/pipeline.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/prepared_statement.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/result.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/robusttransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/row.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/sql_cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/statement_parameters.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/strconv.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_from.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_to.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/subtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablereader.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablestream.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablewriter.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/util.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/version.cxx
+)
diff --git a/contrib/libs/libpqxx/CMakeLists.darwin-x86_64.txt b/contrib/libs/libpqxx/CMakeLists.darwin-x86_64.txt
new file mode 100644
index 0000000000..14c39564ee
--- /dev/null
+++ b/contrib/libs/libpqxx/CMakeLists.darwin-x86_64.txt
@@ -0,0 +1,59 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(contrib-libs-libpqxx)
+target_compile_options(contrib-libs-libpqxx PRIVATE
+ -DHAVE_CONFIG_H
+ $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything>
+)
+target_include_directories(contrib-libs-libpqxx PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/include
+)
+target_include_directories(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq/src/interfaces/libpq
+)
+target_link_libraries(contrib-libs-libpqxx PUBLIC
+ contrib-libs-cxxsupp
+ contrib-libs-libpq
+)
+target_sources(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/array.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/binarystring.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/dbtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/encodings.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/errorhandler.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/except.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/field.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/largeobject.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/nontransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/notification.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/pipeline.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/prepared_statement.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/result.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/robusttransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/row.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/sql_cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/statement_parameters.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/strconv.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_from.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_to.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/subtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablereader.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablestream.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablewriter.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/util.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/version.cxx
+)
diff --git a/contrib/libs/libpqxx/CMakeLists.linux-aarch64.txt b/contrib/libs/libpqxx/CMakeLists.linux-aarch64.txt
new file mode 100644
index 0000000000..2bed345738
--- /dev/null
+++ b/contrib/libs/libpqxx/CMakeLists.linux-aarch64.txt
@@ -0,0 +1,60 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(contrib-libs-libpqxx)
+target_compile_options(contrib-libs-libpqxx PRIVATE
+ -DHAVE_CONFIG_H
+ $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything>
+)
+target_include_directories(contrib-libs-libpqxx PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/include
+)
+target_include_directories(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq/src/interfaces/libpq
+)
+target_link_libraries(contrib-libs-libpqxx PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ contrib-libs-libpq
+)
+target_sources(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/array.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/binarystring.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/dbtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/encodings.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/errorhandler.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/except.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/field.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/largeobject.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/nontransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/notification.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/pipeline.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/prepared_statement.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/result.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/robusttransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/row.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/sql_cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/statement_parameters.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/strconv.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_from.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_to.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/subtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablereader.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablestream.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablewriter.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/util.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/version.cxx
+)
diff --git a/contrib/libs/libpqxx/CMakeLists.linux-x86_64.txt b/contrib/libs/libpqxx/CMakeLists.linux-x86_64.txt
new file mode 100644
index 0000000000..2bed345738
--- /dev/null
+++ b/contrib/libs/libpqxx/CMakeLists.linux-x86_64.txt
@@ -0,0 +1,60 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_library(contrib-libs-libpqxx)
+target_compile_options(contrib-libs-libpqxx PRIVATE
+ -DHAVE_CONFIG_H
+ $<IF:$<CXX_COMPILER_ID:MSVC>,,-Wno-everything>
+)
+target_include_directories(contrib-libs-libpqxx PUBLIC
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/include
+)
+target_include_directories(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpq/src/interfaces/libpq
+)
+target_link_libraries(contrib-libs-libpqxx PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ contrib-libs-libpq
+)
+target_sources(contrib-libs-libpqxx PRIVATE
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/array.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/binarystring.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/connection_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/dbtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/encodings.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/errorhandler.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/except.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/field.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/largeobject.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/nontransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/notification.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/pipeline.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/prepared_statement.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/result.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/robusttransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/row.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/sql_cursor.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/statement_parameters.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/strconv.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_from.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/stream_to.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/subtransaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablereader.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablestream.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/tablewriter.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/transaction_base.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/util.cxx
+ ${CMAKE_SOURCE_DIR}/contrib/libs/libpqxx/src/version.cxx
+)
diff --git a/contrib/libs/libpqxx/CMakeLists.txt b/contrib/libs/libpqxx/CMakeLists.txt
new file mode 100644
index 0000000000..1beba2829f
--- /dev/null
+++ b/contrib/libs/libpqxx/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-aarch64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ include(CMakeLists.darwin-x86_64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
+ include(CMakeLists.darwin-arm64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-x86_64.txt)
+endif()
diff --git a/contrib/libs/libpqxx/COPYING b/contrib/libs/libpqxx/COPYING
new file mode 100755
index 0000000000..006c39da8b
--- /dev/null
+++ b/contrib/libs/libpqxx/COPYING
@@ -0,0 +1,27 @@
+Copyright (c) 2000-2019 Jeroen T. Vermeulen.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author, nor the names of other contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/contrib/libs/libpqxx/INSTALL b/contrib/libs/libpqxx/INSTALL
new file mode 100755
index 0000000000..bf0aebe736
--- /dev/null
+++ b/contrib/libs/libpqxx/INSTALL
@@ -0,0 +1,212 @@
+Basic Installation
+==================
+
+
+The native build system for libpqxx is based on `configure` and `make`,
+but there is also a CMake build.
+
+
+Native build
+------------
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README.md' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself. Running `configure' takes awhile. While
+ running, it prints some messages telling which features it is
+ checking for.
+ 2. Type `make' to compile the package. (Add e.g. `-j8` to run up to 8
+ simultanerous compiler processes to speed this up.)
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+
+CMake build
+-----------
+
+With CMake you can generate a build setup in your choice of build
+system. The one I'm most familiar with is `make`.
+
+Like the native build, the CMake build needs the libpq library and headers
+installed. But in addition, it also needs the `pg_type.h` header installed.
+On some systems this will be in one of the `postgresql-server-dev-*` packages.
+
+That extra header is just to allow CMake to detect that you have a PostgreSQL
+development setup installed. The build shouldn't actually need the file
+otherwise, so if you can't find the file, it may be enough to create an empty
+file in the right place.
+
+The CMake build works like:
+ 1. Go into the directory where you would like to build the library and
+ its intermediate files. This may be the source directory.
+ 2. Enter `cmake <sourcedir>`, where `<sourcedir>` is the location of
+ the libpqxx source code. This generates the build configuration.
+ 3. Type `make' to compile the package. (Add e.g. `-j8` to run up to 8
+ simultanerous compiler processes to speed this up.)
+
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment, or by
+adding them to the `configure` command line:
+
+ ./configure CXX='clang++' CXXFLAGS=-O3 LIBS=-lposix
+
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README.md' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/contrib/libs/libpqxx/NEWS b/contrib/libs/libpqxx/NEWS
new file mode 100644
index 0000000000..7fa015859b
--- /dev/null
+++ b/contrib/libs/libpqxx/NEWS
@@ -0,0 +1,750 @@
+6.4.5
+ - Fixed "const" support in arguments to parameterised/prepared statements.
+6.4.4
+ - Use pkg-config if pg-config is not available.
+ - In CMake build, prefer CMake's config headers over any found in source tree.
+6.4.3
+ - Updated copyright strings.
+ - Added missing "stream" headers to autotools-based install.
+ - Added stream headers to pqxx/pqxx header.
+6.4.2
+ - Fix mistake for Windows in 6.4.1: use PQfreemem, not std::free.
+ - Easily enable runtime checks in configure: "--enable-audit".
+ - Enable optimisation in CircleCI build.
+6.4.1
+ - Fixed more memory leaks.
+6.4.0
+ - Half fix, half work around nasty notice processor life time bug.
+ - Fix selective running of tests: "test/unit/runner test_infinities".
+ - Added some missing `std::` qualifications.
+6.3.3
+ - Throw more appropriate error when unable to read client encoding.
+ - CMake build fixes.
+6.3.2
+ - Conversion errors no longer throw pqxx::failure; always conversion_error!
+ - Use C++17's built-in numeric string conversions, if available.
+ - Query numeric precision in a more sensible, standard way.
+ - Avoid "dead code" warning.
+ - Replace obsolete autoconf macros.
+ - Remove all "using namespace std".
+ - CMake build fixes.
+6.3.1
+ - Windows compile fix (CALLBACK is a macro there).
+ - Work around Visual Studio 2017 not supporting ISO 646.
+6.3.0
+ - New "table stream" classes by Joseph Durel: stream_from/stream_to.
+ - Support weird characters in more identifiers: cursors, notifcations, etc.
+ - Connection policies are deprecated. It'll all be one class in 7.0!
+ - Connection deactivation/reactivation is deprecated.
+ - Some items that were documented as deprecated are now also declared as such.
+ - Fix Windows bug where WSAPoll was never used. Thanks dpolunin.
+ - Fix Windows CMake build to link to socket libraries. Thanks dpolunin.
+ - Various other changes to the CMake build.
+ - Fix failure when doing multiple string conversions with Visual C++.
+ - Fix nested project builds in CMake. Thanks Andrew Brownsword.
+ - In Visual Studio, build for host architecture, not "x64".
+ - Fix string conversion link error in Visual Studio. Thanks Ivan Poiakov.
+ - Fix string conversion to bool for "1". Thanks Amaracs.
+ - Fix in escaping of strings in arrays. Thanks smirql.
+ - Faster copying of results of large queries. Thanks Vsevolod Strukchinsky.
+ - Starting to handle encodings properly! Thanks to Joseph Durel.
+ - No longer using std::iterator (deprecated in C++17).
+6.2.5
+ - Removed deprecated pqxx-config.
+ - Build fix on Visual C++ when not defining NOMINMAX.
+ - Reduce setup code for string conversions, hopefully improving speed.
+ - Allow nul bytes in tablereader.
+ - Support defining string conversions for enum types.
+ - Fixed const/pure attributes warning in gcc 8.
+ - Updated build documentation to mention CMake option.
+ - Fixed a floating-point string conversion failure with Visual Studio 2017.
+6.2.4
+ - Fix builds in paths containing non-ASCII characters.
+ - New macro: PQXX_HIDE_EXP_OPTIONAL (to work around a client build error).
+6.2.3
+ - Build fixes.
+6.2.2
+ - Variable number of arguments to prepared or parameterised statement (#75).
+ - Windows build fix (#76).
+6.2.1
+ - Compile fixes.
+6.2.0
+ - At last! A check against version mismatch between library and headers.
+ - Small compile fixes.
+6.1.1
+ - Small compile fixes.
+ - A particular error string would always come out empty.
+6.1.0
+ - Dependencies among headers have changed. You may need extra includes.
+ - Library headers now include "*.hxx" directly, not the user-level headers.
+ - Supports parsing of SQL arrays, when using "ASCII-like" encodings.
+6.0.0
+ - C++11 is now required. Your compiler must have shared_ptr, noexcept, etc.
+ - Removed configure.ac.in; we now use configure.ac directly.
+ - Removed pqxx::items. Use the new C++11 initialiser syntax.
+ - Removed maketemporary. We weren't using it.
+ - Can now be built outside the source tree.
+ - New, simpler, lambda-friendly transactor framework.
+ - New, simpler, prepared statements and parameterised statements.
+ - Result rows can be passed around independently.
+ - New exec0(): perform query, expect zero rows of data.
+ - New exec1(): perform query, expect (and return) a single row of data.
+ - New exec_n(): perform query, expect exactly n rows of data.
+ - No longer defines Visual Studio's NOMINMAX in headers.
+ - Much faster configure script.
+ - Most configuration items are gone.
+ - Retired all existing capability flags.
+ - Uses WSAPoll() on Windows.
+ - Documentation on readthedocs.org, thanks Tim Sheerman-Chase.
+5.1.0
+ - Releases after this will require C++11!
+ - Internal simplification to pqxx::result.
+ - A row object now keeps its result object alive.
+ - New exec() variants: "expect & return 1 row," "expect no rows," "expect n."
+ - ChangeLog is gone. It was a drag on maintenance.
+5.0.1
+ - Exposed sqlstate in sql_error exception class.
+5.0
+ - The PGSTD namespace alias is gone. Use the std namespace directly.
+ - pqxx::tuple is now pqxx::row, to avoid clashes with std::tuple.
+ - Deprecated escape_binary functions dropped.
+ - Deprecated notify_listener class dropped.
+ - Support for many old compilers dropped.
+ - Support for "long long" and "long double" types is always enabled.
+ - No longer uses obsolete std::tr1 namespace; use plain std instead.
+ - Now requires libpq 9.1 or better.
+ - Requires server version 9.1 or better.
+ - Support for REPEATABLE READ isolation level added.
+ - Makefile fixes for Visual Studio 2013.
+ - Supports C++11 and C++14.
+ - No longer has obsolete debian & RPM packaging built in.
+ - Fixed failure to abort uncommitted subtransactions on destruction.
+ - Fixed failure to detect some integer overflows during conversion.
+ - Build tooling uses /usr/bin/env python instead of /usr/bin/python.
+ - New configure options: --with-postgres-include and --with-postgres-lib.
+ - In g++ or compatible compilers, non-exported items are no longer accessible.
+ - Many build fixes for various platforms and compilers.
+4.0
+ - API change: noticers are gone! Use errorhandlers to capture error output.
+ - API change: tablereaders and tablewriters are gone; they weren't safe.
+ - API change: prepared statements are now weakly-typed, and much simpler.
+ - API change: fields and tuples are now stand-alone classes in ::pqxx.
+ - API change: thread-safety field have_strerror_r is now have_safe_strerror.
+ - API change: notify_listener has been replaced with notification_receiver.
+ - notification_receiver takes a payload parameter.
+ - Easier Visual C++ setup.
+ - Absolutely requires a libpq version with PQescapeStringConn.
+ - Absolutely requires libpq 8.0 or better.
+ - Changes for C++0x.
+ - Supports clang++.
+ - Visual C++ makefiles now support new-style unit tests.
+ - Sample headers for more recent Visual Studio versions.
+ - Fixes binary-data escaping problems with postgres 9.0.
+ - Fixes problems with binary-string handling and escaping.
+ - Fixes compatibility problems between 9.x libpq and 7.x backend.
+ - quote_name to escape SQL identifiers for use in queries.
+ - syntax_error reports error's approximate location in the query.
+ - On Windows, now uses ws2_32 instead of wsock32.
+ - Various Windows build fixes.
+ - Updated for gcc 4.6.0.
+ - configure script supports --enable-documentation/--disable-documentation.
+ - Streamlined test/release toolchain.
+3.1
+ - Shared libraries are now versioned by ABI: 3.1 instead of 3.1.0 etc.
+ - Threading behaviour is now documented, and can be queried.
+ - Version information available at compile time.
+ - Supports parameterized statements.
+ - Result tuples now support slicing.
+ - Configure with --with-tr1=boost to use BOOST shared_ptr.
+ - String conversion now has its own header file.
+ - Supports read-only transactions.
+ - Fixed breakage with Solaris "make".
+ - Uses shared_ptr if available.
+ - binarystring::str() is no longer cached; no longer returns reference.
+ - Fixed problems in Visual C++ Makefile for test suite.
+ - Fixed problems with RPM packaging.
+ - Fixed build problem on RedHat/CentOS 5.
+ - Lets you check whether a prepared statement has been defined.
+ - "Varargs" prepared statements.
+ - Unnamed prepared statements now supported.
+ - Results have iterator as well as const_iterator.
+ - Rewrite of robusttransaction logic; may actually do its job now.
+ - Connections support async query cancel from signal handler or thread.
+ - More documentation for performance features.
+3.0
+ - Website is now at http://pqxx.org/ (no redirects)
+ - Completely replaced cursor classes
+ - More helpful error messages on failed connections
+ - More detailed hierarchy of constraint-violation exception classes
+ - trigger is now called notify_listener, trigger header is now notify-listen
+ - New mixin base class pqxx_exception distinguishes libpqxx exception types
+ - Quoting is back! transaction_base::quote() & connection_base::quote()
+ - Several build & documentation problems with Visual C++ fixed
+ - Compile fixes for gcc 4.2, 4.3
+ - Compile fixes for Sun Studio Express 5.9
+ - Uses strlcpy() where available, instead of strncpy()
+ - Keeps better track of applicable text encodings
+ - Fixed bug with prepared statement parameters in separate C++ statements
+ - robusttransaction now works for multiple users
+ - Pipeline lets you cancel ongoing queries, e.g. because they run for too long
+ - Fixed broken escaping of binary values in tablewriter
+ - Floating-point types now represented with full precision
+ - Proper unit tests for new functionality
+ - New traits-based system for adding data types
+ - Floating-point infinities now supported
+ - Flushing/completing a pipeline now frees up the transaction for other use
+ - Completely reworked test suite, builds and runs much faster
+ - tablewriter supports writing of raw lines
+2.6.9
+ - Removed old 1.x API (that means all identifiers with capital letters!)
+ - Tested with all current libpq versions and oldest/newest supported backends
+ - No longer have old OnCommit()/OnAbort()/OnDoubt() callbacks in transactor!
+ - Fixes failure when closing cursors with upper-case letters in their names
+ - Fixes bug when adding triggers to connections that aren't open yet
+ - Fixes bug when removing triggers
+ - Fixes small memory leak when preparing statements
+ - Fixes many problems with older backends
+ - Fixes bug in result::swap(): protocol versions were not swapped
+ - Some errors went undetected when using certain libpq versions
+ - Fixes prepared statements on new libpq versions talking to old backends
+ - Can estimate server version if libpq does not know how to obtain it
+ - Greatly reduced memory usage while escaping strings
+ - With Visual C++, creates lib/ directory if not already present
+ - Useful error messages when preparing statements
+ - Allows prepared statements to be registered explicitly
+ - Support for "long long" types; enable with PQXX_ALLOW_LONG_LONG macro
+ - Compilation errors for older libpq versions fixed
+ - Some new small utility classes for disabling notice processing etc.
+ - Result sets remember the queries that yielded them
+ - New test script, pqxx-fulltest, tests against all current postgres versions
+ - Connections can simulate failure
+ - Adds password encryption function
+2.6.8
+ - Fixes bug: binary parameters to prepared statements truncated at nul bytes
+ - New, more specific exception types to distinguish errors from server
+ - Resolved serious problems with generated reference documentation
+ - Automatically detect Windows socket library with MinGW
+ - Windows "make" fixed to run from main directory, not win32
+ - Fixes "mktemp" problems on some BSD-based platforms
+ - pqxx-config is deprecated; use pkg-config instead
+ - On GNU/Linux, uses poll() instead of select() to avoid file descriptor limit
+ - Will provide server and protocol version information where available
+ - New cursor class, absolute_cursor
+2.6.7
+ - New escape functions for binary data: transaction_base::esc_raw()
+ - Improved detection of socket libraries, especially for MinGW
+ - Works around bug in some versions of GNU grep 2.5.1
+ - Fixes problem with configuration headers
+ - Fixes PQprepare() detection
+ - Fixes incomplete Visual C++ Makefile
+ - Fixes compile error in workaround for older libpq versions
+ - Removes "rpath" link option
+2.6.6
+ - New, encoding-safe string-escaping functions
+ - Upper-case letters now allowed in prepared-statement names
+ - Fixes crash in test005
+ - More Visual C++ improvements
+ - Removed collaboration diagrams from reference docs
+ - New templating system for generating Windows Makefiles etc.
+2.6.5
+ - Visual C++ users: copy win32/common-sample to win32/common before editing it
+ - Should fix problems finding socket library on MinGW
+ - Even more work on Visual C++ problems
+ - Updated documentation for Visual C++ users
+ - Fixed bug in prepared statements (mostly visible on Visual C++)
+ - Nested transactions work harder to detect backend support
+2.6.4
+ - Massively improved compatibility with Windows and Visual C++
+ - Fixed late initialization of "direct" connection state
+ - Fixed problem with initialization of connection capabilities
+ - Fixed configuration bug for libpq in nonstandard locations
+ - Sample configuration header for libpq found in PostgreSQL 8.1
+2.6.3
+ - Radical rework of prepared statements; INCOMPATIBLE INTERFACE CHANGE!
+ - Dropped support for g++ 2.95
+ - Emulate prepared statements support on old libpq or old backend
+ - Bug fix: missing tutorial (release script now tests for this)
+ - Automatically links in socket library on Windows or Solaris, if needed
+ - Bug fix: check for std namespace didn't work
+ - Fixes for Cygwin/MSYS/MinGW
+2.6.2
+ - Bug fix: connection state was not set up properly in some common cases
+ - Bug fix: headers were installed in "include" instead of "include/pqxx"
+ - Bug fix: sqlesc(string) broke with multibyte or multiple encodings
+ - namedclass is now used as a virtual base; affects all subclass constructors
+ - Initial implementation of subtransactions
+ - Detect more connection capabilities
+ - Standard library namespace can be set from configure script's command line
+ - Completely reworked connection hierarchy, with separate policy objects
+ - Clients can now define their own connection policies
+ - Paved the way for client-defined thread synchronization
+ - Now lives at http://thaiopensource.org/development/libpqxx/
+2.6.1
+ - Hugely improved recognition of different strerror_r() versions
+ - Resolved link problems with gcc 4.0 and shared library
+2.6.0
+ - New macro PQXX_SHARED defines whether to use/build libpqxx as shared library
+ - Robusttransaction compatible with PostgreSQL 8.1
+ - Infrastructure for querying connection/backend capabilities at runtime
+ - Greatly improved cursor support
+ - Connection reactivation can be inhibited explicitly
+ - Tries even harder to make sense of conflicting strerror_r() definitions
+ - Detects connection failures that libpq glosses over
+ - Reference documentation grouped into more coherent sections
+ - Assumes strerror() is threadsafe on systems that have no strerror_r()
+ - Now allows connection's socket number to be queried
+ - New internal_error class for libpqxx-internal errors
+ - With Visual C++, doesn't redefine NOMINMAX if it is defined already
+ - Several compatibility improvements for Visual C++
+ - Fixes and workarounds for HP-UX and HP aCC compiler
+ - Phased old cursor interface out of test suite; tests ported to new interface
+ - Added documentation on thread safety
+ - New thread safety model
+ - Large objects have functions to tell current position
+ - Minor updates to tutorial (somebody pay me and I'll do more :)
+ - No longer needs libpq-fs.h header
+ - Meaningful error messages for ambiguous string conversions fixed
+2.5.6
+ - Support null parameters to prepared statements (use C-style char pointers)
+2.5.5
+ - Diagnoses connection failure during result transfer
+ - Fixes invalid -R link option in pqxx-config
+2.5.4
+ - Fix workaround code for older libpq versions without PQunescapeBytea()
+ - Work around grep bug in Fedora Core 4 that broke configure in UTF-8 locales
+ - In Visual C++, assume libpqxx is a DLL when linking to std library as DLL
+ - Missing documentation in distribution archive is back again
+ - Export fewer symbols from library binary with gcc 4.0
+ - Releases now automatically tested against gcc 4.0
+ - Meaningful link errors for additional ambiguous string conversions
+ - DLL symbol exports now automatically tested before each release
+2.5.3
+ - Greatly improved builds on MinGW with MSYS
+ - All known problems with MinGW fixed
+ - Fix bugs in stream classes that caused failures and crashes with STLport
+ - Detects and uses STLport automatically
+2.5.2
+ - Fix memory leaks
+ - Fix problems with NaN (not-a-number values) on some compilers
+2.5.1
+ - Fix configure script; broke when very recent libpqxx was already installed
+ - Fix cursor breakage when "long" is more than 32 bits
+ - Fix cases where new-style abort/doubt handlers are used
+ - Fix for division-by-zero error in Visual C++ (changed sample headers)
+ - Improved checking for strerror_r in configure script
+ - Fix for problem MinGW has with configure script
+ - Fix spurious failure of Oid check in configure script
+2.5.0
+ - Fix race condition in removing triggers
+ - Fix binary string conversion with older libpq
+ - Fix some error strings that may previously have come out wrong
+ - No longer includes any libpq headers while compiling client code
+ - Improved thread safety: avoid strerror() where possible
+ - Prepared statements
+ - Translate more error conditions to std::bad_alloc exception
+ - Clearer and more specific explanations for configuration failures
+ - Improved documentation
+ - Looks for standard library in global namespace as well as std
+ - Accepts standard C library in std namespace
+ - Release script automatically tests with a range of compilers, not just one
+ - Compatible with g++ 2.95 again; this time it's tested automatically
+2.4.4
+ - Fix problems building shared library in Visual C++
+ - Fix autobuild in Debian, which was broken by mistake in BSD grep workaround
+ - Fix conversion of string to floating-point type NaN
+ - Remove stray CVS directories from distribution archive
+ - Workaround for Visual C++ problem when issuing messages from destructors
+ - Yet more workarounds for Visual C++ bugs
+ - Fix situation where connection state might not be restored after failure
+ - Fix configuration problem on SunOS
+ - Network speedup in connection setup with pending variables and/or triggers
+2.4.3
+ - Yet more workarounds for bugs in Visual C++ .NET 2003
+ - Fixes for SunC++ 5.5
+ - On Visual C++, now defines NOMINMAX, fixing large object support
+ - Workaround for BSD grep
+ - Improvements for builds from CVS
+ - Sample config headers for Sun ONE Studio 8
+2.4.2
+ - Fix minor problems with Apple's version of g++ 3.3
+ - Fix problem with MingW on Windows
+ - Workarounds and fixes for Visual C++.NET 2003
+ - Renewed compatibility with g++ 2.95
+ - More sample configuration headers
+ - Updated reference documentation
+ - Removed assert code
+2.4.1
+ - Several bugs in icursor_iterator fixed; incompatible interface changes
+ - Tightens throw specifications on begin(), end(), size(), capacity()
+ - Containers define reference and pointer types
+ - Implements swap() in all container types
+ - Implements == and != in all container types
+ - Stabilizes new (but still limited) cursor interface
+ - icursor_iterator thinks purely in stride granularity
+ - Introduces </<=/>/>= comparisons for icursor_iterators
+ - Allows "adopted SQL cursors" in new cursor interface
+ - Reference-counting in binarystrings, so they can be copied (and efficiently)
+ - Fixes reference-to-temporary problem with std::reverse_iterator in results
+ - Result/tuple reverse_iterators no longer require std::reverse_iterator
+ - Includes some sample config headers (in config/sample-headers)
+ - Replaces iffy autoconf checks (avoid failures with maintainer mode's -Werror)
+ - Fixes incompatibility with some implementations of Unix "cut" program (again)
+2.4.0
+ - Fixes incompatibility with some implementations of Unix "cut" program
+ - Fixes "ptrdiff_t redefinition" problem in some environments
+ - More container-like tuples, so fields can be iterated
+ - All size_type types are now unsigned
+ - More conservative robusttransaction--thanks Tom Lane
+ - Stream-like extraction operator for result field conversion
+ - Warnings about deprecated headers now suppressed while compiling library
+ - Iterator constructors and copy assignments now have empty throw specs
+2.3.0
+ - Generates MinGW Makefile automatically
+ - Documents MinGW build
+ - Workaround for missing prepared-statement support
+ - Potential bug fixed in closing of connections
+ - Fixed incompatibility between new cursor streams and older backends
+ - Removed pqxxbench
+2.2.9
+ - Bugfix in removing trigger
+ - Added "failed connection" to regression test
+ - Some changes to throw specifications
+ - Putting libpq in its own namespace is optional
+2.2.8
+ - Moved libpq into pqxx::internal::pq namespace
+ - New config system separates compiler-related items from libpq-related ones
+ - Auto-generates Visual C++ Makefile, should always remain up-to-date now
+2.2.7
+ - Bugfix: from_string() didn't handle LONG_MIN--thanks Yannick Boivin
+2.2.6
+ - Complete "pipeline" rewrite, for better exception safety
+ - New garbage collection scheme for "result;" constructors now exception-free
+2.2.5
+ - First new cursor classes!
+ - Fixed strange failure in tablewriter during large insertions
+ - Updated tutorial
+2.2.4
+ - New utility class template, items<> for easy container initialization
+ - New utility function template, separated_list()
+ - Error handling bugfix in tablewriter
+ - Fixed tablereader handling of lines ending in empty fields
+ - tablereader lines no longer end in newline with old libpq versions
+2.2.3
+ - Trigger names no longer need to be proper identifiers
+ - Compile fixes for g++ 3.4.0 and other modern compilers
+ - Tablestreams may specify column lists
+ - Deprecated Quote() in favour of sqlesc(); improved quoting
+ - Fixed generation of libpqxx.spec
+2.2.2
+ - Bugfix in fieldstream w.r.t. reading strings on some systems
+ - Renamed config.h to internalconfig.h to avoid confusion
+ - New connection functions allow client to sleep until notification arrives
+ - Notification functions return number of notifications received
+ - Even fewer client-visible macros exported by libconfig.h
+2.2.1
+ - New, 2.x-style string conversions without locale problem
+ - Documentation improvements
+ - Implemented result::swap()
+2.2.0
+ - Installs to /usr/local by default, NOT to /usr/local/pqxx like before!
+ - Uses Postgres-provided script to find Postgres (thanks Peter Eisentraut)
+ - Which means no more configure arguments required on Irix (thanks Arjen Baart)
+ - Fixes long-standing bug in result class!
+ - New pipeline class for throughput optimization
+ - New field stream class: read result field as C++ stream
+ - Separate namespace pqxx::internal for definitions not relevant to the user
+ - More Windows compilation fixes
+ - SUN Workshop 6 compile fixes and workarounds (thanks Jon Meinecke)
+ - Implemented reverse_iterator for result class
+ - Checks for functional std::reverse_iterator template
+ - Preliminary Makefile for MinGW compiler (thanks Pasquale Fersini)
+ - Changed the way unique<> works
+ - Checks for functional std::count_if()
+ - Bugs fixed & test programs added
+2.1.3
+ - Makefile fixes for Visual C++, thanks Paresh Patel
+ - Library ABI versioning implemented, thanks Roger Leigh
+ - Uses old SQL isolation level syntax for compatibility, thanks koun@sina.com
+ - tablestreams can explicitly complete() before destructor
+ - Bugfix in robusttransaction: forgot to set isolation level
+ - Fixed off-by-ones in tablewriter escape code
+ - tablestreams now use \n-style escape sequences
+ - tablestreams support octal numbers
+ - Freely definable "null" strings in tablestreams, as originally intended
+ - Improved Debian packaging, thanks Roger Leigh
+ - tablestreams use libpq's new-style COPY functions, if available
+ - Extended automation of build/release procedure
+ - tablewriter writes in nonblocking mode to help hide communication latency
+ - Can get backend variables as well as set them
+ - More configuration macro cleanups
+ - Workaround for missing clear() in standard string
+ - Merry Christmas!
+2.1.2
+ - Compile fix for gcc libstdc++ 2.9, thanks Jaroslaw Staniek
+ - Moved deprecated functions below current ones
+ - Cleanups for Debian packaging (thanks Roger Leigh, new Debian maintainer!)
+ - Updated authors listings
+ - Bumped ABI version number for the first time (now 2:0:1)
+2.1.1
+ - More workarounds for gcc 2.95
+ - Automated tools keep test makefiles up to date
+2.1.0
+ - Asynchronous connections
+ - Fixed configure --includedir option (thanks Ray Dassen!)
+ - Compile fixes for SUN Workshop 6, and one for gcc on FreeBSD 4.8
+2.0.0
+ - New stable release!
+ - Includes all changes since 1.5 release.
+ - Workarounds for Microsoft Visual C++ 7 problems. Thanks Costin Musteata!
+ - No longer need to define PQXX_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION
+ - Integrated Windows configuration into regular configuration
+ - Only uses #warning if preprocessor supports it
+ - Works on libpq versions without PQ[un]escapeBytea()
+1.9.9
+ - Minor documentation changes
+1.9.8
+ - Workaround for compile problem with postgres 7.3
+ - Convenience typedef for transaction<>: "work"
+1.9.7
+ - binarystring rewritten and moved to its own file
+ - binarystring::size() does not include terminating null byte!
+ - Implemented escaping of binary strings
+ - Fix in workaround for missing numeric_limits on some compilers
+ - String conversion supported for unsigned char *
+ - More helpful link errors for unsupported string conversions
+ - Complete test coverage
+1.9.6
+ - Fixes in "field table" support
+ - Improved coexistence with client program's config.h, if any
+ - Prefixed autoconf macros used in headers with "PQXX_"
+1.9.5
+ - Header file contents moved to .hxx files for editor filetype recognition
+ - Fixes wrong timestamp for include/pqxx/result in 1.9.4 distribution
+1.9.4
+ - Fixes Visual C++ build problem when compiling as library
+1.9.3
+ - Quick release for various minor changes
+1.9.2
+ - Renamed most public member functions to all-lower-case names
+ - <pqxx/all> (previously <pqxx/all.h> is now called <pqxx/pqxx>
+1.9.1
+ - tablestream destructor crashed if table didn't exist (thanks Sean [Rogers?])
+ - Renamed all header files to remove ".h" suffix
+ - Tables created by regression test now prefixed with "pqxx" for safety
+ - Large objects now considered stable
+ - Migrated tutorial from SGML to DocBook XML (thanks Wichert Akkerman)
+ - Added tests 57-59
+ - Fixed compile error in largeobject
+ - Updated Windows makefiles
+1.9.0
+ - EVERYTHING HAS CHANGED. Read the list or run into trouble!
+ - CURSOR HAS INCOMPATIBLE CHANGES AND MAY BE REPLACED COMPLETELY
+ - CACHEDRESULT HAS INCOMPATIBLE CHANGES (won't compile without changes)
+ - REVISE YOUR TRANSACTORS; now templatized on transaction type
+ - Finally got license file in order
+ - Incompatible change in setting transactor quality of service
+ - Cursors require serializable isolation level (checked at link time)
+ - Renamed Connection_base to connection_base, Connection to connection,
+ LazyConnection to lazyconnection
+ - Renamed LargeObject to largeobject, LargeObjectAccess to largeobjectaccess
+ - Renamed Noticer to noticer
+ - Renamed Trigger to trigger
+ - Renamed Result to result, Tuple to tuple, Field to field
+ - Renamed Unique<> to unique<>
+ - Renamed CachedResult to cachedresult
+ - Transformed Transaction Taxonomy (TTT):
+ - Renamed Transaction_base to transaction_base
+ - Renamed Transaction to transaction
+ - Renamed Transactor to transactor<> (now a template)
+ - Implemented transaction isolation levels as compile-time static properties
+ - transaction and robusttransaction now templatized on their isolation levels
+ - cachedresult requires serializable isolation level (checked at link time)
+ - Now need to include pqxx/transactor.h yourself if you need transactors
+ - Large objects require real backend transaction at compile time
+ - New type oid and constant oid_none for row identifiers resp. null oid
+ - Added some forgotten PQXX_LIBEXPORTs
+ - Tweaked documentation in many places
+1.8.1
+ - By popular request: more convenient way to read field values
+ - Documented locale sensitivity of ToString(), FromString(), Field::to()
+1.8.0
+ - Compiles on gcc 2.95 again (heavy streambuf workarounds in largeobject.h)
+ - ConnectionItf renamed to Connection_base, TransactionItf to Transaction_base
+ - connectionitf.h is now connection_base.h, transactionitf.h connection_base.h
+1.7.8
+ - BinaryString class for unescaping bytea strings
+ - PQAlloc template keeps track of libpq-allocated objects
+ - Removed some consts in Unique<>, ConnectionItf, sorry!
+ - Can now set session variables on connections, transactions
+1.7.7
+ - ./configure also looks for postgres in /usr/local/pgsql
+ - test007 now uses SQL_ASCII as its test encoding
+ - integrated Greg Hookey's Debian packaging
+1.7.6
+ - added postgres library (libpq) to dynamic link path
+1.7.5
+ - added test052 - test055
+ - added Result::Tuple::ColumnNumber()
+ - also test setting of client encodings
+ - removed superfluous versions of to_file() from large object classes
+1.7.4
+ - new exception class, sql_error, remembers query text
+ - moved exception classes to new file include/pqxx/except.h
+ - test cases report texts of any failed queries
+ - added tools/rmlo.cxx
+1.7.3
+ - default constructors for connection classes
+ - revamped seeking operations on large objects
+ - better error messages in large objects
+ - added test050, test051
+1.7.2
+ - more workarounds for Sun CC 5.1, thanks Jeroen van Erp!
+ - preliminary support for "named" queries
+ - can now Quote() string constants
+ - included Doxyfile in distribution archive
+ - helps avoid Windows memory allocation problem in DLLs
+ - allows setting of client character set encoding
+1.7.1
+ - regenerated documentation
+1.7.0
+ - removed all deprecated features
+ - connection string documentation in README
+ - separate Connection, LazyConnection classes
+ - made test001 more concise
+ - added test049
+1.6.4
+ - configure script now respects different std namespace
+1.6.3
+ - olostream, lostream now flush themselves before closing
+ - fixed compilation problems when using ToString<>() on a plain char *
+ - compilation fixes for Sun compiler (thanks Jeroen van Erp!)
+ - added .pc file for pkgconfig (thanks Ray Dassen!)
+1.6.2
+ - Debian packaging added to distribution archive
+ - new ilostream, olostream, lostream classes
+1.6.1
+ - large object's cunlink() replaced by remove()
+ - default constructor for LargeObject
+1.6.0
+ - new large objects interface
+ - added test048
+1.5.0
+ - allow result fields to be written to streams
+ - removed confusing CachedResult::clear()
+ - minor documentation updates
+ - added test046, test047
+ - added <pqxx/all.h> convenience header
+1.4.5
+ - fixed crash CachedResult that was less shallow than I thought
+ - fixed quoting problem with adopted SQL cursors
+1.4.4
+ - (forgot to save cursor.cxx with new constructor in 1.4.4, sorry)
+1.4.3
+ - all tests now have three-digit numbers
+ - Cursor can adopt SQL cursor returned by a function
+1.4.2
+ - bugfix in CachedResult when accessing empty Results
+ - minor documentation improvements
+1.4.1
+ - documents new homepage: http://pqxx.tk/
+ - Connection constructor accepts null connect string
+ - Exec() now also takes queries as C++ strings
+1.4.0
+ - Connection::IsOpen() renamed to is_open()
+ - NoticeProcessor replaced by Noticer (with C++ linkage)
+1.3.7:
+ - detects nasty rare problem case with Cursors in unknown positions
+1.3.6:
+ - fixed detection of missing PQescapeString(). Thanks David Wright!
+v1.3.5:
+ - documented Windows build procedure
+ - fixed problem with upper-case letters in cursor names. Thanks key88!
+2003-01-19 16:00, v1.3.4:
+ - support long double type
+ - clarified some error messages
+2003-01-08 18:45, v1.3.3:
+ - fix missing include in test13
+2003-01-07 02:30, v1.3.2:
+ - configure looks for postgres includes/library in more places, thanks Ray!
+2003-01-02 23:00, v1.3.1:
+ - bugfix in Cursor positioning
+2003-01-02 20:30, v1.3.0:
+ - absolute positioning for Cursor
+ - better documentation on cursors
+ - reduced, but improved test suite output
+2002-12-23 17:30, v1.2.8:
+ - Cursor::Move() returns number of rows skipped
+ - new typedef Cursor::size_type
+2002-12-14 23:30, v1.2.7:
+ - test suite now distinguishes expected errors from unexpected ones
+2002-12-09 20:00, v1.2.6:
+ - fixed some Cursor test cases for change in postgres 7.3
+ - added important warning to Cursor
+2002-12-09 02:00, v1.2.5:
+ - added important warning to CachedResult
+2002-12-08 14:14, v1.2.4:
+ - fixed compile error on some systems in include/pqxx/util.h
+2002-12-04 12:00, v1.2.3:
+ - workaround for broken <sys/select.h> on some systems
+ - fixed Quote() bug
+2002-12-03 01:30, v1.2.2:
+ - fixed serious CachedResult bug
+ - added test41
+2002-12-02 17:00, v1.2.1:
+ - hopefully fixed cursor bug with PostgreSQL 7.3
+2002-12-01 22:00, v1.2.0:
+ - new CachedResult class
+2002-11-07 13:15, v1.1.4:
+ - workaround for missing InvalidOid definition
+2002-10-23 16:00, v1.1.3:
+ - Cursor & TableStream hierarchy now work on any transaction type
+ - get no. of affected rows & oid of inserted row from Result
+ - increased test coverage
+2002-10-21 01:30, v1.1.2:
+ - updated build procedure
+ - Debian packaging improvements
+2002-09-25 03:00, v1.1.1:
+ - supports activating/deactivating of connections
+ - various Connection getters now activate deferred connection first
+2002-09-23 01:00, v1.1.0:
+ - supports lazy connections (added 19 test cases just for these)
+ - greatly reduced performance overhead for RobustTransaction
+ - removed id field from RobustTransaction's transaction log tables
+2002-09-14 20:00, v1.0.1:
+ - now lives on GBorg
+ - various packaging updates
+2002-06-12 17:30, v0.5.1:
+ - no longer have to destroy one transaction before creating the next
+2002-06-07 17:15, v0.5.0:
+ - "make install" now finally installs headers!
+ - distribution now includes SGML (DocBook) version of tutorial
+2002-06-04 15:00, v0.4.4:
+ - may now have multiple triggers with same name on single connection
+2002-06-02 23:00, v0.4.3:
+ - fixed TableReader problem with \t and \n
+2002-06-01 21:00, v0.4.2:
+ - hopefully fixes compile problem with broken std::iterator
+ - configure no longer requires --with-postgres-include=/usr/include/postgresql
+2002-05-29 22:00, v0.4.1:
+ - can now also handle bool, unsigned char, short field types
+2002-05-27 22:30, v0.4.0:
+ - RENAMED Transactor::TRANSACTIONTYPE to argument_type for STL conformance
+ - RENAMED Result::Field::name() to Name()
+ - documentation improvements
+ - minor optimizations
+2002-05-18 00:00, v0.3.1:
+ - removed broken postgres_fe.h dependency (hopefully permanent fix)
+2002-05-12 22:45, v0.3.0:
+ - also looks for postgres_fe.h in postgres' internal/ directory (tmp fix)
+2002-05-05 01:30, v0.2.3:
+ - extensive build instructions in README
+ - make check now controlled through PG environment variables
+2002-05-04 19:30, v0.2.2:
+ - more STL conformance
+ - fixed regression test
+ - test6 now copies "orgevents" to "events" by default
+2002-04-28 23:45 Version bumped to 0.2
+2002-04-28 23:45 Self-generated distribution archive
+2002-04-27 14:20 Replaced automake symlinks with actual files
+2002-04-07 02:30 Released with configure script
+2002-03-29 01:15 Not yet released. Still integrating autogen stuff...
diff --git a/contrib/libs/libpqxx/README-UPGRADE b/contrib/libs/libpqxx/README-UPGRADE
new file mode 100644
index 0000000000..f0368d6875
--- /dev/null
+++ b/contrib/libs/libpqxx/README-UPGRADE
@@ -0,0 +1,11 @@
+NOTICES FOR USERS UPGRADING FROM EARLIER VERSIONS TO 6.x
+
+As of 6.0, libpqxx requires C++11 or better. Make sure that your libpqxx is
+built against the same version of the C++ standard as your own application, or
+there may be build problems.
+
+It may be possible to paper over some mismatches. If your application build
+fails with errors about `std::experimental::optional`, try defining a macro
+`PQXX_HIDE_EXP_OPTIONAL` in your application's build. This will suppress
+support for `std::experimental::optional` even if libpqxx was built to assume
+that the feature is present.
diff --git a/contrib/libs/libpqxx/README.md b/contrib/libs/libpqxx/README.md
new file mode 100644
index 0000000000..754bb02a40
--- /dev/null
+++ b/contrib/libs/libpqxx/README.md
@@ -0,0 +1,489 @@
+libpqxx
+=======
+
+Welcome to libpqxx, the C++ API to the PostgreSQL database management system.
+
+Compiling this package requires PostgreSQL to be installed -- including the C
+headers for client development. The library builds on top of PostgreSQL's
+standard C API, libpq, though this fact is almost completely hidden from
+programmes which use libpqxx.
+
+As of release 6.0, C++11 is the minimum supported C++ version. Make sure your
+compiler supports this, and if necessary, that you have support for C++11
+configured.
+
+**Version 7.0 will require C++17.** However, it's probably not a problem if
+your compiler does not implement C++17 fully. Initially the 7.x series will
+only require some basic C++17 features such as `std::string_view`. More
+advanced use may follow later.
+
+Also, **7.0 will make some breaking changes in rarely used APIs:**
+ * All `connection` classes will be folded into a single class.
+ * Custom `connection` classes will no longer be supported.
+ * Connection reactivation will be explicit: _you_ call `activate()` if needed.
+ * "String traits" (for string conversions) will have a slightly different API.
+
+Find libpqxx on Github: https://github.com/jtv/libpqxx
+
+
+Building libpqxx
+----------------
+
+There are three very different ways of building libpqxx:
+ 1. Using CMake, on any system which supports it.
+ 2. On Unix-like systems, using a `configure` script.
+ 3. With Visual Studio on Windows, using supplied project files and headers.
+
+The CMake build should work on any system where CMake is supported. This is a
+recently contributed alternative build, so if you run into problems, your help
+could be crucial in fixing them.
+
+The "Unix-like" section applies to systems that look like Unix: GNU/Linux,
+Apple OSX and the BSD family, AIX, HP-UX, Irix, Solaris, etc. Microsoft
+Windows with a Unix-like environment such as Cygwin or MinGW installed should
+also work in the same way.
+
+There is a separate section below for a Visual C++ build on Windows. It takes
+a bit of work, and if the CMake build works well, we may drop support for the
+Windows/Visual C++ build later.
+
+
+### Using CMake
+
+On CMake the standard way of working is to have the source tree in one
+directory, and build in another. (The `configure` script supports this as
+well, but that build is enough work that I didn't bother documenting it.)
+Let's say you have the libpqxx source tree in a location `$SOURCE`, and are
+building in a different location `$BUILD`.
+
+CMake also lets you choose whether to run the ultimate build through `make`,
+or some other tool. The default on Unix-like systems is `make`, but you may
+have to look in the CMake documentation what works well on your system.
+
+For a default build, using those two directories, go into `$BUILD` and run:
+
+```shell
+ cmake $SOURCE
+```
+
+This sets up the build, in your current directory.
+
+Stay in the `$SOURCE` directory, and run:
+
+```shell
+ make
+```
+
+If you have multiple cores that you want to put to good use, use the `-j`
+option to make it run multiple jobs in parallel. For instance, if you have 8
+CPU cores, you'll probably want to be compiling about 8 files simultaneously:
+
+```shell
+ make -j8
+```
+
+
+### On Unix-like systems
+
+For the Unix-like systems the procedure is the standard "configure, make, make
+install" sequence. In order to run the test suite, you'll also need to set up a
+database for the tests to play with.
+
+Run the "configure" script with the `--help` option to see build and
+installation options. You need to get these right before you compile. Then:
+
+```shell
+ ./configure # (plus any options you find appropriate)
+ make
+```
+
+This will compile the library. You'll also want to run the test suite to make
+sure that everything works. To prepare for that, you need to set up a
+disposable test database that the test suite to play with. You'll want
+password-less authentication so that you won't need to log in for every test.
+
+In this example, the test database is called pqxx-test and runs on a server at
+IP address 192.168.1.99. Before running the test, make sure you can log into
+your test database with psql, the command-line SQL shell that comes with
+PostgreSQL:
+
+```shell
+ PGHOST=192.168.1.99 PGDATฺABASE=pqxx-test psql
+```
+
+Once you have that working, use the same login parameters to run the libpqxx
+test suite:
+
+```shell
+ make PGHOST=192.168.1.99 PGDATABASE=pqxx-test check
+```
+
+
+Assuming that the test suite runs successfully, you are now ready to install.
+You'll typically need superuser privileges to run this command:
+
+```shell
+ make install
+```
+
+Now you should be able to link your own programs with libpqxx.
+
+If something went wrong along the way, or what you have isn't quite what you
+wanted, it's time to move on to that fineprint that we hinted at earlier.
+
+
+#### 1. Configure
+
+A word on the configure script. It needs to find the C header and the binary
+for libpq, the C-level client library, so that the libpqxx build procedure can
+make use of them.
+
+The configure script finds these files by running a script called pg\_config
+that comes with PostgresQL. If you have postgres installed, pg\_config should
+be somewhere on your system. It will "know" where the relevant files are. The
+configure script just needs to run it.
+
+Make sure that the folder containing pg\_config is in your executable path
+before you run the configure script, or it will fail with a message like:
+
+```
+configure: error: PostgreSQL configuration script pg_config was not found.
+```
+
+If you don't want to have pg\_config in your path for whatever reason, or you
+have multiple PostgreSQL installations on your system (each with their own copy
+of pg\_config) and wish to override the default version, add an option like
+this to your "configure" command line:
+
+```shell
+ PG_CONFIG=/home/me/postgres/bin/pg_config
+```
+
+Here, "/home/me/postgres/bin/pg\_config" is just an example of where your
+preferred copy of pg\_config might be. This would tell the configure script
+that you wish to build a libpqxx based on the postgres version found in
+/home/me/postgres.
+
+About installing: if you wish to install libpqxx in a custom location, such as
+your home directory /home/me, you can specify this to the configure script
+before you build libpqxx. You select the installation location using the
+configure script's --prefix option, e.g.:
+
+```shell
+ ./configure --prefix=/home/me
+```
+
+A custom location can be useful to keep locally-build software separate from
+packaged software. Conventional installation locations for custom software on
+Unix-like systems are /usr/local and /opt.
+
+Custom installation locations can also be handy if you don't have administrator
+rights on the machine you're working on!
+
+The configure scripts supports many other options to tweak how and where
+libpqxx is to be built and installed; try the --help option to get an overview
+if you're interested.
+
+If configuration just plain won't work for whatever reason: take a look in the
+config/sample-headers/ directory. Here you will find configuration headers for
+various compilers and libpq versions. Pick the config-internal-\*.h and
+config-public-\*.h headers for the compiler and libpq version most closely
+matching your own, and see if they work for you. You may also want to tweak
+them manually.
+
+
+#### 2. Make
+
+One problem some people have run into at this stage is that the header files
+for PostgreSQL need the OpenSSL header files to be installed. If this happens
+to you, make sure openssl is installed and its headers are in your compiler's
+include path.
+
+
+#### 3. Make Check
+
+"Make check" is where you compile and run the test suite that verifies the
+library's functionality.
+
+The "make check" procedure needs a database to play with. It will create and
+drop various tables in that database. Use a throwaway database for this or
+risk losing data!
+
+(Actually the test only manipulates tables whose names start with "pqxx" so in
+practice the risk will be small. But better safe than sorry: use a disposable
+test database separate from your own data.)
+
+To direct the test suite to the right database, set some or all of the
+following environment variables as needed for "make check":
+
+```
+ PGDATABASE (name of database; defaults to your user name)
+ PGHOST (database server; defaults to local machine)
+ PGPORT (TCP port to connect to; default is 5432)
+ PGUSER (your PostgreSQL user ID; defaults to your login name)
+ PGPASSWORD (your PostgreSQL password, if needed)
+```
+
+Further environment variables that may be of use to you are documented in the
+libpq documentation and in the manpage for Postgres' command-line client, psql.
+
+Setting environment variables works differently depending on your shell, but
+try one of these:
+
+```shell
+ VARIABLE=value
+ export VARIABLE
+```
+
+or
+
+```shell
+ set VARIABLE=value
+```
+
+Try printing the variable afterwards to make sure. The command is normally
+
+```shell
+ echo $VARIABLE
+```
+
+If you set the variable successfully, it should print the value you assigned.
+It will print nothing if you failed to set the variable.
+
+On Unix-like systems, postgres may be listening on a Unix domain socket instead
+of a TCP port. The socket will appear as a file somewhere in the filesystem
+with a name like .s.PGSQL.5432. To connect to this type of socket, set PGHOST
+to the directory where you find this file, as an absolute path. For example,
+it may be "/tmp" or "/var/run" or "/var/run/postgresql". The leading slash
+tells libpq that this is not a network address but a local Unix socket.
+
+
+#### 4. Make Install
+
+This is where you install the libpqxx library and header files to your system.
+
+Assuming this succeeds, you should now be able to build your own programs by
+adding the location of the header files (e.g. /usr/local/pqxx/include) to your
+compiler's include path when compiling your application. Similarly, add the
+location of the library binary (e.g. /usr/local/pqxx/lib) to your library
+search path when linking your application. See the documentation and the test
+programs for more information on using libpqxx.
+
+If you link with the dynamic version of the library, you may find that your
+program fails to run because the run-time loader cannot find the library.
+
+There are several ways around that. Pick the first option that works for you:
+1. by linking to the static version of the library, or
+2. adding a link to the dynamic libpqxx library somewhere in your system's
+ standard library locations, or
+3. adding libpqxx's lib/ directory to your loader's search path before
+ running your program.
+
+On Unix-like systems including GNU/Linux, the loader's search path can be
+extended by setting the LD\_LIBRARY\_PATH variable.
+
+Enjoy!
+
+
+### On Microsoft Windows
+
+Project files for Visual C++ are provided in the win32 directory, along with
+some other Windows-specific material. These are very old, so if you run into
+problems, please let us know what we can do to fix them. One known problem is
+that _folder names with spaces in them_ cause trouble. If you run into
+trouble, try using the alternative build using CMake!
+
+As yet another alternative, if you are running a Unix-like environment such as
+Cygwin, you may want to try if the Unix build procedure works for you. In
+theory it should be possible to run the configure script and build with Visual
+C++ or any other compiler, so long as you have a reasonably Unix-like shell
+environment.
+
+If you do proceed with the Visual C++ files, you'll need to copy the most
+appropriate compile-time configuration files from various subdirectories in
+config/example-headers/ to include/pqxx. You'll want to tweak them manually
+to define the exact features your system, compiler, and PostgreSQL versions
+support. On a Unix-like system the configure script would do this for you.
+
+Before trying to compile with Visual C++, you'll at least need to copy the file
+win32/common-sample to win32/common, and edit the latter to reflect the proper
+paths to your PostgreSQL headers and the libpq library. See the win32
+subdirectory for more documentation.
+
+
+#### Manual Configuration: config-\*-\*.h
+
+Normally, on any vaguely Unix-like system, the configuration headers (called
+config-internal-\*.h for the library's internal use, config-public-\*.h for
+both the library and client programs) are generated from config.h.in. All
+these files, once generated, are situated in the include/pqxx/ directory.
+
+The configitems file lists all configuration items and where they go; but see
+win32/INSTALL.txt for a detailed description of how these files work.
+
+Getting the compiler-related configuration right can take several stages of
+trying to build, looking at error messages, looking for configuration items
+that may be related, changing them, and building again. If nothing seems to
+help, register an issue on Github. Be sure to read the FAQ though, because
+there are some known problems.
+
+
+#### Windows-Specific Build Problems
+
+One problem specific to Windows is that apparently it doesn't let you free
+memory in a DLL that was allocated in the main program or in another DLL, or
+vice versa. This can cause trouble when setting your own notice handlers to
+process error or warning output. Recommended practice is to build libpqxx as
+a static library, not a DLL.
+
+
+Documentation
+-------------
+
+The doc/ directory contains API reference documentation and a tutorial, both in
+HTML format. These are also available online.
+
+For more detailed information, look at the header files themselves. These are
+in the include/pqxx/ directory. The reference documentation is extracted from
+the headers using a program called Doxygen.
+
+When learning about programming with libpqxx, you'll want to start off by
+reading about the `connection_base` class and its children, as well as the
+`transaction_base` class.
+
+For programming examples, take a look at the test programs in the test/
+directory. If you don't know how a certain function or class is used, try
+searching the test programs for that name.
+
+
+Programming with libpqxx
+------------------------
+
+Your first program will involve the libpqxx classes "connection" (see headers
+`pqxx/connection_base.hxx` and `pqxx/connection.hxx`), and `work` (a
+convenience alias for `transaction<>` which conforms to the interface defined
+in `pqxx/transaction_base.hxx`).
+
+These `*.hxx` headers are not the ones you include in your program. Instead,
+include the versions without filename suffix (e.g. `pqxx/connection_base`).
+Those will include the actual .hxx files for you. This was done so that
+includes are in standard C++ style (as in `<iostream>` etc.), but an editor
+will still recognize them as files containing C++ code.
+
+Continuing the list of classes, you will most likely also need the result class
+(`pqxx/result.hxx`). In a nutshell, you create a `connection` based on a
+Postgres connection string (see below), create a `work` in the context of that
+connection, and run one or more queries on the work which return `result`
+objects. The results are containers of rows of data, each of which you can
+treat as an array of strings: one for each field in the row. It's that simple.
+
+Here is a simple example program to get you going, with full error handling:
+
+```c++
+#include <iostream>
+#include <pqxx/pqxx>
+
+int main()
+{
+ try
+ {
+ pqxx::connection C;
+ std::cout << "Connected to " << C.dbname() << std::endl;
+ pqxx::work W(C);
+
+ pqxx::result R = W.exec("SELECT name FROM employee");
+
+ std::cout << "Found " << R.size() << "employees:" << std::endl;
+ for (auto row: R)
+ std::cout << row[0].c_str() << std::endl;
+
+ std::cout << "Doubling all employees' salaries..." << std::endl;
+ W.exec("UPDATE employee SET salary = salary*2");
+
+ std::cout << "Making changes definite: ";
+ W.commit();
+ std::cout << "OK." << std::endl;
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+```
+
+
+Connection strings
+------------------
+
+Postgres connection strings state which database server you wish to connect to,
+under which username, using which password, and so on. Their format is defined
+in the documentation for libpq, the C client interface for PostgreSQL.
+Alternatively, these values may be defined by setting certain environment
+variables as documented in e.g. the manual for psql, the command line interface
+to PostgreSQL. Again the definitions are the same for libpqxx-based programs.
+
+The connection strings and variables are not fully and definitively documented
+here; this document will tell you just enough to get going. Check the
+PostgreSQL documentation for authoritative information.
+
+The connection string consists of attribute=value pairs separated by spaces,
+e.g. "user=john password=1x2y3z4". The valid attributes include:
+
+- `host`
+ Name of server to connect to, or the full file path (beginning with a
+ slash) to a Unix-domain socket on the local machine. Defaults to
+ "/tmp". Equivalent to (but overrides) environment variable PGHOST.
+
+- `hostaddr`
+ IP address of a server to connect to; mutually exclusive with "host".
+
+- `port`
+ Port number at the server host to connect to, or socket file name
+ extension for Unix-domain connections. Equivalent to (but overrides)
+ environment variable PGPORT.
+
+- `dbname`
+ Name of the database to connect to. A single server may host multiple
+ databases. Defaults to the same name as the current user's name.
+ Equivalent to (but overrides) environment variable PGDATABASE.
+
+- `user`
+ User name to connect under. This defaults to the name of the current
+ user, although PostgreSQL users are not necessarily the same thing as
+ system users.
+
+- `requiressl`
+ If set to 1, demands an encrypted SSL connection (and fails if no SSL
+ connection can be created).
+
+Settings in the connection strings override the environment variables, which in
+turn override the default, on a variable-by-variable basis. You only need to
+define those variables that require non-default values.
+
+
+Linking with libpqxx
+--------------------
+
+To link your final program, make sure you link to both the C-level libpq library
+and the actual C++ library, libpqxx. With most Unix-style compilers, you'd do
+this using the options
+
+```
+ -lpqxx -lpq
+```
+
+while linking. Both libraries must be in your link path, so the linker knows
+where to find them. Any dynamic libraries you use must also be in a place
+where the loader can find them when loading your program at runtime.
+
+Some users have reported problems using the above syntax, however, particularly
+when multiple versions of libpqxx are partially or incorrectly installed on the
+system. If you get massive link errors, try removing the "-lpqxx" argument from
+the command line and replacing it with the name of the libpqxx library binary
+instead. That's typically libpqxx.a, but you'll have to add the path to its
+location as well, e.g. /usr/local/pqxx/lib/libpqxx.a. This will ensure that the
+linker will use that exact version of the library rather than one found
+elsewhere on the system, and eliminate worries about the exact right version of
+the library being installed with your program..
diff --git a/contrib/libs/libpqxx/include/pqxx/array b/contrib/libs/libpqxx/include/pqxx/array
new file mode 100644
index 0000000000..97311d1c18
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/array
@@ -0,0 +1,4 @@
+/** Handling of SQL arrays.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/array.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/array.hxx b/contrib/libs/libpqxx/include/pqxx/array.hxx
new file mode 100644
index 0000000000..dbb464c540
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/array.hxx
@@ -0,0 +1,101 @@
+/** Handling of SQL arrays.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead.
+ *
+ * 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_ARRAY
+#define PQXX_H_ARRAY
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/internal/encoding_group.hxx"
+#include "pqxx/internal/encodings.hxx"
+
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+
+namespace pqxx
+{
+/// Low-level array parser.
+/** Use this to read an array field retrieved from the database.
+ *
+ * This parser will only work reliably if your client encoding is UTF-8, ASCII,
+ * or a single-byte encoding which is a superset of ASCII (such as Latin-1).
+ *
+ * Also, the parser only supports array element types which use either a comma
+ * or a semicolon ("," or ";") as the separator between array elements. All
+ * built-in types use comma, except for one which uses semicolon, but some
+ * custom types may not work.
+ *
+ * The input is a C-style string containing the textual representation of an
+ * array, as returned by the database. The parser reads this representation
+ * on the fly. The string must remain in memory until parsing is done.
+ *
+ * Parse the array by making calls to @c get_next until it returns a
+ * @c juncture of "done". The @c juncture tells you what the parser found in
+ * that step: did the array "nest" to a deeper level, or "un-nest" back up?
+ */
+class PQXX_LIBEXPORT array_parser
+{
+public:
+ /// What's the latest thing found in the array?
+ enum juncture
+ {
+ /// Starting a new row.
+ row_start,
+ /// Ending the current row.
+ row_end,
+ /// Found a NULL value.
+ null_value,
+ /// Found a string value.
+ string_value,
+ /// Parsing has completed.
+ done,
+ };
+
+// XXX: Actually _pass_ encoding group!
+ /// Constructor. You don't need this; use @c field::as_array instead.
+ explicit array_parser(
+ const char input[],
+ internal::encoding_group=internal::encoding_group::MONOBYTE);
+
+ /// Parse the next step in the array.
+ /** Returns what it found. If the juncture is @c string_value, the string
+ * will contain the value. Otherwise, it will be empty.
+ *
+ * Call this until the @c juncture it returns is @c done.
+ */
+ std::pair<juncture, std::string> get_next();
+
+private:
+ const char *const m_input;
+ const std::string::size_type m_end;
+ internal::glyph_scanner_func *const m_scan;
+
+ /// Current parsing position in the input.
+ std::string::size_type m_pos;
+
+ std::string::size_type scan_single_quoted_string() const;
+ std::string parse_single_quoted_string(std::string::size_type end) const;
+ std::string::size_type scan_double_quoted_string() const;
+ std::string parse_double_quoted_string(std::string::size_type end) const;
+ std::string::size_type scan_unquoted_string() const;
+ std::string parse_unquoted_string(std::string::size_type end) const;
+
+ std::string::size_type scan_glyph(std::string::size_type pos) const;
+ std::string::size_type scan_glyph(
+ std::string::size_type pos,
+ std::string::size_type end) const;
+};
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/basic_connection.hxx b/contrib/libs/libpqxx/include/pqxx/basic_connection.hxx
new file mode 100644
index 0000000000..6e7372195a
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/basic_connection.hxx
@@ -0,0 +1,107 @@
+/** Definition of the pqxx::basic_connection class template.
+ *
+ * Instantiations of basic_connection bring connections and policies together.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/basic_connection instead.
+ *
+ * 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_BASIC_CONNECTION
+#define PQXX_H_BASIC_CONNECTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include "pqxx/connection_base.hxx"
+
+
+namespace pqxx
+{
+
+/// Base-class template for all libpqxx connection types.
+/** @deprecated In libpqxx 7, all built-in connection types will be implemented
+ * as a single class. You'll specify the connection policy as an optional
+ * constructor argument.
+ *
+ * Combines connection_base (the highly complex class implementing essentially
+ * all connection-related functionality) with a connection policy (a simpler
+ * helper class determining the rules that govern the process of setting up the
+ * underlying connection to the backend).
+ *
+ * The pattern used to combine these classes is the same as for
+ * basic_transaction. Through use of the template mechanism, the policy object
+ * is embedded in the basic_connection object so that it does not need to be
+ * allocated separately. This also avoids the need for virtual functions in
+ * this class.
+ */
+template<typename CONNECTPOLICY> class basic_connection_base :
+ public connection_base
+{
+public:
+ basic_connection_base() :
+ connection_base(m_policy),
+ m_options(std::string{}),
+ m_policy(m_options)
+ { init(); }
+
+ /// The parsing of options is the same as libpq's PQconnect.
+ /// See: https://www.postgresql.org/docs/10/static/libpq-connect.html
+ explicit basic_connection_base(const std::string &opt) :
+ connection_base(m_policy),
+ m_options(opt),
+ m_policy(m_options)
+ {init();}
+
+ /// See: @c basic_connection(const std::string &opt)
+ explicit basic_connection_base(const char opt[]) :
+ basic_connection_base(opt ? std::string{opt} : std::string{}) {}
+
+ explicit basic_connection_base(std::nullptr_t) : basic_connection_base() {}
+
+ ~basic_connection_base() noexcept
+ { close(); }
+
+ const std::string &options() const noexcept //[t01]
+ {return m_policy.options();}
+
+private:
+ /// Connect string. @warn Must be initialized before the connector!
+ std::string m_options;
+ /// Connection policy. @warn Must be initialized after the connect string!
+ CONNECTPOLICY m_policy;
+};
+
+
+/// Concrete connection type template.
+/** @deprecated In libpqxx 7, all built-in connection types will be implemented
+ * as a single class. You'll specify the connection policy as an optional
+ * constructor argument.
+ */
+template<typename CONNECTPOLICY> struct basic_connection :
+ basic_connection_base<CONNECTPOLICY>
+{
+ PQXX_DEPRECATED basic_connection() =default;
+ PQXX_DEPRECATED explicit basic_connection(const std::string &opt) :
+ basic_connection(opt) {}
+ PQXX_DEPRECATED explicit basic_connection(const char opt[]) :
+ basic_connection(opt) {}
+
+ PQXX_DEPRECATED explicit basic_connection(std::nullptr_t) :
+ basic_connection() {}
+
+ using basic_connection_base<CONNECTPOLICY>::options;
+};
+
+} // namespace
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/binarystring b/contrib/libs/libpqxx/include/pqxx/binarystring
new file mode 100644
index 0000000000..4214f0257d
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/binarystring
@@ -0,0 +1,4 @@
+/** BYTEA (binary string) conversions.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/binarystring.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/binarystring.hxx b/contrib/libs/libpqxx/include/pqxx/binarystring.hxx
new file mode 100644
index 0000000000..4262938ef3
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/binarystring.hxx
@@ -0,0 +1,157 @@
+/** Representation for raw, binary data.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead.
+ *
+ * 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_BINARYSTRING
+#define PQXX_H_BINARYSTRING
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <memory>
+#include <string>
+
+#include "pqxx/result.hxx"
+
+
+namespace pqxx
+{
+
+/// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type.
+/** @ingroup escaping-functions
+ *
+ * This class represents a binary string as stored in a field of type bytea.
+ * The raw value returned by a bytea field contains escape sequences for certain
+ * characters, which are filtered out by binarystring.
+ *
+ * Internally a binarystring is zero-terminated, but it may also contain zero
+ * bytes, just like any other byte value. So don't assume that it can be
+ * treated as a C-style string unless you've made sure of this yourself.
+ *
+ * The binarystring retains its value even if the result it was obtained from is
+ * destroyed, but it cannot be copied or assigned.
+ *
+ * \relatesalso transaction_base::esc_raw
+ *
+ * To convert the other way, i.e. from a raw series of bytes to a string
+ * suitable for inclusion as bytea values in your SQL, use the transaction's
+ * esc_raw() functions.
+ *
+ * @warning This class is implemented as a reference-counting smart pointer.
+ * Copying, swapping, and destroying binarystring objects that refer to the same
+ * underlying data block is <em>not thread-safe</em>. If you wish to pass
+ * binarystrings around between threads, make sure that each of these operations
+ * is protected against concurrency with similar operations on the same object,
+ * or other objects pointing to the same data block.
+ */
+class PQXX_LIBEXPORT binarystring
+{
+public:
+ using char_type = unsigned char;
+ using value_type = std::char_traits<char_type>::char_type;
+ using size_type = size_t;
+ using difference_type = long;
+ using const_reference = const value_type &;
+ using const_pointer = const value_type *;
+ using const_iterator = const_pointer;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ binarystring(const binarystring &) =default;
+
+ /// Read and unescape bytea field
+ /** The field will be zero-terminated, even if the original bytea field isn't.
+ * @param F the field to read; must be a bytea field
+ */
+ explicit binarystring(const field &); //[t62]
+
+ /// Copy binary data from std::string.
+ explicit binarystring(const std::string &);
+
+ /// Copy binary data of given length straight out of memory.
+ binarystring(const void *, size_t);
+
+ /// Size of converted string in bytes
+ size_type size() const noexcept { return m_size; } //[t62]
+ /// Size of converted string in bytes
+ size_type length() const noexcept { return size(); } //[t62]
+ bool empty() const noexcept { return size()==0; } //[t62]
+
+ const_iterator begin() const noexcept { return data(); } //[t62]
+ const_iterator cbegin() const noexcept { return begin(); }
+ const_iterator end() const noexcept { return data()+m_size; } //[t62]
+ const_iterator cend() const noexcept { return end(); }
+
+ const_reference front() const noexcept { return *begin(); } //[t62]
+ const_reference back() const noexcept //[t62]
+ { return *(data()+m_size-1); }
+
+ const_reverse_iterator rbegin() const //[t62]
+ { return const_reverse_iterator{end()}; }
+ const_reverse_iterator crbegin() const { return rbegin(); }
+ const_reverse_iterator rend() const //[t62]
+ { return const_reverse_iterator{begin()}; }
+ const_reverse_iterator crend() const { return rend(); }
+
+ /// Unescaped field contents
+ const value_type *data() const noexcept {return m_buf.get();} //[t62]
+
+ const_reference operator[](size_type i) const noexcept //[t62]
+ { return data()[i]; }
+
+ PQXX_PURE bool operator==(const binarystring &) const noexcept; //[t62]
+ bool operator!=(const binarystring &rhs) const noexcept //[t62]
+ { return not operator==(rhs); }
+
+ binarystring &operator=(const binarystring &);
+
+ /// Index contained string, checking for valid index
+ const_reference at(size_type) const; //[t62]
+
+ /// Swap contents with other binarystring
+ void swap(binarystring &); //[t62]
+
+ /// Raw character buffer (no terminating zero is added)
+ /** @warning No terminating zero is added! If the binary data did not end in
+ * a null character, you will not find one here.
+ */
+ const char *get() const noexcept //[t62]
+ { return reinterpret_cast<const char *>(m_buf.get()); }
+
+ /// Read as regular C++ string (may include null characters)
+ /** @warning libpqxx releases before 3.1 stored the string and returned a
+ * reference to it. This is no longer the case! It now creates and returns
+ * a new string object. Avoid repeated use of this function; retrieve your
+ * string once and keep it in a local variable. Also, do not expect to be
+ * able to compare the string's address to that of an earlier invocation.
+ */
+ std::string str() const; //[t62]
+
+private:
+ using smart_pointer_type = std::shared_ptr<value_type>;
+
+ /// Shorthand: construct a smart_pointer_type.
+ static smart_pointer_type make_smart_pointer(unsigned char *buf=nullptr)
+ {
+#if !(defined(_MSC_VER) && defined(__clang__))
+ return smart_pointer_type{
+ buf,
+ internal::freemallocmem_templated<unsigned char>};
+#else
+ return smart_pointer_type{buf, internal::freemallocmem};
+#endif
+ }
+
+ smart_pointer_type m_buf;
+ size_type m_size;
+};
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/compiler-internal-post.hxx b/contrib/libs/libpqxx/include/pqxx/compiler-internal-post.hxx
new file mode 100644
index 0000000000..6af34b5d30
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/compiler-internal-post.hxx
@@ -0,0 +1,21 @@
+/** Compiler deficiency workarounds for compiling libpqxx headers.
+ *
+ * To be included at the end of each libpqxx header, in order to restore the
+ * client program's settings.
+ *
+ * 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.
+ */
+// NO GUARDS HERE! This code should be executed every time!
+
+#ifdef _WIN32
+
+#ifdef _MSC_VER
+#pragma warning (pop) // Restore client program's warning state
+#endif
+
+#endif
+
diff --git a/contrib/libs/libpqxx/include/pqxx/compiler-internal-pre.hxx b/contrib/libs/libpqxx/include/pqxx/compiler-internal-pre.hxx
new file mode 100644
index 0000000000..ac3a7b89ab
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/compiler-internal-pre.hxx
@@ -0,0 +1,35 @@
+/** Compiler deficiency workarounds for compiling libpqxx headers.
+ *
+ * To be called at the start of each libpqxx header, in order to push the
+ * client program's settings and apply libpqxx's settings.
+ *
+ * Must be balanced by an include of -header-post.hxx at the end
+ * of the header.
+ *
+ * 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.
+ */
+// NO GUARDS HERE! This code should be executed every time!
+
+#ifdef _WIN32
+#ifdef _MSC_VER
+
+// Save client program warning state, and set warning level 4.
+// Setting the warning level explicitly ensures that libpqxx
+// headers will work with this warning level as well.
+#pragma warning (push,4)
+
+#pragma warning (disable: 4251)
+#pragma warning (disable: 4273)
+#pragma warning (disable: 4275)
+#pragma warning (disable: 4355)
+#pragma warning (disable: 4511) // Copy constructor could not be generated.
+#pragma warning (disable: 4512) // Assignment operator could not be generated.
+#pragma warning (disable: 4996) // Deprecation warning, e.g. about strncpy().
+
+#endif // _MSC_VER
+#endif // _WIN32
+
diff --git a/contrib/libs/libpqxx/include/pqxx/compiler-internal.hxx b/contrib/libs/libpqxx/include/pqxx/compiler-internal.hxx
new file mode 100644
index 0000000000..9743f47866
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/compiler-internal.hxx
@@ -0,0 +1,42 @@
+/** Compiler deficiency workarounds for compiling libpqxx itself.
+ *
+ * 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.
+ */
+#ifndef PQXX_H_COMPILER_INTERNAL
+#define PQXX_H_COMPILER_INTERNAL
+
+
+// Workarounds & definitions needed to compile libpqxx into a library
+#include "pqxx/config-internal-compiler.h"
+
+#ifdef _WIN32
+
+#ifdef PQXX_SHARED
+#undef PQXX_LIBEXPORT
+#define PQXX_LIBEXPORT __declspec(dllexport)
+#define PQXX_PRIVATE __declspec()
+#endif // PQXX_SHARED
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4251 4275 4273)
+#pragma warning (disable: 4355)
+#pragma warning (disable: 4996) // Deprecation warning, e.g. about strncpy().
+#endif
+
+#elif defined(__GNUC__) && defined(PQXX_HAVE_GCC_VISIBILITY) // !_WIN32
+
+#define PQXX_LIBEXPORT __attribute__ ((visibility("default")))
+#define PQXX_PRIVATE __attribute__ ((visibility("hidden")))
+
+#endif // __GNUC__ && PQXX_HAVE_GCC_VISIBILITY
+
+
+#include "pqxx/compiler-public.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/compiler-public.hxx b/contrib/libs/libpqxx/include/pqxx/compiler-public.hxx
new file mode 100644
index 0000000000..352956c237
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/compiler-public.hxx
@@ -0,0 +1,122 @@
+/** Compiler deficiency workarounds for libpqxx clients.
+ *
+ * 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_COMPILER_PUBLIC
+#define PQXX_H_COMPILER_PUBLIC
+
+// Workarounds & definitions that need to be included even in library's headers
+#include "pqxx/config-public-compiler.h"
+
+// Some compilers, Visual Studio in particular, don't seem to support the
+// standard's ISO-646 keywords out of the box.
+#include <ciso646>
+
+
+#if defined(__GNUC__) && defined(PQXX_HAVE_GCC_CONST)
+/// Declare function without effects and without reading anything but its args.
+#define PQXX_CONST __attribute__ ((const))
+#else
+#define PQXX_CONST
+#endif
+
+#if defined(PQXX_HAVE_DEPRECATED)
+/// Mark an item as deprecated.
+#define PQXX_DEPRECATED [[deprecated]]
+#elif defined(__GNUC__) && defined(PQXX_HAVE_GCC_DEPRECATED)
+#define PQXX_DEPRECATED __attribute__ ((deprecated))
+#else
+#define PQXX_DEPRECATED
+#endif
+
+#if defined(__GNUC__) && defined(PQXX_HAVE_GCC_PURE)
+/// Declare function "pure": no side effects, only reads globals and its args.
+#define PQXX_PURE __attribute__ ((pure))
+#else
+#define PQXX_PURE
+#endif
+
+
+// Workarounds for Windows
+#ifdef _WIN32
+
+/* For now, export DLL symbols if _DLL is defined. This is done automatically
+ * by the compiler when linking to the dynamic version of the runtime library,
+ * according to "gzh"
+ */
+#if !defined(PQXX_LIBEXPORT) && defined(PQXX_SHARED)
+#define PQXX_LIBEXPORT __declspec(dllimport)
+#endif // !PQXX_LIBEXPORT && PQXX_SHARED
+
+
+// Workarounds for Microsoft Visual C++
+#ifdef _MSC_VER
+
+// Suppress vtables on abstract classes.
+#define PQXX_NOVTABLE __declspec(novtable)
+
+// Automatically link with the appropriate libpq (static or dynamic, debug or
+// release). The default is to use the release DLL. Define PQXX_PQ_STATIC to
+// link to a static version of libpq, and _DEBUG to link to a debug version.
+// The two may be combined.
+#if defined(PQXX_AUTOLINK)
+#if defined(PQXX_PQ_STATIC)
+#ifdef _DEBUG
+#pragma comment(lib, "libpqd")
+#else
+#pragma comment(lib, "libpq")
+#endif
+#else
+#ifdef _DEBUG
+#pragma comment(lib, "libpqddll")
+#else
+#pragma comment(lib, "libpqdll")
+#endif
+#endif
+#endif
+
+// If we're not compiling libpqxx itself, automatically link with the
+// appropriate libpqxx library. To link with the libpqxx DLL, define
+// PQXX_SHARED; the default is to link with the static library. A static link
+// is the recommended practice.
+//
+// The preprocessor macro PQXX_INTERNAL is used to detect whether we
+// are compiling the libpqxx library itself. When you compile the library
+// yourself using your own project file, make sure to include this macro.
+#if defined(PQXX_AUTOLINK) && !defined(PQXX_INTERNAL)
+ #ifdef PQXX_SHARED
+ #ifdef _DEBUG
+ #pragma comment(lib, "libpqxxD")
+ #else
+ #pragma comment(lib, "libpqxx")
+ #endif
+ #else // !PQXX_SHARED
+ #ifdef _DEBUG
+ #pragma comment(lib, "libpqxx_staticD")
+ #else
+ #pragma comment(lib, "libpqxx_static")
+ #endif
+ #endif
+#endif
+
+#endif // _MSC_VER
+#endif // _WIN32
+
+
+#ifndef PQXX_LIBEXPORT
+#define PQXX_LIBEXPORT
+#endif
+
+#ifndef PQXX_PRIVATE
+#define PQXX_PRIVATE
+#endif
+
+#ifndef PQXX_NOVTABLE
+#define PQXX_NOVTABLE
+#endif
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/config-internal-compiler.h b/contrib/libs/libpqxx/include/pqxx/config-internal-compiler.h
new file mode 100644
index 0000000000..ddf45f0db7
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/config-internal-compiler.h
@@ -0,0 +1,14 @@
+/* Automatically generated from config.h: internal/compiler config. */
+
+#include <util/system/platform.h>
+
+#if defined(_linux_) || defined(_darwin_)
+
+# define HAVE_POLL 1
+# define HAVE_SYS_TIME_H 1
+# define HAVE_SYS_TYPES_H 1
+# define HAVE_UNISTD_H 1
+# define PQXX_HAVE_CHARCONV_INT 1
+# define PQXX_HAVE_GCC_VISIBILITY 1
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/config-public-compiler.h b/contrib/libs/libpqxx/include/pqxx/config-public-compiler.h
new file mode 100644
index 0000000000..5a6feb5739
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/config-public-compiler.h
@@ -0,0 +1,11 @@
+/* Automatically generated from config.h: public/compiler config. */
+
+#ifndef _MSC_VER
+#define PQXX_HAVE_DEPRECATED 1
+#endif
+#ifndef _MSC_VER
+#define PQXX_HAVE_GCC_CONST 1
+#define PQXX_HAVE_GCC_DEPRECATED 1
+#define PQXX_HAVE_GCC_PURE 1
+#endif
+#define PQXX_HAVE_OPTIONAL 1
diff --git a/contrib/libs/libpqxx/include/pqxx/connection b/contrib/libs/libpqxx/include/pqxx/connection
new file mode 100644
index 0000000000..d08e357e93
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/connection
@@ -0,0 +1,6 @@
+/** pqxx::connection and pqxx::lazyconnection classes.
+ *
+ * Different ways of setting up a backend connection.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/connection.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/connection.hxx b/contrib/libs/libpqxx/include/pqxx/connection.hxx
new file mode 100644
index 0000000000..cb00743fec
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/connection.hxx
@@ -0,0 +1,170 @@
+/** Definition of the pqxx::connection and pqxx::lazyconnection classes.
+ *
+ * Different ways of setting up a backend connection.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead.
+ *
+ * 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_CONNECTION
+#define PQXX_H_CONNECTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/connectionpolicy.hxx"
+#include "pqxx/basic_connection.hxx"
+
+namespace pqxx
+{
+
+/**
+ * @addtogroup connection Connection classes
+ *
+ * The connection classes are where the use of a database begins. You must
+ * connect to a database in order to access it. Your connection represents a
+ * session with the database. In the context of that connection you can create
+ * transactions, which in turn you can use to execute SQL. A connection can
+ * have only one regular transaction open at a time, but you can break your work
+ * down into any number of consecutive transactions and there is also some
+ * support for transaction nesting (using the subtransaction class).
+ *
+ * Many things come together in the connection classes. Handling of error and
+ * warning messages, for example, is defined by @e errorhandlers in the context
+ * of a connection. Prepared statements are also defined here.
+ *
+ * @warning In libpqxx 7, all built-in connection types will be implemented
+ * as a single class. You'll specify the connection policy as an optional
+ * constructor argument.
+ *
+ * Several types of connections are available, including plain connection and
+ * lazyconnection. These types are aliases combining a derivative of the
+ * connection_base class (where essentially all connection-related functionality
+ * is defined) with a policy class which governs how the connection is to be
+ * established. You pass details such as the database you wish to connect to,
+ * username and password, and so on as as PostgreSQL "connection string" and
+ * certain environment variables that you can learn more about from the core
+ * postgres documentation.
+ *
+ * See the connection_base documentation for a full list of features inherited
+ * by all connection classes. Connections can be deactivated and reactivated if
+ * needed (within reason, of course--you can't do this in the middle of a
+ * transaction), and where possible, disabled or broken connections are
+ * transparently re-enabled when you use them again. This is called
+ * "reactivation," and you may need to understand it because you'll want it
+ * disabled in certain situations.
+ *
+ * @warning Connection deactivation/reactivation will probably be removed in
+ * libpqxx 7. If your application relies on an ability to "put connections to
+ * sleep" and reactivate them later, you'll need to wrap them in some way to
+ * handle this.
+ *
+ * You can also set certain variables defined by the backend to influence its
+ * behaviour for the duration of your session, such as the applicable text
+ * encoding. You can query the connection's capabilities (because some features
+ * will depend on the versions of libpq and of the server backend that you're
+ * using) and parameters that you set in your connection string and/or
+ * environment variables.
+ *
+ * @{
+ */
+
+/// Connection policy; creates an immediate connection to a database.
+/** This is the policy you typically need when you work with a database through
+ * libpqxx. It connects to the database immediately. Another option is to
+ * defer setting up the underlying connection to the database until it's
+ * actually needed; the connect_lazy policy implements such "lazy" * behaviour.
+ *
+ * The advantage of having an "immediate" connection (as this policy gives you)
+ * is that any errors in setting up the connection will occur during
+ * construction of the connection object, rather than at some later point
+ * further down your program.
+ */
+class PQXX_LIBEXPORT connect_direct : public connectionpolicy
+{
+public:
+ /// The parsing of options is the same as in libpq's PQconnect.
+ /// See: https://www.postgresql.org/docs/10/static/libpq-connect.html
+ explicit connect_direct(const std::string &opts) : connectionpolicy{opts} {}
+ virtual handle do_startconnect(handle) override;
+};
+
+/// The "standard" connection type: connect to database right now
+using connection = basic_connection_base<connect_direct>;
+
+
+/// Lazy connection policy; causes connection to be deferred until first use.
+/** This is connect_direct's lazy younger brother. It does not attempt to open
+ * a connection right away; the connection is only created when it is actually
+ * used.
+ */
+class PQXX_LIBEXPORT connect_lazy : public connectionpolicy
+{
+public:
+ /// The parsing of options is the same as in libpq's PQconnect.
+ /// See: https://www.postgresql.org/docs/10/static/libpq-connect.html
+ explicit connect_lazy(const std::string &opts) : connectionpolicy{opts} {}
+ virtual handle do_completeconnect(handle) override;
+};
+
+
+/// A "lazy" connection type: connect to database only when needed
+using lazyconnection = basic_connection_base<connect_lazy>;
+
+
+/// Asynchronous connection policy; connects "in the background"
+/** Connection is initiated immediately, but completion is deferred until the
+ * connection is actually needed.
+ *
+ * This may help performance by allowing the client to do useful work while
+ * waiting for an answer from the server.
+ */
+class PQXX_LIBEXPORT connect_async : public connectionpolicy
+{
+public:
+ /// The parsing of options is the same as in libpq's PQConnect
+ /// See: https://www.postgresql.org/docs/10/static/libpq-connect.html
+ explicit connect_async(const std::string &opts);
+ virtual handle do_startconnect(handle) override;
+ virtual handle do_completeconnect(handle) override;
+ virtual handle do_dropconnect(handle) noexcept override;
+ virtual bool is_ready(handle) const noexcept override;
+
+private:
+ /// Is a connection attempt in progress?
+ bool m_connecting;
+};
+
+
+/// "Asynchronous" connection type: start connecting, but don't wait for it
+using asyncconnection = basic_connection_base<connect_async>;
+
+
+/// Nonfunctional, always-down connection policy for testing/debugging purposes
+/** @warning You don't want to use this policy in normal code.
+ * Written for debugging and testing, this "connection policy" always fails to
+ * connect, and the internal connection pointer always remains null.
+ */
+class PQXX_LIBEXPORT connect_null : public connectionpolicy
+{
+public:
+ explicit connect_null(const std::string &opts) : connectionpolicy{opts} {}
+};
+
+
+/// A "dummy" connection type: don't connect to any database at all
+using nullconnection = basic_connection_base<connect_null>;
+
+/**
+ * @}
+ */
+
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/connection_base b/contrib/libs/libpqxx/include/pqxx/connection_base
new file mode 100644
index 0000000000..187b667cb3
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/connection_base
@@ -0,0 +1,6 @@
+/** pqxx::connection_base abstract base class.
+ *
+ * pqxx::connection_base encapsulates a frontend-to-backend connection.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/connection_base.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/connection_base.hxx b/contrib/libs/libpqxx/include/pqxx/connection_base.hxx
new file mode 100644
index 0000000000..8809639873
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/connection_base.hxx
@@ -0,0 +1,940 @@
+/** Definition of the pqxx::connection_base abstract base class.
+ *
+ * pqxx::connection_base encapsulates a frontend to backend connection
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection_base instead.
+ *
+ * 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_CONNECTION_BASE
+#define PQXX_H_CONNECTION_BASE
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <bitset>
+#include <list>
+#include <map>
+#include <memory>
+
+#include "pqxx/errorhandler.hxx"
+#include "pqxx/except.hxx"
+#include "pqxx/prepared_statement.hxx"
+#include "pqxx/strconv.hxx"
+#include "pqxx/util.hxx"
+#include "pqxx/version.hxx"
+
+
+/* Use of the libpqxx library starts here.
+ *
+ * Everything that can be done with a database through libpqxx must go through
+ * a connection object derived from connection_base.
+ */
+
+/* Methods tested in eg. self-test program test1 are marked with "//[t01]"
+ */
+
+namespace pqxx
+{
+namespace internal
+{
+class reactivation_avoidance_exemption;
+class sql_cursor;
+
+class reactivation_avoidance_counter
+{
+public:
+ reactivation_avoidance_counter() =default;
+
+ void add(int n) noexcept { m_counter += n; }
+ void clear() noexcept { m_counter = 0; }
+ int get() const noexcept { return m_counter; }
+
+private:
+ int m_counter = 0;
+};
+
+}
+
+
+/// Encrypt password for given user.
+/** Use this when setting a new password for the user if password encryption is
+ * enabled. Inputs are the username the password is for, and the plaintext
+ * password.
+ *
+ * @return encrypted version of the password, suitable for encrypted PostgreSQL
+ * authentication.
+ *
+ * Thus the password for a user can be changed with:
+ * @code
+ * void setpw(transaction_base &t, const string &user, const string &pw)
+ * {
+ * t.exec("ALTER USER " + user + " "
+ * "PASSWORD '" + encrypt_password(user,pw) + "'");
+ * }
+ * @endcode
+ */
+std::string PQXX_LIBEXPORT encrypt_password( //[t00]
+ const std::string &user,
+ const std::string &password);
+
+
+namespace internal
+{
+namespace gate
+{
+class connection_dbtransaction;
+class connection_errorhandler;
+class connection_largeobject;
+class connection_notification_receiver;
+class connection_parameterized_invocation;
+class connection_pipeline;
+class connection_prepare_invocation;
+class connection_reactivation_avoidance_exemption;
+class connection_sql_cursor;
+class connection_transaction;
+class const_connection_largeobject;
+} // namespace pqxx::internal::gate
+} // namespace pqxx::internal
+
+
+/// connection_base abstract base class; represents a connection to a database.
+/** This is the first class to look at when you wish to work with a database
+ * through libpqxx. Depending on the implementing concrete child class, a
+ * connection can be automatically opened when it is constructed, or when it is
+ * first used, or somewhere inbetween. The connection is automatically closed
+ * upon destruction (if it hasn't been closed already).
+ *
+ * To query or manipulate the database once connected, use one of the
+ * transaction classes (see pqxx/transaction_base.hxx) or preferably the
+ * transactor framework (see pqxx/transactor.hxx).
+ *
+ * If a network connection to the database server fails, the connection will be
+ * restored automatically (although any transaction going on at the time will
+ * have to be aborted). This also means that any information set in previous
+ * transactions that is not stored in the database, such as temp tables or
+ * connection-local variables defined with PostgreSQL's SET command, will be
+ * lost. Whenever you create such state, either keept it local to one
+ * transaction, where possible, or inhibit automatic reactivation of the
+ * connection using the inhibit_reactivation() method.
+ *
+ * When a connection breaks, you will typically get a broken_connection
+ * exception. This can happen at almost any point, and the details may depend
+ * on which connection class (all derived from this one) you use.
+ *
+ * As a general rule, always avoid raw queries if libpqxx offers a dedicated
+ * function for the same purpose. There may be hidden logic to hide certain
+ * complications from you, such as reinstating session variables when a
+ * broken or disabled connection is reactivated.
+ *
+ * @warning On Unix-like systems, including GNU and BSD systems, your program
+ * may receive the SIGPIPE signal when the connection to the backend breaks. By
+ * default this signal will abort your program. Use "signal(SIGPIPE, SIG_IGN)"
+ * if you want your program to continue running after a connection fails.
+ */
+class PQXX_LIBEXPORT connection_base
+{
+public:
+ /// Explicitly close connection.
+ void disconnect() noexcept; //[t02]
+
+ /// Is this connection open at the moment?
+ /** @warning This function is @b not needed in most code. Resist the
+ * temptation to check it after opening a connection; instead, rely on the
+ * broken_connection exception that will be thrown on connection failure.
+ */
+ bool PQXX_PURE is_open() const noexcept; //[t01]
+
+ /**
+ * @name Activation
+ *
+ * @warning Connection deactivation/reactivation will probably be removed in
+ * libpqxx 7. If your application relies on an ability to "put connections
+ * to sleep" and reactivate them later, you'll need to wrap them in some way
+ * to handle this.
+ *
+ * Connections can be temporarily deactivated, or they can break because of
+ * overly impatient firewalls dropping TCP connections. Where possible,
+ * libpqxx will try to re-activate these when resume using them, or you can
+ * wake them up explicitly. You probably won't need this feature, but you
+ * should be aware of it.
+ */
+ //@{
+ /// @deprecated Explicitly activate deferred or deactivated connection.
+ /** Use of this method is entirely optional. Whenever a connection is used
+ * while in a deferred or deactivated state, it will transparently try to
+ * bring itself into an activated state. This function is best viewed as an
+ * explicit hint to the connection that "if you're not in an active state, now
+ * would be a good time to get into one." Whether a connection is currently
+ * in an active state or not makes no real difference to its functionality.
+ * There is also no particular need to match calls to activate() with calls to
+ * deactivate(). A good time to call activate() might be just before you
+ * first open a transaction on a lazy connection.
+ */
+ PQXX_DEPRECATED void activate(); //[t12]
+
+ /// @deprecated Explicitly deactivate connection.
+ /** Like its counterpart activate(), this method is entirely optional.
+ * Calling this function really only makes sense if you won't be using this
+ * connection for a while and want to reduce the number of open connections on
+ * the database server.
+ * There is no particular need to match or pair calls to deactivate() with
+ * calls to activate(), but calling deactivate() during a transaction is an
+ * error.
+ */
+ PQXX_DEPRECATED void deactivate(); //[t12]
+
+ /// @deprecated Disallow (or permit) connection recovery
+ /** A connection whose underlying socket is not currently connected to the
+ * server will normally (re-)establish communication with the server whenever
+ * needed, or when the client program requests it (although for reasons of
+ * integrity, never inside a transaction; but retrying the whole transaction
+ * may implicitly cause the connection to be restored). In normal use this is
+ * quite a convenient thing to have and presents a simple, safe, predictable
+ * interface.
+ *
+ * There is at least one situation where this feature is not desirable,
+ * however. Although most session state (prepared statements, session
+ * variables) is automatically restored to its working state upon connection
+ * reactivation, temporary tables and so-called WITH HOLD cursors (which can
+ * live outside transactions) are not.
+ *
+ * Cursors that live outside transactions are automatically handled, and the
+ * library will quietly ignore requests to deactivate or reactivate
+ * connections while they exist; it does not want to give you the illusion of
+ * being back in your transaction when in reality you just dropped a cursor.
+ * With temporary tables this is not so easy: there is no easy way for the
+ * library to detect their creation or track their lifetimes.
+ *
+ * So if your program uses temporary tables, and any part of this use happens
+ * outside of any database transaction (or spans multiple transactions), some
+ * of the work you have done on these tables may unexpectedly be undone if the
+ * connection is broken or deactivated while any of these tables exists, and
+ * then reactivated or implicitly restored before you are finished with it.
+ *
+ * If this describes any part of your program, guard it against unexpected
+ * reconnections by inhibiting reconnection at the beginning. And if you want
+ * to continue doing work on the connection afterwards that no longer requires
+ * the temp tables, you can permit it again to get the benefits of connection
+ * reactivation for the remainder of the program.
+ *
+ * @param inhibit should reactivation be inhibited from here on?
+ *
+ * @warning Some connection types (the lazy and asynchronous types) defer
+ * completion of the socket-level connection until it is actually needed by
+ * the client program. Inhibiting reactivation before this connection is
+ * really established will prevent these connection types from doing their
+ * work. For those connection types, if you are sure that reactivation needs
+ * to be inhibited before any query goes across the connection, activate() the
+ * connection first. This will ensure that definite activation happens before
+ * you inhibit it.
+ */
+ PQXX_DEPRECATED void inhibit_reactivation(bool inhibit) //[t86]
+ { m_inhibit_reactivation=inhibit; }
+
+ /// Make the connection fail. @warning Do not use this except for testing!
+ /** Breaks the connection in some unspecified, horrible, dirty way to enable
+ * failure testing.
+ *
+ * Do not use this in normal programs. This is only meant for testing.
+ */
+ void simulate_failure(); //[t94]
+ //@}
+
+ /// Invoke notice processor function. The message should end in newline.
+ void process_notice(const char[]) noexcept; //[t14]
+ /// Invoke notice processor function. Newline at end is recommended.
+ void process_notice(const std::string &) noexcept; //[t14]
+
+ /// Enable tracing to a given output stream, or nullptr to disable.
+ void trace(std::FILE *) noexcept; //[t03]
+
+ /**
+ * @name Connection properties
+ *
+ * These are probably not of great interest, since most are derived from
+ * information supplied by the client program itself, but they are included
+ * for completeness.
+ */
+ //@{
+ /// Name of database we're connected to, if any.
+ /** @warning This activates the connection, which may fail with a
+ * broken_connection exception.
+ */
+ const char *dbname(); //[t01]
+
+ /// Database user ID we're connected under, if any.
+ /** @warning This activates the connection, which may fail with a
+ * broken_connection exception.
+ */
+ const char *username(); //[t01]
+
+ /// Address of server, or nullptr if none specified (i.e. default or local)
+ /** @warning This activates the connection, which may fail with a
+ * broken_connection exception.
+ */
+ const char *hostname(); //[t01]
+
+ /// Server port number we're connected to.
+ /** @warning This activates the connection, which may fail with a
+ * broken_connection exception.
+ */
+ const char *port(); //[t01]
+
+ /// Process ID for backend process.
+ /** Use with care: connections may be lost and automatically re-established
+ * without your knowledge, in which case this process ID may no longer be
+ * correct. You may, however, assume that this number remains constant and
+ * reliable within the span of a successful backend transaction. If the
+ * transaction fails, which may be due to a lost connection, then this number
+ * will have become invalid at some point within the transaction.
+ *
+ * @return Process identifier, or 0 if not currently connected.
+ */
+ int PQXX_PURE backendpid() const noexcept; //[t01]
+
+ /// Socket currently used for connection, or -1 for none. Use with care!
+ /** Query the current socket number. This is intended for event loops based
+ * on functions such as select() or poll(), where multiple file descriptors
+ * are watched.
+ *
+ * Please try to stay away from this function. It is really only meant for
+ * event loops that need to wait on more than one file descriptor. If all you
+ * need is to block until a notification arrives, for instance, use
+ * await_notification(). If you want to issue queries and retrieve results in
+ * nonblocking fashion, check out the pipeline class.
+ *
+ * @warning Don't store this value anywhere, and always be prepared for the
+ * possibility that, at any given time, there may not be a socket! The
+ * socket may change or even go away or be established during any invocation
+ * of libpqxx code on the connection, no matter how trivial.
+ */
+ int PQXX_PURE sock() const noexcept; //[t87]
+
+ /**
+ * @name Capabilities
+ *
+ * Some functionality may only be available in certain versions of the
+ * backend, or only when speaking certain versions of the communications
+ * protocol that connects us to the backend.
+ */
+ //@{
+
+ /// Session capabilities.
+ /** No capabilities are defined at the moment: all capabilities that older
+ * versions checked for are now always supported.
+ */
+ enum capability
+ {
+ /// Not a capability value; end-of-enumeration marker
+ cap_end,
+ };
+
+
+ /// Does this connection seem to support the given capability?
+ /** Don't try to be smart by caching this information anywhere. Obtaining it
+ * is quite fast (especially after the first time) and what's more, a
+ * capability may "suddenly" appear or disappear if the connection is broken
+ * or deactivated, and then restored. This may happen silently any time no
+ * backend transaction is active; if it turns out that the server was upgraded
+ * or restored from an older backup, or the new connection goes to a different
+ * backend, then the restored session may have different capabilities than
+ * were available previously.
+ *
+ * Some guesswork is involved in establishing the presence of any capability;
+ * try not to rely on this function being exactly right.
+ *
+ * @warning Make sure your connection is active before calling this function,
+ * or the answer will always be "no." In particular, if you are using this
+ * function on a newly-created lazyconnection, activate the connection first.
+ */
+ bool supports(capability c) const noexcept //[t88]
+ { return m_caps.test(c); }
+
+ /// What version of the PostgreSQL protocol is this connection using?
+ /** The answer can be 0 (when there is no connection); 3 for protocol 3.0; or
+ * possibly higher values as newer protocol versions are taken into use.
+ *
+ * If the connection is broken and restored, the restored connection could
+ * possibly use a different server and protocol version. This would normally
+ * happen if the server is upgraded without shutting down the client program,
+ * for example.
+ */
+ int PQXX_PURE protocol_version() const noexcept; //[t01]
+
+ /// What version of the PostgreSQL server are we connected to?
+ /** The result is a bit complicated: each of the major, medium, and minor
+ * release numbers is written as a two-digit decimal number, and the three
+ * are then concatenated. Thus server version 9.4.2 will be returned as the
+ * decimal number 90402. If there is no connection to the server, this
+ * returns zero.
+ *
+ * @warning When writing version numbers in your code, don't add zero at the
+ * beginning! Numbers beginning with zero are interpreted as octal (base-8)
+ * in C++. Thus, 070402 is not the same as 70402, and 080000 is not a number
+ * at all because there is no digit "8" in octal notation. Use strictly
+ * decimal notation when it comes to these version numbers.
+ */
+ int PQXX_PURE server_version() const noexcept; //[t01]
+ //@}
+
+ /// @name Text encoding
+ /**
+ * Each connection is governed by a "client encoding," which dictates how
+ * strings and other text is represented in bytes. The database server will
+ * send text data to you in this encoding, and you should use it for the
+ * queries and data which you send to the server.
+ *
+ * Search the PostgreSQL documentation for "character set encodings" to find
+ * out more about the available encodings, how to extend them, and how to use
+ * them. Not all server-side encodings are compatible with all client-side
+ * encodings or vice versa.
+ *
+ * Encoding names are case-insensitive, so e.g. "UTF8" is equivalent to
+ * "utf8".
+ *
+ * You can change the client encoding, but this may not work when the
+ * connection is in a special state, such as when streaming a table. It's
+ * not clear what happens if you change the encoding during a transaction,
+ * and then abort the transaction.
+ */
+ //@{
+ /// Get client-side character encoding, by name.
+ std::string get_client_encoding() const;
+
+ /// Set client-side character encoding, by name.
+ /**
+ * @param Encoding Name of the character set encoding to use.
+ */
+ void set_client_encoding(const std::string &encoding); //[t07]
+
+ /// Set client-side character encoding, by name.
+ /**
+ * @param Encoding Name of the character set encoding to use.
+ */
+ void set_client_encoding(const char encoding[]); //[t07]
+
+ /// Get the connection's encoding, as a PostgreSQL-defined code.
+ int PQXX_PRIVATE encoding_id() const;
+
+ //@}
+
+ /// Set session variable
+ /** Set a session variable for this connection, using the SET command. If the
+ * connection to the database is lost and recovered, the last-set value will
+ * be restored automatically. See the PostgreSQL documentation for a list of
+ * variables that can be set and their permissible values.
+ * If a transaction is currently in progress, aborting that transaction will
+ * normally discard the newly set value. However nontransaction (which
+ * doesn't start a real backend transaction) is an exception.
+ *
+ * @warning Do not mix the set_variable interface with manual setting of
+ * variables by executing the corresponding SQL commands, and do not get or
+ * set variables while a tablestream or pipeline is active on the same
+ * connection.
+ * @param Var Variable to set
+ * @param Value Value vor Var to assume: an identifier, a quoted string, or a
+ * number.
+ */
+ void set_variable( //[t60]
+ const std::string &Var,
+ const std::string &Value);
+
+ /// Read session variable
+ /** Will try to read the value locally, from the list of variables set with
+ * the set_variable function. If that fails, the database is queried.
+ * @warning Do not mix the set_variable interface with manual setting of
+ * variables by executing the corresponding SQL commands, and do not get or
+ * set variables while a tablestream or pipeline is active on the same
+ * connection.
+ */
+ std::string get_variable(const std::string &); //[t60]
+ //@}
+
+
+ /**
+ * @name Notifications and Receivers
+ */
+ //@{
+ /// Check for pending notifications and take appropriate action.
+ /**
+ * All notifications found pending at call time are processed by finding
+ * any matching receivers and invoking those. If no receivers matched the
+ * notification string, none are invoked but the notification is considered
+ * processed.
+ *
+ * Exceptions thrown by client-registered receivers are reported using the
+ * connection's errorhandlers, but the exceptions themselves are not passed
+ * on outside this function.
+ *
+ * @return Number of notifications processed
+ */
+ int get_notifs(); //[t04]
+
+
+ /// Wait for a notification to come in
+ /** The wait may also be terminated by other events, such as the connection
+ * to the backend failing. Any pending or received notifications are
+ * processed as part of the call.
+ *
+ * @return Number of notifications processed
+ */
+ int await_notification(); //[t78]
+
+ /// Wait for a notification to come in, or for given timeout to pass
+ /** The wait may also be terminated by other events, such as the connection
+ * to the backend failing. Any pending or received notifications are
+ * processed as part of the call.
+
+ * @return Number of notifications processed
+ */
+ int await_notification(long seconds, long microseconds); //[t79]
+ //@}
+
+
+ /**
+ * @name Prepared statements
+ *
+ * PostgreSQL supports prepared SQL statements, i.e. statements that can be
+ * registered under a client-provided name, optimized once by the backend, and
+ * executed any number of times under the given name.
+ *
+ * Prepared statement definitions are not sensitive to transaction boundaries;
+ * a statement defined inside a transaction will remain defined outside that
+ * transaction, even if the transaction itself is subsequently aborted. Once
+ * a statement has been prepared, only closing the connection or explicitly
+ * "unpreparing" it can make it go away.
+ *
+ * Use the @c pqxx::transaction_base::exec_prepared functions to execute a
+ * prepared statement. Use @c prepared().exists() to find out whether a
+ * statement has been prepared under a given name. See \ref prepared for a
+ * full discussion.
+ *
+ * Never try to prepare, execute, or unprepare a prepared statement manually
+ * using direct SQL queries. Always use the functions provided by libpqxx.
+ *
+ * @{
+ */
+
+ /// Define a prepared statement.
+ /**
+ * The statement's definition can refer to a parameter using the parameter's
+ * positional number n in the definition. For example, the first parameter
+ * can be used as a variable "$1", the second as "$2" and so on.
+ *
+ * Here's an example of how to use prepared statements. Note the unusual
+ * syntax for passing parameters: every new argument is a parenthesized
+ * expression that is simply tacked onto the end of the statement!
+ *
+ * @code
+ * using namespace pqxx;
+ * void foo(connection_base &C)
+ * {
+ * C.prepare("findtable", "select * from pg_tables where name=$1");
+ * work W{C};
+ * result R = W.exec_prepared("findtable", "mytable");
+ * if (R.empty()) throw runtime_error{"mytable not found!"};
+ * }
+ * @endcode
+ *
+ * To save time, prepared statements aren't really registered with the backend
+ * until they are first used. If this is not what you want, e.g. because you
+ * have very specific realtime requirements, you can use the @c prepare_now()
+ * function to force immediate preparation.
+ *
+ * The statement may not be registered with the backend until it is actually
+ * used. So if, for example, the statement is syntactically incorrect, you
+ * may see a syntax_error here, or later when you try to call the statement,
+ * or during a @c prepare_now() call.
+ *
+ * @param name unique name for the new prepared statement.
+ * @param definition SQL statement to prepare.
+ */
+ void prepare(const std::string &name, const std::string &definition);
+
+ /// Define a nameless prepared statement.
+ /**
+ * This can be useful if you merely want to pass large binary parameters to a
+ * statement without otherwise wishing to prepare it. If you use this
+ * feature, always keep the definition and the use close together to avoid
+ * the nameless statement being redefined unexpectedly by code somewhere else.
+ */
+ void prepare(const std::string &definition);
+
+ /// Drop prepared statement.
+ void unprepare(const std::string &name);
+
+ /// Request that prepared statement be registered with the server.
+ /** If the statement had already been fully prepared, this will do nothing.
+ *
+ * If the connection should break and be transparently restored, then the new
+ * connection will again defer registering the statement with the server.
+ * Since connections are never restored inside backend transactions, doing
+ * this once at the beginning of your transaction ensures that the statement
+ * will not be re-registered during that transaction. In most cases, however,
+ * it's probably better not to use this and let the connection decide when and
+ * whether to register prepared statements that you've defined.
+ */
+ void prepare_now(const std::string &name);
+
+ /**
+ * @}
+ */
+
+ /// @deprecated Pre-C++11 transactor function.
+ /**
+ * This has been superseded by the new transactor framework and
+ * @c pqxx::perform.
+ *
+ * Invokes the given transactor, making at most Attempts attempts to perform
+ * the encapsulated code. If the code throws any exception other than
+ * broken_connection, it will be aborted right away.
+ *
+ * @param T The transactor to be executed.
+ * @param Attempts Maximum number of attempts to be made to execute T.
+ */
+ template<typename TRANSACTOR>
+ PQXX_DEPRECATED void perform(const TRANSACTOR &T, int Attempts); //[t04]
+
+ /// @deprecated Pre-C++11 transactor function. Use @c pqxx::perform instead.
+ /**
+ * This has been superseded by the new transactor framework and
+ * @c pqxx::perform.
+ *
+ * @param T The transactor to be executed.
+ */
+ template<typename TRANSACTOR>
+ PQXX_DEPRECATED void perform(const TRANSACTOR &T)
+ {
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ perform(T, 3);
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+ }
+
+ /// Suffix unique number to name to make it unique within session context
+ /** Used internally to generate identifiers for SQL objects (such as cursors
+ * and nested transactions) based on a given human-readable base name.
+ */
+ std::string adorn_name(const std::string &); //[90]
+
+ /**
+ * @defgroup escaping-functions String-escaping functions
+ */
+ //@{
+ /// Escape string for use as SQL string literal on this connection
+ std::string esc(const char str[]);
+
+ /// Escape string for use as SQL string literal on this connection
+ std::string esc(const char str[], size_t maxlen);
+
+ /// Escape string for use as SQL string literal on this connection
+ std::string esc(const std::string &str);
+
+ /// Escape binary string for use as SQL string literal on this connection
+ std::string esc_raw(const unsigned char str[], size_t len);
+
+ /// Unescape binary data, e.g. from a table field or notification payload.
+ /** Takes a binary string as escaped by PostgreSQL, and returns a restored
+ * copy of the original binary data.
+ */
+ std::string unesc_raw(const std::string &text)
+ { return unesc_raw(text.c_str()); }
+
+ /// Unescape binary data, e.g. from a table field or notification payload.
+ /** Takes a binary string as escaped by PostgreSQL, and returns a restored
+ * copy of the original binary data.
+ */
+ std::string unesc_raw(const char *text);
+
+ /// Escape and quote a string of binary data.
+ std::string quote_raw(const unsigned char str[], size_t len);
+
+ /// Escape and quote an SQL identifier for use in a query.
+ std::string quote_name(const std::string &identifier);
+
+ /// Represent object as SQL string, including quoting & escaping.
+ /** Nulls are recognized and represented as SQL nulls. */
+ template<typename T>
+ std::string quote(const T &t)
+ {
+ if (string_traits<T>::is_null(t)) return "NULL";
+ return "'" + this->esc(to_string(t)) + "'";
+ }
+
+ std::string quote(const binarystring &);
+
+ /// Escape string for literal LIKE match.
+ /** Use this when part of an SQL "LIKE" pattern should match only as a
+ * literal string, not as a pattern, even if it contains "%" or "_"
+ * characters that would normally act as wildcards.
+ *
+ * The string does not get string-escaped or quoted. You do that later.
+ *
+ * For instance, let's say you have a string @c name entered by the user,
+ * and you're searching a @c file column for items that match @c name
+ * followed by a dot and three letters. Even if @c name contains wildcard
+ * characters "%" or "_", you only want those to match literally, so "_"
+ * only matches "_" and "%" only matches a single "%".
+ *
+ * You do that by "like-escaping" @c name, appending the wildcard pattern
+ * @c ".___", and finally, escaping and quoting the result for inclusion in
+ * your query:
+ *
+ * tx.exec(
+ * "SELECT file FROM item WHERE file LIKE " +
+ * tx.quote(tx.esc_like(name) + ".___"));
+ *
+ * The SQL "LIKE" operator also lets you choose your own escape character.
+ * This is supported, but must be a single-byte character.
+ */
+ std::string esc_like(const std::string &str, char escape_char='\\') const;
+ //@}
+
+ /// Attempt to cancel the ongoing query, if any.
+ void cancel_query();
+
+ /// Error verbosity levels.
+ enum error_verbosity
+ {
+ // These values must match those in libpq's PGVerbosity enum.
+ terse=0,
+ normal=1,
+ verbose=2
+ };
+
+ /// Set session verbosity.
+ /** Set the verbosity of error messages to "terse", "normal" (i.e. default) or
+ * "verbose."
+ *
+ * If "terse", returned messages include severity, primary text, and position
+ * only; this will normally fit on a single line. "normal" produces messages
+ * that include the above plus any detail, hint, or context fields (these
+ * might span multiple lines). "verbose" includes all available fields.
+ */
+ void set_verbosity(error_verbosity verbosity) noexcept;
+ /// Retrieve current error verbosity
+ error_verbosity get_verbosity() const noexcept {return m_verbosity;}
+
+ /// Return pointers to the active errorhandlers.
+ /** The entries are ordered from oldest to newest handler.
+ *
+ * You may use this to find errorhandlers that your application wants to
+ * delete when destroying the connection. Be aware, however, that libpqxx
+ * may also add errorhandlers of its own, and those will be included in the
+ * list. If this is a problem for you, derive your errorhandlers from a
+ * custom base class derived from pqxx::errorhandler. Then use dynamic_cast
+ * to find which of the error handlers are yours.
+ *
+ * The pointers point to the real errorhandlers. The container it returns
+ * however is a copy of the one internal to the connection, not a reference.
+ */
+ std::vector<errorhandler *> get_errorhandlers() const;
+
+protected:
+ explicit connection_base(connectionpolicy &pol) :
+ m_policy{pol}
+ {
+ // Check library version. The check_library_version template is declared
+ // for any library version, but only actually defined for the version of
+ // the libpqxx binary against which the code is linked.
+ //
+ // If the library binary is a different version than the one declared in
+ // these headers, then this call will fail to link: there will be no
+ // definition for the function with these exact template parameter values.
+ // There will be a definition, but the version in the parameter values will
+ // be different.
+ //
+ // There is no particular reason to do this here in this constructor, except
+ // to ensure that every meaningful libpqxx client will execute it. The call
+ // must be in the execution path somewhere or the compiler won't try to link
+ // it. We can't use it to initialise a global or class-static variable,
+ // because a smart compiler might resolve it at compile time.
+ //
+ // On the other hand, we don't want to make a useless function call too
+ // often for performance reasons. A local static variable is initialised
+ // only on the definition's first execution. Compilers will be well
+ // optimised for this behaviour, so there's a minimal one-time cost.
+ static const auto version_ok =
+ internal::check_library_version<PQXX_VERSION_MAJOR, PQXX_VERSION_MINOR>();
+ ignore_unused(version_ok);
+
+ clearcaps();
+ }
+ void init();
+
+ void close() noexcept;
+ void wait_read() const;
+ void wait_read(long seconds, long microseconds) const;
+ void wait_write() const;
+
+private:
+
+ result make_result(internal::pq::PGresult *rhs, const std::string &query);
+
+ void clearcaps() noexcept;
+ void PQXX_PRIVATE set_up_state();
+ void PQXX_PRIVATE check_result(const result &);
+
+ void PQXX_PRIVATE internal_set_trace() noexcept;
+ int PQXX_PRIVATE PQXX_PURE status() const noexcept;
+
+ friend class internal::gate::const_connection_largeobject;
+ const char * PQXX_PURE err_msg() const noexcept;
+
+ void PQXX_PRIVATE reset();
+ std::string PQXX_PRIVATE raw_get_var(const std::string &);
+ void PQXX_PRIVATE process_notice_raw(const char msg[]) noexcept;
+
+ void read_capabilities();
+
+ prepare::internal::prepared_def &find_prepared(const std::string &);
+
+ prepare::internal::prepared_def &register_prepared(const std::string &);
+
+ friend class internal::gate::connection_prepare_invocation;
+ /// @deprecated Use exec_prepared instead.
+ PQXX_DEPRECATED result prepared_exec(
+ const std::string &,
+ const char *const[],
+ const int[],
+ const int[],
+ int,
+ result_format format);
+ result exec_prepared(const std::string &statement, const internal::params &, result_format format = result_format::text);
+ bool prepared_exists(const std::string &) const;
+
+ /// Connection handle.
+ internal::pq::PGconn *m_conn = nullptr;
+
+ connectionpolicy &m_policy;
+
+ /// Active transaction on connection, if any.
+ internal::unique<transaction_base> m_trans;
+
+ /// Set libpq notice processor to call connection's error handlers chain.
+ void set_notice_processor();
+ /// Clear libpq notice processor.
+ void clear_notice_processor();
+ std::list<errorhandler *> m_errorhandlers;
+
+ /// File to trace to, if any
+ std::FILE *m_trace = nullptr;
+
+ using receiver_list =
+ std::multimap<std::string, pqxx::notification_receiver *>;
+ /// Notification receivers.
+ receiver_list m_receivers;
+
+ /// Variables set in this session
+ std::map<std::string, std::string> m_vars;
+
+ using PSMap = std::map<std::string, prepare::internal::prepared_def>;
+ /// Prepared statements existing in this section
+ PSMap m_prepared;
+
+ /// Server version
+ int m_serverversion = 0;
+
+ /// Stacking counter: known objects that can't be auto-reactivated
+ internal::reactivation_avoidance_counter m_reactivation_avoidance;
+
+ /// Unique number to use as suffix for identifiers (see adorn_name())
+ int m_unique_id = 0;
+
+ /// Have we successfully established this connection?
+ bool m_completed = false;
+
+ /// Is reactivation currently inhibited?
+ bool m_inhibit_reactivation = false;
+
+ /// Set of session capabilities
+ std::bitset<cap_end> m_caps;
+
+ /// Current verbosity level
+ error_verbosity m_verbosity = normal;
+
+ friend class internal::gate::connection_errorhandler;
+ void PQXX_PRIVATE register_errorhandler(errorhandler *);
+ void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
+
+ friend class internal::gate::connection_transaction;
+ result PQXX_PRIVATE exec(const char[], int Retries);
+ void PQXX_PRIVATE register_transaction(transaction_base *);
+ void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
+ bool PQXX_PRIVATE read_copy_line(std::string &);
+ void PQXX_PRIVATE write_copy_line(const std::string &);
+ void PQXX_PRIVATE end_copy_write();
+ void PQXX_PRIVATE raw_set_var(const std::string &, const std::string &);
+ void PQXX_PRIVATE add_variables(const std::map<std::string, std::string> &);
+
+ friend class internal::gate::connection_largeobject;
+ internal::pq::PGconn *raw_connection() const { return m_conn; }
+
+ friend class internal::gate::connection_notification_receiver;
+ void add_receiver(notification_receiver *);
+ void remove_receiver(notification_receiver *) noexcept;
+
+ friend class internal::gate::connection_pipeline;
+ void PQXX_PRIVATE start_exec(const std::string &);
+ bool PQXX_PRIVATE consume_input() noexcept;
+ bool PQXX_PRIVATE is_busy() const noexcept;
+ internal::pq::PGresult *get_result();
+
+ friend class internal::gate::connection_dbtransaction;
+
+ friend class internal::gate::connection_sql_cursor;
+ void add_reactivation_avoidance_count(int);
+
+ friend class internal::gate::connection_reactivation_avoidance_exemption;
+
+ friend class internal::gate::connection_parameterized_invocation;
+ /// @deprecated Use exec_params instead.
+ PQXX_DEPRECATED result parameterized_exec(
+ const std::string &query,
+ const char *const params[],
+ const int paramlengths[],
+ const int binaries[],
+ int nparams);
+
+ result exec_params(
+ const std::string &query,
+ const internal::params &args);
+
+ connection_base(const connection_base &) =delete;
+ connection_base &operator=(const connection_base &) =delete;
+};
+
+
+namespace internal
+{
+
+/// Scoped exemption to reactivation avoidance
+class PQXX_LIBEXPORT reactivation_avoidance_exemption
+{
+public:
+ explicit reactivation_avoidance_exemption(connection_base &C);
+ ~reactivation_avoidance_exemption();
+
+ void close_connection() noexcept { m_open = false; }
+
+private:
+ connection_base &m_home;
+ int m_count;
+ bool m_open;
+};
+
+
+void wait_read(const internal::pq::PGconn *);
+void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
+void wait_write(const internal::pq::PGconn *);
+} // namespace pqxx::internal
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/connectionpolicy.hxx b/contrib/libs/libpqxx/include/pqxx/connectionpolicy.hxx
new file mode 100644
index 0000000000..3eebf9edbe
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/connectionpolicy.hxx
@@ -0,0 +1,59 @@
+/** Definition of the connection policy classes.
+ *
+ * Interface for defining connection policies
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead.
+ *
+ * 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_CONNECTIONPOLICY
+#define PQXX_H_CONNECTIONPOLICY
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <string>
+
+#include "pqxx/internal/libpq-forward.hxx"
+
+
+namespace pqxx
+{
+
+/**
+ * @addtogroup connection Connection classes
+ */
+//@{
+
+class PQXX_LIBEXPORT connectionpolicy
+{
+public:
+ using handle = internal::pq::PGconn *;
+
+ explicit connectionpolicy(const std::string &opts);
+ virtual ~connectionpolicy() noexcept;
+
+ const std::string &options() const noexcept { return m_options; }
+
+ virtual handle do_startconnect(handle orig);
+ virtual handle do_completeconnect(handle orig);
+ virtual handle do_dropconnect(handle orig) noexcept;
+ virtual handle do_disconnect(handle orig) noexcept;
+ virtual bool is_ready(handle) const noexcept;
+
+protected:
+ handle normalconnect(handle);
+
+private:
+ std::string m_options;
+};
+
+//@}
+} // namespace
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/cursor b/contrib/libs/libpqxx/include/pqxx/cursor
new file mode 100644
index 0000000000..02979afda5
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/cursor
@@ -0,0 +1,6 @@
+/** Definition of the iterator/container-style cursor classes.
+ *
+ * C++-style wrappers for SQL cursors
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/cursor.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/cursor.hxx b/contrib/libs/libpqxx/include/pqxx/cursor.hxx
new file mode 100644
index 0000000000..a1b53ab1cb
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/cursor.hxx
@@ -0,0 +1,437 @@
+/** Definition of the iterator/container-style cursor classes.
+ *
+ * C++-style wrappers for SQL cursors
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/cursor instead.
+ *
+ * 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_CURSOR
+#define PQXX_H_CURSOR
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <limits>
+#include <stdexcept>
+
+#include "pqxx/result.hxx"
+#include "pqxx/transaction_base.hxx"
+
+
+namespace pqxx
+{
+/// Common definitions for cursor types
+/** In C++ terms, fetches are always done in pre-increment or pre-decrement
+ * fashion--i.e. the result does not include the row the cursor is on at the
+ * beginning of the fetch, and the cursor ends up being positioned on the last
+ * row in the result.
+ *
+ * There are singular positions akin to @c end() at both the beginning and the
+ * end of the cursor's range of movement, although these fit in so naturally
+ * with the semantics that one rarely notices them. The cursor begins at the
+ * first of these, but any fetch in the forward direction will move the cursor
+ * off this position and onto the first row before returning anything.
+ */
+class PQXX_LIBEXPORT cursor_base
+{
+public:
+ using size_type = result_size_type;
+ using difference_type = result_difference_type;
+
+ /// Cursor access-pattern policy
+ /** Allowing a cursor to move forward only can result in better performance,
+ * so use this access policy whenever possible.
+ */
+ enum accesspolicy
+ {
+ /// Cursor can move forward only
+ forward_only,
+ /// Cursor can move back and forth
+ random_access
+ };
+
+ /// Cursor update policy
+ /**
+ * @warning Not all PostgreSQL versions support updatable cursors.
+ */
+ enum updatepolicy
+ {
+ /// Cursor can be used to read data but not to write
+ read_only,
+ /// Cursor can be used to update data as well as read it
+ update
+ };
+
+ /// Cursor destruction policy
+ /** The normal thing to do is to make a cursor object the owner of the SQL
+ * cursor it represents. There may be cases, however, where a cursor needs to
+ * persist beyond the end of the current transaction (and thus also beyond the
+ * lifetime of the cursor object that created it!), where it can be "adopted"
+ * into a new cursor object. See the basic_cursor documentation for an
+ * explanation of cursor adoption.
+ *
+ * If a cursor is created with "loose" ownership policy, the object
+ * representing the underlying SQL cursor will not take the latter with it
+ * when its own lifetime ends, nor will its originating transaction.
+ *
+ * @warning Use this feature with care and moderation. Only one cursor object
+ * should be responsible for any one underlying SQL cursor at any given time.
+ *
+ * @warning Don't "leak" cursors! As long as any "loose" cursor exists,
+ * any attempts to deactivate or reactivate the connection, implicitly or
+ * explicitly, are quietly ignored.
+ */
+ enum ownershippolicy
+ {
+ /// Destroy SQL cursor when cursor object is closed at end of transaction
+ owned,
+ /// Leave SQL cursor in existence after close of object and transaction
+ loose
+ };
+
+ cursor_base() =delete;
+ cursor_base(const cursor_base &) =delete;
+ cursor_base &operator=(const cursor_base &) =delete;
+
+ /**
+ * @name Special movement distances.
+ */
+ //@{
+
+ /// Special value: read until end.
+ /** @return Maximum value for result::difference_type, so the cursor will
+ * attempt to read the largest possible result set.
+ */
+ static difference_type all() noexcept; //[t81]
+
+ /// Special value: read one row only.
+ /** @return Unsurprisingly, 1.
+ */
+ static difference_type next() noexcept { return 1; } //[t81]
+
+ /// Special value: read backwards, one row only.
+ /** @return Unsurprisingly, -1.
+ */
+ static difference_type prior() noexcept { return -1; } //[t00]
+
+ /// Special value: read backwards from current position back to origin.
+ /** @return Minimum value for result::difference_type.
+ */
+ static difference_type backward_all() noexcept; //[t00]
+
+ //@}
+
+ /// Name of underlying SQL cursor
+ /**
+ * @returns Name of SQL cursor, which may differ from original given name.
+ * @warning Don't use this to access the SQL cursor directly without going
+ * through the provided wrapper classes!
+ */
+ const std::string &name() const noexcept { return m_name; } //[t81]
+
+protected:
+ cursor_base(
+ connection_base &,
+ const std::string &Name,
+ bool embellish_name=true);
+
+ const std::string m_name;
+};
+} // namespace pqxx
+
+
+#include <pqxx/internal/sql_cursor.hxx>
+
+
+namespace pqxx
+{
+/// "Stateless cursor" class: easy API for retrieving parts of result sets
+/** This is a front-end for SQL cursors, but with a more C++-like API.
+ *
+ * Actually, stateless_cursor feels entirely different from SQL cursors. You
+ * don't keep track of positions, fetches, and moves; you just say which rows
+ * you want. See the retrieve() member function.
+ */
+template<cursor_base::updatepolicy up, cursor_base::ownershippolicy op>
+class stateless_cursor
+{
+public:
+ using size_type = result_size_type;
+ using difference_type = result_difference_type;
+
+ /// Create cursor.
+ stateless_cursor(
+ transaction_base &trans,
+ const std::string &query,
+ const std::string &cname,
+ bool hold) :
+ m_cur{trans, query, cname, cursor_base::random_access, up, op, hold}
+ {
+ }
+
+ /// Adopt existing scrolling SQL cursor.
+ stateless_cursor(
+ transaction_base &trans,
+ const std::string adopted_cursor) :
+ m_cur{trans, adopted_cursor, op}
+ {
+ // Put cursor in known position
+ m_cur.move(cursor_base::backward_all());
+ }
+
+ void close() noexcept { m_cur.close(); }
+
+ /// Number of rows in cursor's result set
+ /** @note This function is not const; it may need to scroll to find the size
+ * of the result set.
+ */
+ size_type size() { return internal::obtain_stateless_cursor_size(m_cur); }
+
+ /// Retrieve rows from begin_pos (inclusive) to end_pos (exclusive)
+ /** Rows are numbered starting from 0 to size()-1.
+ *
+ * @param begin_pos First row to retrieve. May be one row beyond the end of
+ * the result set, to avoid errors for empty result sets. Otherwise, must be
+ * a valid row number in the result set.
+ * @param end_pos Row up to which to fetch. Rows are returned ordered from
+ * begin_pos to end_pos, i.e. in ascending order if begin_pos < end_pos but
+ * in descending order if begin_pos > end_pos. The end_pos may be arbitrarily
+ * inside or outside the result set; only existing rows are included in the
+ * result.
+ */
+ result retrieve(difference_type begin_pos, difference_type end_pos)
+ {
+ return internal::stateless_cursor_retrieve(
+ m_cur,
+ result::difference_type(size()),
+ begin_pos,
+ end_pos);
+ }
+
+ const std::string &name() const noexcept { return m_cur.name(); }
+
+private:
+ internal::sql_cursor m_cur;
+};
+
+
+class icursor_iterator;
+
+
+namespace internal
+{
+namespace gate
+{
+class icursor_iterator_icursorstream;
+class icursorstream_icursor_iterator;
+} // namespace internal::gate
+} // namespace internal
+
+
+/// Simple read-only cursor represented as a stream of results
+/** SQL cursors can be tricky, especially in C++ since the two languages seem to
+ * have been designed on different planets. An SQL cursor has two singular
+ * positions akin to @c end() on either side of the underlying result set.
+ *
+ * These cultural differences are hidden from view somewhat by libpqxx, which
+ * tries to make SQL cursors behave more like familiar C++ entities such as
+ * iterators, sequences, streams, and containers.
+ *
+ * Data is fetched from the cursor as a sequence of result objects. Each of
+ * these will contain the number of rows defined as the stream's stride, except
+ * of course the last block of data which may contain fewer rows.
+ *
+ * This class can create or adopt cursors that live outside any backend
+ * transaction, which your backend version may not support.
+ */
+class PQXX_LIBEXPORT icursorstream
+{
+public:
+ using size_type = cursor_base::size_type;
+ using difference_type = cursor_base::difference_type;
+
+ /// Set up a read-only, forward-only cursor
+ /** Roughly equivalent to a C++ Standard Library istream, this cursor type
+ * supports only two operations: reading a block of rows while moving forward,
+ * and moving forward without reading any data.
+ *
+ * @param context Transaction context that this cursor will be active in
+ * @param query SQL query whose results this cursor shall iterate
+ * @param basename Suggested name for the SQL cursor; a unique code will be
+ * appended by the library to ensure its uniqueness
+ * @param sstride Number of rows to fetch per read operation; must be a
+ * positive number
+ */
+ icursorstream(
+ transaction_base &context,
+ const std::string &query,
+ const std::string &basename,
+ difference_type sstride=1); //[t81]
+
+ /// Adopt existing SQL cursor. Use with care.
+ /** Forms a cursor stream around an existing SQL cursor, as returned by e.g. a
+ * server-side function. The SQL cursor will be cleaned up by the stream's
+ * destructor as if it had been created by the stream; cleaning it up by hand
+ * or adopting the same cursor twice is an error.
+ *
+ * Passing the name of the cursor as a string is not allowed, both to avoid
+ * confusion with the other constructor and to discourage unnecessary use of
+ * adopted cursors.
+ *
+ * @warning It is technically possible to adopt a "WITH HOLD" cursor, i.e. a
+ * cursor that stays alive outside its creating transaction. However, any
+ * cursor stream (including the underlying SQL cursor, naturally) must be
+ * destroyed before its transaction context object is destroyed. Therefore
+ * the only way to use SQL's WITH HOLD feature is to adopt the cursor, but
+ * defer doing so until after entering the transaction context that will
+ * eventually destroy it.
+ *
+ * @param context Transaction context that this cursor will be active in.
+ * @param cname Result field containing the name of the SQL cursor to adopt.
+ * @param sstride Number of rows to fetch per read operation; must be a
+ * positive number.
+ * @param op Ownership policy. Determines whether the cursor underlying this
+ * stream will be destroyed when the stream is closed.
+ */
+ icursorstream(
+ transaction_base &context,
+ const field &cname,
+ difference_type sstride=1,
+ cursor_base::ownershippolicy op=cursor_base::owned); //[t84]
+
+ operator bool() const noexcept { return not m_done; }
+
+ /// Read new value into given result object; same as operator >>
+ /** The result set may continue any number of rows from zero to the chosen
+ * stride, inclusive. An empty result will only be returned if there are no
+ * more rows to retrieve.
+ * @return Reference to this very stream, to facilitate "chained" invocations
+ * ("C.get(r1).get(r2);")
+ */
+ icursorstream &get(result &res) { res = fetchblock(); return *this; } //[t81]
+ /// Read new value into given result object; same as get(result &)
+ /** The result set may continue any number of rows from zero to the chosen
+ * stride, inclusive. An empty result will only be returned if there are no
+ * more rows to retrieve.
+ * @return Reference to this very stream, to facilitate "chained" invocations
+ * ("C >> r1 >> r2;")
+ */
+ icursorstream &operator>>(result &res) { return get(res); } //[t81]
+
+ /// Move given number of rows forward (ignoring stride) without reading data
+ /**
+ * @return Reference to this very stream, to facilitate "chained" invocations
+ * ("C.ignore(2).get(r).ignore(4);")
+ */
+ icursorstream &ignore(std::streamsize n=1); //[t81]
+
+ /// Change stride, i.e. the number of rows to fetch per read operation
+ /**
+ * @param stride Must be a positive number
+ */
+ void set_stride(difference_type stride); //[t81]
+ difference_type stride() const noexcept { return m_stride; } //[t81]
+
+private:
+ result fetchblock();
+
+ friend class internal::gate::icursorstream_icursor_iterator;
+ size_type forward(size_type n=1);
+ void insert_iterator(icursor_iterator *) noexcept;
+ void remove_iterator(icursor_iterator *) const noexcept;
+
+ void service_iterators(difference_type);
+
+ internal::sql_cursor m_cur;
+
+ difference_type m_stride;
+ difference_type m_realpos, m_reqpos;
+
+ mutable icursor_iterator *m_iterators;
+
+ bool m_done;
+};
+
+
+/// Approximate istream_iterator for icursorstream
+/** Intended as an implementation of an input_iterator (as defined by the C++
+ * Standard Library), this class supports only two basic operations: reading the
+ * current element, and moving forward. In addition to the minimal guarantees
+ * for istream_iterators, this class supports multiple successive reads of the
+ * same position (the current result set is cached in the iterator) even after
+ * copying and even after new data have been read from the stream. This appears
+ * to be a requirement for input_iterators. Comparisons are also supported in
+ * the general case.
+ *
+ * The iterator does not care about its own position, however. Moving an
+ * iterator forward moves the underlying stream forward and reads the data from
+ * the new stream position, regardless of the iterator's old position in the
+ * stream.
+ *
+ * The stream's stride defines the granularity for all iterator movement or
+ * access operations, i.e. "ici += 1" advances the stream by one stride's worth
+ * of rows, and "*ici++" reads one stride's worth of rows from the stream.
+ *
+ * @warning Do not read from the underlying stream or its cursor, move its read
+ * position, or change its stride, between the time the first icursor_iterator
+ * on it is created and the time its last icursor_iterator is destroyed.
+ *
+ * @warning Manipulating these iterators within the context of a single cursor
+ * stream is <em>not thread-safe</em>. Creating a new iterator, copying one, or
+ * destroying one affects the stream as a whole.
+ */
+class PQXX_LIBEXPORT icursor_iterator
+{
+public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = result;
+ using pointer = const result *;
+ using reference = const result &;
+ using istream_type = icursorstream;
+ using size_type = istream_type::size_type;
+ using difference_type = istream_type::difference_type;
+
+ icursor_iterator() noexcept; //[t84]
+ explicit icursor_iterator(istream_type &) noexcept; //[t84]
+ icursor_iterator(const icursor_iterator &) noexcept; //[t84]
+ ~icursor_iterator() noexcept;
+
+ const result &operator*() const { refresh(); return m_here; } //[t84]
+ const result *operator->() const { refresh(); return &m_here; } //[t84]
+ icursor_iterator &operator++(); //[t84]
+ icursor_iterator operator++(int); //[t84]
+ icursor_iterator &operator+=(difference_type); //[t84]
+ icursor_iterator &operator=(const icursor_iterator &) noexcept; //[t84]
+
+ bool operator==(const icursor_iterator &rhs) const; //[t84]
+ bool operator!=(const icursor_iterator &rhs) const noexcept //[t84]
+ { return not operator==(rhs); }
+ bool operator<(const icursor_iterator &rhs) const; //[t84]
+ bool operator>(const icursor_iterator &rhs) const //[t84]
+ { return rhs < *this; }
+ bool operator<=(const icursor_iterator &rhs) const //[t84]
+ { return not (*this > rhs); }
+ bool operator>=(const icursor_iterator &rhs) const //[t84]
+ { return not (*this < rhs); }
+
+private:
+ void refresh() const;
+
+ friend class internal::gate::icursor_iterator_icursorstream;
+ difference_type pos() const noexcept { return m_pos; }
+ void fill(const result &);
+
+ icursorstream *m_stream = nullptr;
+ result m_here;
+ difference_type m_pos;
+ icursor_iterator *m_prev = nullptr, *m_next = nullptr;
+};
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/dbtransaction b/contrib/libs/libpqxx/include/pqxx/dbtransaction
new file mode 100644
index 0000000000..d3d6092ca9
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/dbtransaction
@@ -0,0 +1,6 @@
+/** pqxx::dbtransaction abstract base class.
+ *
+ * pqxx::dbransaction defines a real transaction on the database.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/dbtransaction.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/dbtransaction.hxx b/contrib/libs/libpqxx/include/pqxx/dbtransaction.hxx
new file mode 100644
index 0000000000..8ba7d70c6f
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/dbtransaction.hxx
@@ -0,0 +1,109 @@
+/** Definition of the pqxx::dbtransaction abstract base class.
+ *
+ * pqxx::dbransaction defines a real transaction on the database.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/dbtransaction instead.
+ *
+ * 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_DBTRANSACTION
+#define PQXX_H_DBTRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/transaction_base.hxx"
+
+namespace pqxx
+{
+
+enum readwrite_policy
+{
+ read_only,
+ read_write
+};
+
+
+/// Abstract base class responsible for bracketing a backend transaction.
+/**
+ * @ingroup transaction
+ *
+ * Use a dbtransaction-derived object such as "work" (transaction<>) to enclose
+ * operations on a database in a single "unit of work." This ensures that the
+ * whole series of operations either succeeds as a whole or fails completely.
+ * In no case will it leave half-finished work behind in the database.
+ *
+ * Once processing on a transaction has succeeded and any changes should be
+ * allowed to become permanent in the database, call commit(). If something
+ * has gone wrong and the changes should be forgotten, call abort() instead.
+ * If you do neither, an implicit abort() is executed at destruction time.
+ *
+ * It is an error to abort a transaction that has already been committed, or to
+ * commit a transaction that has already been aborted. Aborting an already
+ * aborted transaction or committing an already committed one has been allowed
+ * to make errors easier to deal with. Repeated aborts or commits have no
+ * effect after the first one.
+ *
+ * Database transactions are not suitable for guarding long-running processes.
+ * If your transaction code becomes too long or too complex, please consider
+ * ways to break it up into smaller ones. There's no easy, general way to do
+ * this since application-specific considerations become important at this
+ * point.
+ *
+ * The actual operations for beginning and committing/aborting the backend
+ * transaction are implemented by a derived class. The implementing concrete
+ * class must also call Begin() and End() from its constructors and destructors,
+ * respectively, and implement do_exec().
+ */
+class PQXX_LIBEXPORT PQXX_NOVTABLE dbtransaction : public transaction_base
+{
+public:
+ virtual ~dbtransaction();
+
+protected:
+ dbtransaction(
+ connection_base &,
+ const std::string &IsolationString,
+ readwrite_policy rw=read_write);
+
+ explicit dbtransaction(
+ connection_base &,
+ bool direct=true,
+ readwrite_policy rw=read_write);
+
+
+ /// Start a transaction on the backend and set desired isolation level
+ void start_backend_transaction();
+
+ /// Sensible default implemented here: begin backend transaction
+ virtual void do_begin() override; //[t01]
+ /// Sensible default implemented here: perform query
+ virtual result do_exec(const char Query[]) override;
+ /// To be implemented by derived class: commit backend transaction
+ virtual void do_commit() override =0;
+ /// Sensible default implemented here: abort backend transaction
+ /** Default implementation does two things:
+ * <ol>
+ * <li>Clears the "connection reactivation avoidance counter"</li>
+ * <li>Executes a ROLLBACK statement</li>
+ * </ol>
+ */
+ virtual void do_abort() override; //[t13]
+
+ static std::string fullname(const std::string &ttype,
+ const std::string &isolation);
+
+private:
+ /// Precomputed SQL command to run at start of this transaction
+ std::string m_start_cmd;
+};
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/errorhandler b/contrib/libs/libpqxx/include/pqxx/errorhandler
new file mode 100644
index 0000000000..fda3c0ae62
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/errorhandler
@@ -0,0 +1,6 @@
+/** pqxx::errorhandler class.
+ *
+ * Callbacks for handling errors and warnings.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/errorhandler.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/errorhandler.hxx b/contrib/libs/libpqxx/include/pqxx/errorhandler.hxx
new file mode 100644
index 0000000000..03ce923a3b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/errorhandler.hxx
@@ -0,0 +1,96 @@
+/** Definition of the pqxx::errorhandler class.
+ *
+ * pqxx::errorhandler handlers errors and warnings in a database session.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection_base instead.
+ *
+ * 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_ERRORHANDLER
+#define PQXX_H_ERRORHANDLER
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/types.hxx"
+
+
+namespace pqxx
+{
+namespace internal
+{
+namespace gate
+{
+class errorhandler_connection_base;
+}
+}
+
+/**
+ * @addtogroup errorhandler
+ * @{
+ */
+
+/// Base class for error-handler callbacks.
+/** To receive errors and warnings from a connection, subclass this with your
+ * own error-handler functor, and instantiate it for the connection. Destroying
+ * the handler un-registers it.
+ *
+ * A connection can have multiple error handlers at the same time. When the
+ * database connection emits an error or warning message, it passes the message
+ * to each error handler, starting with the most recently registered one and
+ * progressing towards the oldest one. However an error handler may also
+ * instruct the connection not to pass the message to further handlers by
+ * returning "false."
+ *
+ * @warning Strange things happen when a result object outlives its parent
+ * connection. If you register an error handler on a connection, then you must
+ * not access the result after destroying the connection. This applies even if
+ * you destroy the error handler first!
+ */
+class PQXX_LIBEXPORT errorhandler
+{
+public:
+ explicit errorhandler(connection_base &);
+ virtual ~errorhandler();
+
+ /// Define in subclass: receive an error or warning message from the database.
+ /**
+ * @return Whether the same error message should also be passed to the
+ * remaining, older errorhandlers.
+ */
+ virtual bool operator()(const char msg[]) noexcept =0;
+
+private:
+ connection_base *m_home;
+
+ friend class internal::gate::errorhandler_connection_base;
+ void unregister() noexcept;
+
+ errorhandler() =delete;
+ errorhandler(const errorhandler &) =delete;
+ errorhandler &operator=(const errorhandler &) =delete;
+};
+
+
+/// An error handler that suppresses any previously registered error handlers.
+class quiet_errorhandler : public errorhandler
+{
+public:
+ quiet_errorhandler(connection_base &conn) : errorhandler{conn} {}
+
+ virtual bool operator()(const char[]) noexcept override { return false; }
+};
+
+/**
+ * @}
+ */
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/except b/contrib/libs/libpqxx/include/pqxx/except
new file mode 100644
index 0000000000..e3cf0b0d5c
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/except
@@ -0,0 +1,6 @@
+/** libpqxx exception classes.
+ *
+ * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ...
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/except.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/except.hxx b/contrib/libs/libpqxx/include/pqxx/except.hxx
new file mode 100644
index 0000000000..24d52d13e3
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/except.hxx
@@ -0,0 +1,532 @@
+/** Definition of libpqxx exception classes.
+ *
+ * pqxx::sql_error, pqxx::broken_connection, pqxx::in_doubt_error, ...
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/except instead.
+ *
+ * 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_EXCEPT
+#define PQXX_H_EXCEPT
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <stdexcept>
+
+#include "pqxx/util.hxx"
+
+
+namespace pqxx
+{
+
+/**
+ * @addtogroup exception Exception classes
+ *
+ * These exception classes follow, roughly, the two-level hierarchy defined by
+ * the PostgreSQL error codes (see Appendix A of the PostgreSQL documentation
+ * corresponding to your server version). The hierarchy given here is, as yet,
+ * not a complete mirror of the error codes. There are some other differences
+ * as well, e.g. the error code statement_completion_unknown has a separate
+ * status in libpqxx as in_doubt_error, and too_many_connections is classified
+ * as a broken_connection rather than a subtype of insufficient_resources.
+ *
+ * @see http://www.postgresql.org/docs/9.4/interactive/errcodes-appendix.html
+ *
+ * @{
+ */
+
+/// Mixin base class to identify libpqxx-specific exception types
+/**
+ * If you wish to catch all exception types specific to libpqxx for some reason,
+ * catch this type. All of libpqxx's exception classes are derived from it
+ * through multiple-inheritance (they also fit into the standard library's
+ * exception hierarchy in more fitting places).
+ *
+ * This class is not derived from std::exception, since that could easily lead
+ * to exception classes with multiple std::exception base-class objects. As
+ * Bart Samwel points out, "catch" is subject to some nasty fineprint in such
+ * cases.
+ */
+class PQXX_LIBEXPORT PQXX_NOVTABLE pqxx_exception
+{
+public:
+ /// Support run-time polymorphism, and keep this class abstract
+ virtual ~pqxx_exception() noexcept =0;
+
+ /// Return std::exception base-class object
+ /** Use this to get at the exception's what() function, or to downcast to a
+ * more specific type using dynamic_cast.
+ *
+ * Casting directly from pqxx_exception to a specific exception type is not
+ * likely to work since pqxx_exception is not (and could not safely be)
+ * derived from std::exception.
+ *
+ * For example, to test dynamically whether an exception is an sql_error:
+ *
+ * @code
+ * try
+ * {
+ * // ...
+ * }
+ * catch (const pqxx::pqxx_exception &e)
+ * {
+ * std::cerr << e.base().what() << std::endl;
+ * const pqxx::sql_error *s=dynamic_cast<const pqxx::sql_error*>(&e.base());
+ * if (s) std::cerr << "Query was: " << s->query() << std::endl;
+ * }
+ * @endcode
+ */
+ PQXX_CONST virtual const std::exception &base() const noexcept =0; //[t00]
+};
+
+
+/// Run-time failure encountered by libpqxx, similar to std::runtime_error
+class PQXX_LIBEXPORT failure :
+ public pqxx_exception, public std::runtime_error
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit failure(const std::string &);
+};
+
+
+/// Exception class for lost or failed backend connection.
+/**
+ * @warning When this happens on Unix-like systems, you may also get a SIGPIPE
+ * signal. That signal aborts the program by default, so if you wish to be able
+ * to continue after a connection breaks, be sure to disarm this signal.
+ *
+ * If you're working on a Unix-like system, see the manual page for
+ * @c signal (2) on how to deal with SIGPIPE. The easiest way to make this
+ * signal harmless is to make your program ignore it:
+ *
+ * @code
+ * #include <signal.h>
+ *
+ * int main()
+ * {
+ * signal(SIGPIPE, SIG_IGN);
+ * // ...
+ * @endcode
+ */
+class PQXX_LIBEXPORT broken_connection : public failure
+{
+public:
+ broken_connection();
+ explicit broken_connection(const std::string &);
+};
+
+
+/// Exception class for failed queries.
+/** Carries, in addition to a regular error message, a copy of the failed query
+ * and (if available) the SQLSTATE value accompanying the error.
+ */
+class PQXX_LIBEXPORT sql_error : public failure
+{
+ /// Query string. Empty if unknown.
+ const std::string m_query;
+ /// SQLSTATE string describing the error type, if known; or empty string.
+ const std::string m_sqlstate;
+
+public:
+ explicit sql_error(
+ const std::string &msg="",
+ const std::string &Q="",
+ const char sqlstate[]=nullptr);
+ virtual ~sql_error() noexcept;
+
+ /// The query whose execution triggered the exception
+ PQXX_PURE const std::string &query() const noexcept; //[t56]
+
+ /// SQLSTATE error code if known, or empty string otherwise.
+ PQXX_PURE const std::string &sqlstate() const noexcept;
+};
+
+
+/// "Help, I don't know whether transaction was committed successfully!"
+/** Exception that might be thrown in rare cases where the connection to the
+ * database is lost while finishing a database transaction, and there's no way
+ * of telling whether it was actually executed by the backend. In this case
+ * the database is left in an indeterminate (but consistent) state, and only
+ * manual inspection will tell which is the case.
+ */
+class PQXX_LIBEXPORT in_doubt_error : public failure
+{
+public:
+ explicit in_doubt_error(const std::string &);
+};
+
+
+/// The backend saw itself forced to roll back the ongoing transaction.
+class PQXX_LIBEXPORT transaction_rollback : public failure
+{
+public:
+ explicit transaction_rollback(const std::string &);
+};
+
+
+/// Transaction failed to serialize. Please retry it.
+/** Can only happen at transaction isolation levels REPEATABLE READ and
+ * SERIALIZABLE.
+ *
+ * The current transaction cannot be committed without violating the guarantees
+ * made by its isolation level. This is the effect of a conflict with another
+ * ongoing transaction. The transaction may still succeed if you try to
+ * perform it again.
+ */
+class PQXX_LIBEXPORT serialization_failure : public transaction_rollback
+{
+public:
+ explicit serialization_failure(const std::string &);
+};
+
+
+/// We can't tell whether our last statement succeeded.
+class PQXX_LIBEXPORT statement_completion_unknown : public transaction_rollback
+{
+public:
+ explicit statement_completion_unknown(const std::string &);
+};
+
+
+/// The ongoing transaction has deadlocked. Retrying it may help.
+class PQXX_LIBEXPORT deadlock_detected : public transaction_rollback
+{
+public:
+ explicit deadlock_detected(const std::string &);
+};
+
+
+/// Internal error in libpqxx library
+class PQXX_LIBEXPORT internal_error :
+ public pqxx_exception, public std::logic_error
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit internal_error(const std::string &);
+};
+
+
+/// Error in usage of libpqxx library, similar to std::logic_error
+class PQXX_LIBEXPORT usage_error :
+ public pqxx_exception, public std::logic_error
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit usage_error(const std::string &);
+};
+
+
+/// Invalid argument passed to libpqxx, similar to std::invalid_argument
+class PQXX_LIBEXPORT argument_error :
+ public pqxx_exception, public std::invalid_argument
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit argument_error(const std::string &);
+};
+
+
+/// Value conversion failed, e.g. when converting "Hello" to int.
+class PQXX_LIBEXPORT conversion_error :
+ public pqxx_exception, public std::domain_error
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit conversion_error(const std::string &);
+};
+
+
+/// Something is out of range, similar to std::out_of_range
+class PQXX_LIBEXPORT range_error :
+ public pqxx_exception, public std::out_of_range
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit range_error(const std::string &);
+};
+
+
+/// Query returned an unexpected number of rows.
+class PQXX_LIBEXPORT unexpected_rows : public range_error
+{
+ virtual const std::exception &base() const noexcept override
+ { return *this; }
+public:
+ explicit unexpected_rows(const std::string &msg) : range_error{msg} {}
+};
+
+
+/// Database feature not supported in current setup
+class PQXX_LIBEXPORT feature_not_supported : public sql_error
+{
+public:
+ explicit feature_not_supported(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+/// Error in data provided to SQL statement
+class PQXX_LIBEXPORT data_exception : public sql_error
+{
+public:
+ explicit data_exception(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT integrity_constraint_violation : public sql_error
+{
+public:
+ explicit integrity_constraint_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT restrict_violation :
+ public integrity_constraint_violation
+{
+public:
+ explicit restrict_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ integrity_constraint_violation{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT not_null_violation :
+ public integrity_constraint_violation
+{
+public:
+ explicit not_null_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ integrity_constraint_violation{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT foreign_key_violation :
+ public integrity_constraint_violation
+{
+public:
+ explicit foreign_key_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ integrity_constraint_violation{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT unique_violation :
+ public integrity_constraint_violation
+{
+public:
+ explicit unique_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ integrity_constraint_violation{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT check_violation :
+ public integrity_constraint_violation
+{
+public:
+ explicit check_violation(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ integrity_constraint_violation{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT invalid_cursor_state : public sql_error
+{
+public:
+ explicit invalid_cursor_state(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT invalid_sql_statement_name : public sql_error
+{
+public:
+ explicit invalid_sql_statement_name(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT invalid_cursor_name : public sql_error
+{
+public:
+ explicit invalid_cursor_name(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT syntax_error : public sql_error
+{
+public:
+ /// Approximate position in string where error occurred, or -1 if unknown.
+ const int error_position;
+
+ explicit syntax_error(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr,
+ int pos=-1) :
+ sql_error{err, Q, sqlstate}, error_position{pos} {}
+};
+
+class PQXX_LIBEXPORT undefined_column : public syntax_error
+{
+public:
+ explicit undefined_column(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ syntax_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT undefined_function : public syntax_error
+{
+public:
+ explicit undefined_function(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ syntax_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT undefined_table : public syntax_error
+{
+public:
+ explicit undefined_table(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ syntax_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT insufficient_privilege : public sql_error
+{
+public:
+ explicit insufficient_privilege(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+/// Resource shortage on the server
+class PQXX_LIBEXPORT insufficient_resources : public sql_error
+{
+public:
+ explicit insufficient_resources(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err,Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT disk_full : public insufficient_resources
+{
+public:
+ explicit disk_full(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ insufficient_resources{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT out_of_memory : public insufficient_resources
+{
+public:
+ explicit out_of_memory(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ insufficient_resources{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT too_many_connections : public broken_connection
+{
+public:
+ explicit too_many_connections(const std::string &err) :
+ broken_connection{err} {}
+};
+
+/// PL/pgSQL error
+/** Exceptions derived from this class are errors from PL/pgSQL procedures.
+ */
+class PQXX_LIBEXPORT plpgsql_error : public sql_error
+{
+public:
+ explicit plpgsql_error(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ sql_error{err, Q, sqlstate} {}
+};
+
+/// Exception raised in PL/pgSQL procedure
+class PQXX_LIBEXPORT plpgsql_raise : public plpgsql_error
+{
+public:
+ explicit plpgsql_raise(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ plpgsql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT plpgsql_no_data_found : public plpgsql_error
+{
+public:
+ explicit plpgsql_no_data_found(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ plpgsql_error{err, Q, sqlstate} {}
+};
+
+class PQXX_LIBEXPORT plpgsql_too_many_rows : public plpgsql_error
+{
+public:
+ explicit plpgsql_too_many_rows(
+ const std::string &err,
+ const std::string &Q="",
+ const char sqlstate[]=nullptr) :
+ plpgsql_error{err, Q, sqlstate} {}
+};
+
+/**
+ * @}
+ */
+
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/field b/contrib/libs/libpqxx/include/pqxx/field
new file mode 100644
index 0000000000..e799e6797b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/field
@@ -0,0 +1,6 @@
+/** pqxx::field class.
+ *
+ * pqxx::field refers to a field in a query result.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/field.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/field.hxx b/contrib/libs/libpqxx/include/pqxx/field.hxx
new file mode 100644
index 0000000000..5676d2a848
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/field.hxx
@@ -0,0 +1,373 @@
+/** Definitions for the pqxx::field class.
+ *
+ * pqxx::field refers to a field in a query result.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead.
+ *
+ * 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_FIELD
+#define PQXX_H_FIELD
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/internal/type_utils.hxx"
+
+#if defined(PQXX_HAVE_OPTIONAL)
+#include <optional>
+
+/* Use std::experimental::optional as a fallback for std::optional, if
+ * present.
+ *
+ * This may break compilation for some software, if using a libpqxx that was
+ * configured for a different language version. To stop libpqxx headers from
+ * using or supporting std::experimental::optional, define a macro
+ * PQXX_HIDE_EXP_OPTIONAL when building your software.
+ */
+#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
+#error #include <experimental/optional>
+#endif
+
+#include "pqxx/array.hxx"
+#include "pqxx/result.hxx"
+#include "pqxx/strconv.hxx"
+#include "pqxx/types.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+/// Reference to a field in a result set.
+/** A field represents one entry in a row. It represents an actual value
+ * in the result set, and can be converted to various types.
+ */
+class PQXX_LIBEXPORT field
+{
+public:
+ using size_type = field_size_type;
+
+ /// Constructor.
+ /** Create field as reference to a field in a result set.
+ * @param R Row that this field is part of.
+ * @param C Column number of this field.
+ */
+ field(const row &R, row_size_type C) noexcept; //[t01]
+
+ /**
+ * @name Comparison
+ */
+ //@{
+ /// Byte-by-byte comparison of two fields (all nulls are considered equal)
+ /** @warning null handling is still open to discussion and change!
+ *
+ * Handling of null values differs from that in SQL where a comparison
+ * involving a null value yields null, so nulls are never considered equal
+ * to one another or even to themselves.
+ *
+ * Null handling also probably differs from the closest equivalent in C++,
+ * which is the NaN (Not-a-Number) value, a singularity comparable to
+ * SQL's null. This is because the builtin == operator demands that a == a.
+ *
+ * The usefulness of this operator is questionable. No interpretation
+ * whatsoever is imposed on the data; 0 and 0.0 are considered different,
+ * as are null vs. the empty string, or even different (but possibly
+ * equivalent and equally valid) encodings of the same Unicode character
+ * etc.
+ */
+ bool operator==(const field &) const; //[t75]
+
+ /// Byte-by-byte comparison (all nulls are considered equal)
+ /** @warning See operator==() for important information about this operator
+ */
+ bool operator!=(const field &rhs) const //[t82]
+ {return not operator==(rhs);}
+ //@}
+
+ /**
+ * @name Column information
+ */
+ //@{
+ /// Column name
+ const char *name() const; //[t11]
+
+ /// Column type
+ oid type() const; //[t07]
+
+ /// What table did this column come from?
+ oid table() const; //[t02]
+
+ row_size_type num() const { return col(); } //[t82]
+
+ /// What column number in its originating table did this column come from?
+ row_size_type table_column() const; //[t93]
+ //@}
+
+ /**
+ * @name Content access
+ */
+ //@{
+ /// Read as plain C string
+ /** Since the field's data is stored internally in the form of a
+ * zero-terminated C string, this is the fastest way to read it. Use the
+ * to() or as() functions to convert the string to other types such as
+ * @c int, or to C++ strings.
+ */
+ const char *c_str() const; //[t02]
+
+ /// Is this field's value null?
+ bool is_null() const noexcept; //[t12]
+
+ /// Return number of bytes taken up by the field's value.
+ /**
+ * Includes the terminating zero byte.
+ */
+ size_type size() const noexcept; //[t11]
+
+ /// Read value into Obj; or leave Obj untouched and return @c false if null
+ /** Note this can be used with optional types (except pointers other than
+ * C-strings)
+ */
+ template<typename T> auto to(T &Obj) const //[t03]
+ -> typename std::enable_if<(
+ not std::is_pointer<T>::value
+ or std::is_same<T, const char*>::value
+ ), bool>::type
+ {
+ const char *const bytes = c_str();
+ if (bytes[0] == '\0' and is_null()) return false;
+ from_string(bytes, Obj);
+ return true;
+ }
+
+ /// Read value into Obj; or leave Obj untouched and return @c false if null
+ template<typename T> bool operator>>(T &Obj) const //[t07]
+ { return to(Obj); }
+
+ /// Read value into Obj; or use Default & return @c false if null
+ /** Note this can be used with optional types (except pointers other than
+ * C-strings)
+ */
+ template<typename T> auto to(T &Obj, const T &Default) const //[t12]
+ -> typename std::enable_if<(
+ not std::is_pointer<T>::value
+ or std::is_same<T, const char*>::value
+ ), bool>::type
+ {
+ const bool NotNull = to(Obj);
+ if (not NotNull) Obj = Default;
+ return NotNull;
+ }
+
+ /// Return value as object of given type, or Default if null
+ /** Note that unless the function is instantiated with an explicit template
+ * argument, the Default value's type also determines the result type.
+ */
+ template<typename T> T as(const T &Default) const //[t01]
+ {
+ T Obj;
+ to(Obj, Default);
+ return Obj;
+ }
+
+ /// Return value as object of given type, or throw exception if null
+ /** Use as `as<std::optional<int>>()` or `as<my_untemplated_optional_t>()` as
+ * an alternative to `get<int>()`; this is disabled for use with raw pointers
+ * (other than C-strings) because storage for the value can't safely be
+ * allocated here
+ */
+ template<typename T> T as() const //[t45]
+ {
+ T Obj;
+ if (not to(Obj)) Obj = string_traits<T>::null();
+ return Obj;
+ }
+
+ /// Return value wrapped in some optional type (empty for nulls)
+ /** Use as `get<int>()` as before to obtain previous behavior (i.e. only
+ * usable when `std::optional` or `std::experimental::optional` are
+ * available), or specify container type with `get<int, std::optional>()`
+ */
+ template<typename T, template<typename> class O
+#if defined(PQXX_HAVE_OPTIONAL)
+ = std::optional
+#elif defined(PQXX_HAVE_EXP_OPTIONAL) && !defined(PQXX_HIDE_EXP_OPTIONAL)
+ = std::experimental::optional
+#endif
+ > constexpr O<T> get() const { return as<O<T>>(); }
+
+ /// Parse the field as an SQL array.
+ /** Call the parser to retrieve values (and structure) from the array.
+ *
+ * Make sure the @c result object stays alive until parsing is finished. If
+ * you keep the @c row of @c field object alive, it will keep the @c result
+ * object alive as well.
+ */
+ array_parser as_array() const
+ { return array_parser{c_str(), m_home.m_encoding}; }
+ //@}
+
+
+protected:
+ const result &home() const noexcept { return m_home; }
+ size_t idx() const noexcept { return m_row; }
+ row_size_type col() const noexcept { return row_size_type(m_col); }
+
+ /**
+ * You'd expect this to be a size_t, but due to the way reverse iterators
+ * are related to regular iterators, it must be allowed to underflow to -1.
+ */
+ long m_col;
+
+private:
+ result m_home;
+ size_t m_row;
+};
+
+
+/// Specialization: <tt>to(string &)</tt>.
+template<>
+inline bool field::to<std::string>(std::string &Obj) const
+{
+ const char *const bytes = c_str();
+ if (bytes[0] == '\0' and is_null()) return false;
+ Obj = std::string{bytes, size()};
+ return true;
+}
+
+/// Specialization: <tt>to(const char *&)</tt>.
+/** The buffer has the same lifetime as the data in this result (i.e. of this
+ * result object, or the last remaining one copied from it etc.), so take care
+ * not to use it after the last result object referring to this query result is
+ * destroyed.
+ */
+template<>
+inline bool field::to<const char *>(const char *&Obj) const
+{
+ if (is_null()) return false;
+ Obj = c_str();
+ return true;
+}
+
+
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class field_streambuf :
+ public std::basic_streambuf<CHAR, TRAITS>
+{
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+ using openmode = std::ios::openmode;
+ using seekdir = std::ios::seekdir;
+
+ explicit field_streambuf(const field &F) : //[t74]
+ m_field{F}
+ {
+ initialize();
+ }
+
+protected:
+ virtual int sync() override { return traits_type::eof(); }
+
+protected:
+ virtual pos_type seekoff(off_type, seekdir, openmode) override
+ { return traits_type::eof(); }
+ virtual pos_type seekpos(pos_type, openmode) override
+ {return traits_type::eof();}
+ virtual int_type overflow(int_type) override
+ { return traits_type::eof(); }
+ virtual int_type underflow() override
+ { return traits_type::eof(); }
+
+private:
+ const field &m_field;
+
+ int_type initialize()
+ {
+ char_type *G =
+ reinterpret_cast<char_type *>(const_cast<char *>(m_field.c_str()));
+ this->setg(G, G, G + m_field.size());
+ return int_type(m_field.size());
+ }
+};
+
+
+/// Input stream that gets its data from a result field
+/** Use this class exactly as you would any other istream to read data from a
+ * field. All formatting and streaming operations of @c std::istream are
+ * supported. What you'll typically want to use, however, is the fieldstream
+ * alias (which defines a basic_fieldstream for @c char). This is similar to
+ * how e.g. @c std::ifstream relates to @c std::basic_ifstream.
+ *
+ * This class has only been tested for the char type (and its default traits).
+ */
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class basic_fieldstream :
+ public std::basic_istream<CHAR, TRAITS>
+{
+ using super = std::basic_istream<CHAR, TRAITS>;
+
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+
+ basic_fieldstream(const field &F) : super{nullptr}, m_buf{F}
+ { super::init(&m_buf); }
+
+private:
+ field_streambuf<CHAR, TRAITS> m_buf;
+};
+
+using fieldstream = basic_fieldstream<char>;
+
+/// Write a result field to any type of stream
+/** This can be convenient when writing a field to an output stream. More
+ * importantly, it lets you write a field to e.g. a @c stringstream which you
+ * can then use to read, format and convert the field in ways that to() does not
+ * support.
+ *
+ * Example: parse a field into a variable of the nonstandard
+ * "<tt>long long</tt>" type.
+ *
+ * @code
+ * extern result R;
+ * long long L;
+ * stringstream S;
+ *
+ * // Write field's string into S
+ * S << R[0][0];
+ *
+ * // Parse contents of S into L
+ * S >> L;
+ * @endcode
+ */
+template<typename CHAR>
+inline std::basic_ostream<CHAR> &operator<<(
+ std::basic_ostream<CHAR> &S, const field &F) //[t46]
+{
+ S.write(F.c_str(), std::streamsize(F.size()));
+ return S;
+}
+
+
+/// Convert a field's string contents to another type.
+template<typename T>
+inline void from_string(const field &F, T &Obj) //[t46]
+ { from_string(F.c_str(), Obj, F.size()); }
+
+/// Convert a field to a string.
+template<> PQXX_LIBEXPORT std::string to_string(const field &Obj); //[t74]
+
+} // namespace pqxx
+#include "pqxx/compiler-internal-post.hxx"
+#endif
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
diff --git a/contrib/libs/libpqxx/include/pqxx/isolation.hxx b/contrib/libs/libpqxx/include/pqxx/isolation.hxx
new file mode 100644
index 0000000000..fbabb994ed
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/isolation.hxx
@@ -0,0 +1,87 @@
+/** Definitions of transaction isolation levels.
+ *
+ * Policies and traits describing SQL transaction isolation levels
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/isolation instead.
+ *
+ * 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_ISOLATION
+#define PQXX_H_ISOLATION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/util.hxx"
+
+namespace pqxx
+{
+
+/// Transaction isolation levels.
+/** These are as defined in the SQL standard. But there are a few notes
+ * specific to PostgreSQL.
+ *
+ * First, postgres does not support "read uncommitted." The lowest level you
+ * can get is "read committed," which is better. PostgreSQL is built on the
+ * MVCC paradigm, which guarantees "read committed" isolation without any
+ * additional performance overhead, so there was no point in providing the
+ * lower level.
+ *
+ * Second, "repeatable read" also makes more isolation guarantees than the
+ * standard requires. According to the standard, this level prevents "dirty
+ * reads" and "nonrepeatable reads," but not "phantom reads." In postgres,
+ * it actually prevents all three.
+ *
+ * Third, "serializable" is only properly supported starting at postgres 9.1.
+ * If you request "serializable" isolation on an older backend, you will get
+ * the same isolation as in "repeatable read." It's better than the "repeatable
+ * read" defined in the SQL standard, but not a complete implementation of the
+ * standard's "serializable" isolation level.
+ *
+ * In general, a lower isolation level will allow more surprising interactions
+ * between ongoing transactions, but improve performance. A higher level
+ * gives you more protection from subtle concurrency bugs, but sometimes it
+ * may not be possible to complete your transaction without avoiding paradoxes
+ * in the data. In that case a transaction may fail, and the application will
+ * have to re-do the whole thing based on the latest state of the database.
+ * (If you want to retry your code in that situation, have a look at the
+ * transactor framework.)
+ *
+ * Study the levels and design your application with the right level in mind.
+ */
+enum isolation_level
+{
+ // read_uncommitted,
+ read_committed,
+ repeatable_read,
+ serializable
+};
+
+/// Traits class to describe an isolation level; primarly for libpqxx's own use
+template<isolation_level LEVEL> struct isolation_traits
+{
+ static constexpr isolation_level level() noexcept { return LEVEL; }
+ static constexpr const char *name() noexcept;
+};
+
+
+template<>
+inline constexpr const char *isolation_traits<read_committed>::name() noexcept
+ { return "READ COMMITTED"; }
+
+template<>
+inline constexpr const char *isolation_traits<repeatable_read>::name() noexcept
+ { return "REPEATABLE READ"; }
+
+template<>
+inline constexpr const char *isolation_traits<serializable>::name() noexcept
+ { return "SERIALIZABLE"; }
+
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/largeobject b/contrib/libs/libpqxx/include/pqxx/largeobject
new file mode 100644
index 0000000000..b1dedd597a
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/largeobject
@@ -0,0 +1,6 @@
+/** Large Objects interface.
+ *
+ * Supports direct access to large objects, as well as through I/O streams
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/largeobject.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/largeobject.hxx b/contrib/libs/libpqxx/include/pqxx/largeobject.hxx
new file mode 100644
index 0000000000..f2f7c0e7fe
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/largeobject.hxx
@@ -0,0 +1,672 @@
+/** Large Objects interface.
+ *
+ * Allows access to large objects directly, or through I/O streams.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead.
+ *
+ * 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_LARGEOBJECT
+#define PQXX_H_LARGEOBJECT
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <streambuf>
+
+#include "pqxx/dbtransaction.hxx"
+
+
+namespace pqxx
+{
+/// Identity of a large object
+/** This class encapsulates the identity of a large object. To access the
+ * contents of the object, create a largeobjectaccess, a largeobject_streambuf,
+ * or an ilostream, an olostream or a lostream around the largeobject.
+ *
+ * A largeobject must be accessed only from within a backend transaction, but
+ * the object's identity remains valid as long as the object exists.
+ */
+class PQXX_LIBEXPORT largeobject
+{
+public:
+ using size_type = large_object_size_type;
+
+ /// Refer to a nonexistent large object (similar to what a null pointer does)
+ largeobject() noexcept =default; //[t48]
+
+ /// Create new large object
+ /** @param T Backend transaction in which the object is to be created
+ */
+ explicit largeobject(dbtransaction &T); //[t48]
+
+ /// Wrap object with given oid
+ /** Convert combination of a transaction and object identifier into a
+ * large object identity. Does not affect the database.
+ * @param O Object identifier for the given object
+ */
+ explicit largeobject(oid O) noexcept : m_id{O} {} //[t48]
+
+ /// Import large object from a local file
+ /** Creates a large object containing the data found in the given file.
+ * @param T Backend transaction in which the large object is to be created
+ * @param File A filename on the client program's filesystem
+ */
+ largeobject(dbtransaction &T, const std::string &File); //[t53]
+
+ /// Take identity of an opened large object
+ /** Copy identity of already opened large object. Note that this may be done
+ * as an implicit conversion.
+ * @param O Already opened large object to copy identity from
+ */
+ largeobject(const largeobjectaccess &O) noexcept; //[t50]
+
+ /// Object identifier
+ /** The number returned by this function identifies the large object in the
+ * database we're connected to (or oid_none is returned if we refer to the
+ * null object).
+ */
+ oid id() const noexcept { return m_id; } //[t48]
+
+ /**
+ * @name Identity comparisons
+ *
+ * These operators compare the object identifiers of large objects. This has
+ * nothing to do with the objects' actual contents; use them only for keeping
+ * track of containers of references to large objects and such.
+ */
+ //@{
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator==(const largeobject &other) const //[t51]
+ { return m_id == other.m_id; }
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator!=(const largeobject &other) const //[t51]
+ { return m_id != other.m_id; }
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator<=(const largeobject &other) const //[t51]
+ { return m_id <= other.m_id; }
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator>=(const largeobject &other) const //[t51]
+ { return m_id >= other.m_id; }
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator<(const largeobject &other) const //[t51]
+ { return m_id < other.m_id; }
+ /// Compare object identities
+ /** @warning Only valid between large objects in the same database. */
+ bool operator>(const largeobject &other) const //[t51]
+ { return m_id > other.m_id; }
+ //@}
+
+ /// Export large object's contents to a local file
+ /** Writes the data stored in the large object to the given file.
+ * @param T Transaction in which the object is to be accessed
+ * @param File A filename on the client's filesystem
+ */
+ void to_file(dbtransaction &T, const std::string &File) const; //[t52]
+
+ /// Delete large object from database
+ /** Unlike its low-level equivalent cunlink, this will throw an exception if
+ * deletion fails.
+ * @param T Transaction in which the object is to be deleted
+ */
+ void remove(dbtransaction &T) const; //[t48]
+
+protected:
+ PQXX_PURE static internal::pq::PGconn *raw_connection(
+ const dbtransaction &T);
+
+ PQXX_PRIVATE std::string reason(const connection_base &, int err) const;
+
+private:
+ oid m_id = oid_none;
+};
+
+
+// TODO: New hierarchy with separate read / write / mixed-mode access
+
+/// Accessor for large object's contents.
+class PQXX_LIBEXPORT largeobjectaccess : private largeobject
+{
+public:
+ using largeobject::size_type;
+ using off_type = long;
+ using pos_type = size_type;
+
+ /// Open mode: @c in, @c out (can be combined with the "or" operator)
+ /** According to the C++ standard, these should be in @c std::ios_base. We
+ * take them from @c std::ios instead, which should be safe because it
+ * inherits the same definition, to accommodate gcc 2.95 & 2.96.
+ */
+ using openmode = std::ios::openmode;
+
+ /// Seek direction: @c beg, @c cur, @c end
+ /** According to the C++ standard, these should be in @c std::ios_base. We
+ * take them from @c std::ios instead, which should be safe because it
+ * inherits the same definition, to accommodate gcc 2.95 & 2.96.
+ */
+ using seekdir = std::ios::seekdir;
+
+ /// Create new large object and open it
+ /**
+ * @param T Backend transaction in which the object is to be created
+ * @param mode Access mode, defaults to ios_base::in | ios_base::out
+ */
+ explicit largeobjectaccess( //[t51]
+ dbtransaction &T,
+ openmode mode=std::ios::in|std::ios::out);
+
+ /// Open large object with given oid
+ /** Convert combination of a transaction and object identifier into a
+ * large object identity. Does not affect the database.
+ * @param T Transaction in which the object is to be accessed
+ * @param O Object identifier for the given object
+ * @param mode Access mode, defaults to ios_base::in | ios_base::out
+ */
+ largeobjectaccess( //[t52]
+ dbtransaction &T,
+ oid O,
+ openmode mode=std::ios::in|std::ios::out);
+
+ /// Open given large object
+ /** Open a large object with the given identity for reading and/or writing
+ * @param T Transaction in which the object is to be accessed
+ * @param O Identity for the large object to be accessed
+ * @param mode Access mode, defaults to ios_base::in | ios_base::out
+ */
+ largeobjectaccess( //[t50]
+ dbtransaction &T,
+ largeobject O,
+ openmode mode=std::ios::in|std::ios::out);
+
+ /// Import large object from a local file and open it
+ /** Creates a large object containing the data found in the given file.
+ * @param T Backend transaction in which the large object is to be created
+ * @param File A filename on the client program's filesystem
+ * @param mode Access mode, defaults to ios_base::in | ios_base::out
+ */
+ largeobjectaccess( //[t55]
+ dbtransaction &T,
+ const std::string &File,
+ openmode mode=std::ios::in|std::ios::out);
+
+ ~largeobjectaccess() noexcept { close(); }
+
+ /// Object identifier
+ /** The number returned by this function uniquely identifies the large object
+ * in the context of the database we're connected to.
+ */
+ using largeobject::id;
+
+ /// Export large object's contents to a local file
+ /** Writes the data stored in the large object to the given file.
+ * @param File A filename on the client's filesystem
+ */
+ void to_file(const std::string &File) const //[t54]
+ { largeobject::to_file(m_trans, File); }
+
+ using largeobject::to_file;
+
+ /**
+ * @name High-level access to object contents
+ */
+ //@{
+ /// Write data to large object
+ /** If not all bytes could be written, an exception is thrown.
+ * @param Buf Data to write
+ * @param Len Number of bytes from Buf to write
+ */
+ void write(const char Buf[], size_type Len); //[t51]
+
+ /// Write string to large object
+ /** If not all bytes could be written, an exception is thrown.
+ * @param Buf Data to write; no terminating zero is written
+ */
+ void write(const std::string &Buf) //[t50]
+ { write(Buf.c_str(), static_cast<size_type>(Buf.size())); }
+
+ /// Read data from large object
+ /** Throws an exception if an error occurs while reading.
+ * @param Buf Location to store the read data in
+ * @param Len Number of bytes to try and read
+ * @return Number of bytes read, which may be less than the number requested
+ * if the end of the large object is reached
+ */
+ size_type read(char Buf[], size_type Len); //[t50]
+
+ /// Seek in large object's data stream
+ /** Throws an exception if an error occurs.
+ * @return The new position in the large object
+ */
+ size_type seek(size_type dest, seekdir dir); //[t51]
+
+ /// Report current position in large object's data stream
+ /** Throws an exception if an error occurs.
+ * @return The current position in the large object
+ */
+ size_type tell() const; //[t50]
+ //@}
+
+ /**
+ * @name Low-level access to object contents
+ *
+ * These functions provide a more "C-like" access interface, returning special
+ * values instead of throwing exceptions on error. These functions are
+ * generally best avoided in favour of the high-level access functions, which
+ * behave more like C++ functions should.
+ */
+ //@{
+ /// Seek in large object's data stream
+ /** Does not throw exception in case of error; inspect return value and
+ * @c errno instead.
+ * @param dest Offset to go to
+ * @param dir Origin to which dest is relative: ios_base::beg (from beginning
+ * of the object), ios_base::cur (from current access position), or
+ * ios_base;:end (from end of object)
+ * @return New position in large object, or -1 if an error occurred.
+ */
+ pos_type cseek(off_type dest, seekdir dir) noexcept; //[t50]
+
+ /// Write to large object's data stream
+ /** Does not throw exception in case of error; inspect return value and
+ * @c errno instead.
+ * @param Buf Data to write
+ * @param Len Number of bytes to write
+ * @return Number of bytes actually written, or -1 if an error occurred.
+ */
+ off_type cwrite(const char Buf[], size_type Len) noexcept; //[t50]
+
+ /// Read from large object's data stream
+ /** Does not throw exception in case of error; inspect return value and
+ * @c errno instead.
+ * @param Buf Area where incoming bytes should be stored
+ * @param Len Number of bytes to read
+ * @return Number of bytes actually read, or -1 if an error occurred.
+ */
+ off_type cread(char Buf[], size_type Len) noexcept; //[t50]
+
+ /// Report current position in large object's data stream
+ /** Does not throw exception in case of error; inspect return value and
+ * @c errno instead.
+ * @return Current position in large object, of -1 if an error occurred.
+ */
+ pos_type ctell() const noexcept; //[t50]
+ //@}
+
+ /**
+ * @name Error/warning output
+ */
+ //@{
+ /// Issue message to transaction's notice processor
+ void process_notice(const std::string &) noexcept; //[t50]
+ //@}
+
+ using largeobject::remove;
+
+ using largeobject::operator==;
+ using largeobject::operator!=;
+ using largeobject::operator<;
+ using largeobject::operator<=;
+ using largeobject::operator>;
+ using largeobject::operator>=;
+
+private:
+ PQXX_PRIVATE std::string reason(int err) const;
+ internal::pq::PGconn *raw_connection() const
+ { return largeobject::raw_connection(m_trans); }
+
+ PQXX_PRIVATE void open(openmode mode);
+ void close() noexcept;
+
+ dbtransaction &m_trans;
+ int m_fd = -1;
+
+ largeobjectaccess() =delete;
+ largeobjectaccess(const largeobjectaccess &) =delete;
+ largeobjectaccess operator=(const largeobjectaccess &) =delete;
+};
+
+
+/// Streambuf to use large objects in standard I/O streams
+/** The standard streambuf classes provide uniform access to data storage such
+ * as files or string buffers, so they can be accessed using standard input or
+ * output streams. This streambuf implementation provides similar access to
+ * large objects, so they can be read and written using the same stream classes.
+ *
+ * @warning This class may not work properly in compiler environments that don't
+ * fully support Standard-compliant streambufs, such as g++ 2.95 or older.
+ */
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class largeobject_streambuf :
+ public std::basic_streambuf<CHAR, TRAITS>
+{
+ using size_type = long;
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+ using openmode = largeobjectaccess::openmode;
+ using seekdir = largeobjectaccess::seekdir;
+
+ largeobject_streambuf( //[t48]
+ dbtransaction &T,
+ largeobject O,
+ openmode mode=std::ios::in|std::ios::out,
+ size_type BufSize=512) :
+ m_bufsize{BufSize},
+ m_obj{T, O, mode},
+ m_g{nullptr},
+ m_p{nullptr}
+ { initialize(mode); }
+
+ largeobject_streambuf( //[t48]
+ dbtransaction &T,
+ oid O,
+ openmode mode=std::ios::in|std::ios::out,
+ size_type BufSize=512) :
+ m_bufsize{BufSize},
+ m_obj{T, O, mode},
+ m_g{nullptr},
+ m_p{nullptr}
+ { initialize(mode); }
+
+ virtual ~largeobject_streambuf() noexcept
+ { delete [] m_p; delete [] m_g; }
+
+
+ /// For use by large object stream classes
+ void process_notice(const std::string &s) { m_obj.process_notice(s); }
+
+protected:
+ virtual int sync() override
+ {
+ // setg() sets eback, gptr, egptr
+ this->setg(this->eback(), this->eback(), this->egptr());
+ return overflow(EoF());
+ }
+
+ virtual pos_type seekoff(
+ off_type offset,
+ seekdir dir,
+ openmode)
+ override
+ {
+ return AdjustEOF(m_obj.cseek(largeobjectaccess::off_type(offset), dir));
+ }
+
+ virtual pos_type seekpos(pos_type pos, openmode) override
+ {
+ const largeobjectaccess::pos_type newpos = m_obj.cseek(
+ largeobjectaccess::off_type(pos),
+ std::ios::beg);
+ return AdjustEOF(newpos);
+ }
+
+ virtual int_type overflow(int_type ch = EoF()) override
+ {
+ char *const pp = this->pptr();
+ if (pp == nullptr) return EoF();
+ char *const pb = this->pbase();
+ int_type res = 0;
+
+ if (pp > pb) res = int_type(AdjustEOF(m_obj.cwrite(pb, pp-pb)));
+ this->setp(m_p, m_p + m_bufsize);
+
+ // Write that one more character, if it's there.
+ if (ch != EoF())
+ {
+ *this->pptr() = char(ch);
+ this->pbump(1);
+ }
+ return res;
+ }
+
+ virtual int_type underflow() override
+ {
+ if (this->gptr() == nullptr) return EoF();
+ char *const eb = this->eback();
+ const int_type res(static_cast<int_type>(
+ AdjustEOF(m_obj.cread(this->eback(), m_bufsize))));
+ this->setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
+ return ((res == 0) or (res == EoF())) ? EoF() : *eb;
+ }
+
+private:
+ /// Shortcut for traits_type::eof().
+ static int_type EoF() { return traits_type::eof(); }
+
+ /// Helper: change error position of -1 to EOF (probably a no-op).
+ template<typename INTYPE>
+ static std::streampos AdjustEOF(INTYPE pos)
+ { return (pos==-1) ? std::streampos(EoF()) : std::streampos(pos); }
+
+ void initialize(openmode mode)
+ {
+ if (mode & std::ios::in)
+ {
+ m_g = new char_type[unsigned(m_bufsize)];
+ this->setg(m_g, m_g, m_g);
+ }
+ if (mode & std::ios::out)
+ {
+ m_p = new char_type[unsigned(m_bufsize)];
+ this->setp(m_p, m_p + m_bufsize);
+ }
+ }
+
+ const size_type m_bufsize;
+ largeobjectaccess m_obj;
+
+ /// Get & put buffers.
+ char_type *m_g, *m_p;
+};
+
+
+/// Input stream that gets its data from a large object.
+/** Use this class exactly as you would any other istream to read data from a
+ * large object. All formatting and streaming operations of @c std::istream are
+ * supported. What you'll typically want to use, however, is the ilostream
+ * alias (which defines a basic_ilostream for @c char). This is similar to
+ * how e.g. @c std::ifstream relates to @c std::basic_ifstream.
+ *
+ * Currently only works for <tt><char, std::char_traits<char>></tt>.
+ */
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class basic_ilostream :
+ public std::basic_istream<CHAR, TRAITS>
+{
+ using super = std::basic_istream<CHAR, TRAITS>;
+
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+
+ /// Create a basic_ilostream
+ /**
+ * @param T Transaction in which this stream is to exist
+ * @param O Large object to access
+ * @param BufSize Size of buffer to use internally (optional)
+ */
+ basic_ilostream( //[t57]
+ dbtransaction &T,
+ largeobject O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::in, BufSize}
+ { super::init(&m_buf); }
+
+ /// Create a basic_ilostream
+ /**
+ * @param T Transaction in which this stream is to exist
+ * @param O Identifier of a large object to access
+ * @param BufSize Size of buffer to use internally (optional)
+ */
+ basic_ilostream( //[t48]
+ dbtransaction &T,
+ oid O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::in, BufSize}
+ { super::init(&m_buf); }
+
+private:
+ largeobject_streambuf<CHAR,TRAITS> m_buf;
+};
+
+using ilostream = basic_ilostream<char>;
+
+
+/// Output stream that writes data back to a large object
+/** Use this class exactly as you would any other ostream to write data to a
+ * large object. All formatting and streaming operations of @c std::ostream are
+ * supported. What you'll typically want to use, however, is the olostream
+ * alias (which defines a basic_olostream for @c char). This is similar to
+ * how e.g. @c std::ofstream is related to @c std::basic_ofstream.
+ *
+ * Currently only works for <tt><char, std::char_traits<char>></tt>.
+ */
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class basic_olostream :
+ public std::basic_ostream<CHAR, TRAITS>
+{
+ using super = std::basic_ostream<CHAR, TRAITS>;
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+
+ /// Create a basic_olostream
+ /**
+ * @param T transaction in which this stream is to exist
+ * @param O a large object to access
+ * @param BufSize size of buffer to use internally (optional)
+ */
+ basic_olostream( //[t48]
+ dbtransaction &T,
+ largeobject O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::out, BufSize}
+ { super::init(&m_buf); }
+
+ /// Create a basic_olostream
+ /**
+ * @param T transaction in which this stream is to exist
+ * @param O a large object to access
+ * @param BufSize size of buffer to use internally (optional)
+ */
+ basic_olostream( //[t57]
+ dbtransaction &T,
+ oid O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::out, BufSize}
+ { super::init(&m_buf); }
+
+ ~basic_olostream()
+ {
+ try
+ {
+ m_buf.pubsync(); m_buf.pubsync();
+ }
+ catch (const std::exception &e)
+ {
+ m_buf.process_notice(e.what());
+ }
+ }
+
+private:
+ largeobject_streambuf<CHAR,TRAITS> m_buf;
+};
+
+using olostream = basic_olostream<char>;
+
+
+/// Stream that reads and writes a large object
+/** Use this class exactly as you would a std::iostream to read data from, or
+ * write data to a large object. All formatting and streaming operations of
+ * @c std::iostream are supported. What you'll typically want to use, however,
+ * is the lostream alias (which defines a basic_lostream for @c char). This
+ * is similar to how e.g. @c std::fstream is related to @c std::basic_fstream.
+ *
+ * Currently only works for <tt><char, std::char_traits<char>></tt>.
+ */
+template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
+ class basic_lostream :
+ public std::basic_iostream<CHAR, TRAITS>
+{
+ using super = std::basic_iostream<CHAR, TRAITS>;
+
+public:
+ using char_type = CHAR;
+ using traits_type = TRAITS;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+
+ /// Create a basic_lostream
+ /**
+ * @param T Transaction in which this stream is to exist
+ * @param O Large object to access
+ * @param BufSize Size of buffer to use internally (optional)
+ */
+ basic_lostream( //[t59]
+ dbtransaction &T,
+ largeobject O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::in | std::ios::out, BufSize}
+ { super::init(&m_buf); }
+
+ /// Create a basic_lostream
+ /**
+ * @param T Transaction in which this stream is to exist
+ * @param O Large object to access
+ * @param BufSize Size of buffer to use internally (optional)
+ */
+ basic_lostream( //[t59]
+ dbtransaction &T,
+ oid O,
+ largeobject::size_type BufSize=512) :
+ super{nullptr},
+ m_buf{T, O, std::ios::in | std::ios::out, BufSize}
+ { super::init(&m_buf); }
+
+ ~basic_lostream()
+ {
+ try
+ {
+ m_buf.pubsync(); m_buf.pubsync();
+ }
+ catch (const std::exception &e)
+ {
+ m_buf.process_notice(e.what());
+ }
+ }
+
+private:
+ largeobject_streambuf<CHAR,TRAITS> m_buf;
+};
+
+using lostream = basic_lostream<char>;
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/nontransaction b/contrib/libs/libpqxx/include/pqxx/nontransaction
new file mode 100644
index 0000000000..e62ebdbc0b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/nontransaction
@@ -0,0 +1,6 @@
+/** pqxx::nontransaction class.
+ *
+ * pqxx::nontransaction provides nontransactional database access.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/nontransaction.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/nontransaction.hxx b/contrib/libs/libpqxx/include/pqxx/nontransaction.hxx
new file mode 100644
index 0000000000..40fb1331cf
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/nontransaction.hxx
@@ -0,0 +1,80 @@
+/** Definition of the pqxx::nontransaction class.
+ *
+ * pqxx::nontransaction provides nontransactional database access
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/nontransaction instead.
+ *
+ * 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_NONTRANSACTION
+#define PQXX_H_NONTRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/connection_base.hxx"
+#include "pqxx/result.hxx"
+#include "pqxx/transaction_base.hxx"
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+
+/// Simple "transaction" class offering no transactional integrity.
+/**
+ * @ingroup transaction
+ *
+ * nontransaction, like transaction or any other transaction_base-derived class,
+ * provides access to a database through a connection. Unlike its siblings,
+ * however, nontransaction does not maintain any kind of transactional
+ * integrity. This may be useful eg. for read-only access to the database that
+ * does not require a consistent, atomic view on its data; or for operations
+ * that are not allowed within a backend transaction, such as creating tables.
+ *
+ * For queries that update the database, however, a real transaction is likely
+ * to be faster unless the transaction consists of only a single record update.
+ *
+ * Also, you can keep a nontransaction open for as long as you like. Actual
+ * back-end transactions are limited in lifespan, and will sometimes fail just
+ * because they took too long to execute or were left idle for too long. This
+ * will not happen with a nontransaction (although the connection may still time
+ * out, e.g. when the network is unavailable for a very long time).
+ *
+ * Any query executed in a nontransaction is committed immediately, and neither
+ * commit() nor abort() has any effect.
+ *
+ * Database features that require a backend transaction, such as cursors or
+ * large objects, will not work in a nontransaction.
+ */
+class PQXX_LIBEXPORT nontransaction : public transaction_base
+{
+public:
+ /// Constructor.
+ /** Create a "dummy" transaction.
+ * @param C Connection that this "transaction" will operate on.
+ * @param Name Optional name for the transaction, beginning with a letter
+ * and containing only letters and digits.
+ */
+ explicit nontransaction( //[t14]
+ connection_base &C,
+ const std::string &Name=std::string{}) :
+ namedclass{"nontransaction", Name}, transaction_base{C} { Begin(); }
+
+ virtual ~nontransaction(); //[t14]
+
+private:
+ virtual void do_begin() override {} //[t14]
+ virtual result do_exec(const char C[]) override; //[t14]
+ virtual void do_commit() override {} //[t14]
+ virtual void do_abort() override {} //[t14]
+};
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/notification b/contrib/libs/libpqxx/include/pqxx/notification
new file mode 100644
index 0000000000..025b220baf
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/notification
@@ -0,0 +1,6 @@
+/** pqxx::notification_receiver functor interface.
+ *
+ * pqxx::notification_receiver handles incoming notifications.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/notification.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/notification.hxx b/contrib/libs/libpqxx/include/pqxx/notification.hxx
new file mode 100644
index 0000000000..77e818e009
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/notification.hxx
@@ -0,0 +1,91 @@
+/** Definition of the pqxx::notification_receiver functor interface.
+ *
+ * pqxx::notification_receiver handles incoming notifications.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/notification instead.
+ *
+ * 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_NOTIFICATION
+#define PQXX_H_NOTIFICATION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <string>
+
+#include "pqxx/types.hxx"
+
+
+namespace pqxx
+{
+/// "Observer" base class for notifications.
+/** @addtogroup notification Notifications and Receivers
+ *
+ * To listen on a notification issued using the NOTIFY command, derive your own
+ * class from notification_receiver and define its function-call operator to
+ * perform whatever action you wish to take when the given notification arrives.
+ * Then create an object of that class and pass it to your connection. DO NOT
+ * use raw SQL to listen for notifications, or your attempts to listen won't be
+ * resumed when a connection fails--and you'll have no way to notice.
+ *
+ * Notifications never arrive inside a transaction, not even in a
+ * nontransaction. Therefore, you are free to open a transaction of your own
+ * inside your receiver's function invocation operator.
+ *
+ * Notifications you are listening for may arrive anywhere within libpqxx code,
+ * but be aware that @b PostgreSQL @b defers @b notifications @b occurring
+ * @b inside @b transactions. (This was done for excellent reasons; just think
+ * about what happens if the transaction where you happen to handle an incoming
+ * notification is later rolled back for other reasons). So if you're keeping a
+ * transaction open, don't expect any of your receivers on the same connection
+ * to be notified.
+ *
+ * (For very similar reasons, outgoing notifications are also not sent until the
+ * transaction that sends them commits.)
+ *
+ * Multiple receivers on the same connection may listen on a notification of the
+ * same name. An incoming notification is processed by invoking all receivers
+ * (zero or more) of the same name.
+ */
+class PQXX_LIBEXPORT PQXX_NOVTABLE notification_receiver
+{
+public:
+ /// Register the receiver with a connection.
+ /**
+ * @param c Connnection to operate on.
+ * @param channel Name of the notification to listen for.
+ */
+ notification_receiver(connection_base &c, const std::string &channel);
+ notification_receiver(const notification_receiver &) =delete;
+ notification_receiver &operator=(const notification_receiver &) =delete;
+ virtual ~notification_receiver();
+
+ /// The channel that this receiver listens on.
+ const std::string &channel() const { return m_channel; }
+
+ /// Overridable: action to invoke when notification arrives.
+ /**
+ * @param payload On PostgreSQL 9.0 or later, an optional string that may have
+ * been passed to the NOTIFY command.
+ * @param backend_pid Process ID of the database backend process that served
+ * our connection when the notification arrived. The actual process ID behind
+ * the connection may have changed by the time this method is called.
+ */
+ virtual void operator()(const std::string &payload, int backend_pid) =0;
+
+protected:
+ connection_base &conn() const noexcept { return m_conn; }
+
+private:
+ connection_base &m_conn;
+ std::string m_channel;
+};
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/pipeline b/contrib/libs/libpqxx/include/pqxx/pipeline
new file mode 100644
index 0000000000..6029f14622
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/pipeline
@@ -0,0 +1,6 @@
+/** pqxx::pipeline class.
+ *
+ * Throughput-optimized query interface.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/pipeline.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/pipeline.hxx b/contrib/libs/libpqxx/include/pqxx/pipeline.hxx
new file mode 100644
index 0000000000..25a5dea6a6
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/pipeline.hxx
@@ -0,0 +1,210 @@
+/** Definition of the pqxx::pipeline class.
+ *
+ * Throughput-optimized query manager
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/pipeline instead.
+ *
+ * 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_PIPELINE
+#define PQXX_H_PIPELINE
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <limits>
+#include <map>
+#include <string>
+
+#include "pqxx/transaction_base.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+
+/// Processes several queries in FIFO manner, optimized for high throughput
+/** Use a pipeline if you want to execute queries without always sitting still
+ * while they execute. Result retrieval is decoupled from execution request;
+ * queries "go in at the front" and results "come out the back." Actually
+ * results may be retrieved in any order, if you want.
+ *
+ * Feel free to pump as many queries into the pipeline as possible, even if they
+ * were generated after looking at a result from the same pipeline. To get the
+ * best possible throughput, try to make insertion of queries run as far ahead
+ * of results retrieval as possible; issue each query as early as possible and
+ * retrieve their results as late as possible, so the pipeline has as many
+ * ongoing queries as possible at any given time. In other words, keep it busy!
+ *
+ * One warning: if any of the queries you insert leads to a syntactic error, the
+ * error may be returned as if it were generated by an older query. Future
+ * versions may try to work around this if working in a nontransaction.
+ */
+class PQXX_LIBEXPORT pipeline : public internal::transactionfocus
+{
+public:
+ using query_id = long;
+
+ pipeline(const pipeline &) =delete;
+ pipeline &operator=(const pipeline &) =delete;
+
+ explicit pipeline( //[t69]
+ transaction_base &,
+ const std::string &Name=std::string{});
+
+ ~pipeline() noexcept;
+
+ /// Add query to the pipeline.
+ /** Queries are accumulated in the pipeline and sent to the backend in a
+ * concatenated format, separated by semicolons. The queries you insert must
+ * not use this construct themselves, or the pipeline will get hopelessly
+ * confused!
+ * @return Identifier for this query, unique only within this pipeline
+ */
+ query_id insert(const std::string &); //[t69]
+
+ /// Wait for all ongoing or pending operations to complete.
+ /** Detaches from the transaction when done. */
+ void complete(); //[t71]
+
+ /// Forget all ongoing or pending operations and retrieved results
+ /** Queries already sent to the backend may still be completed, depending
+ * on implementation and timing.
+ *
+ * Any error state (unless caused by an internal error) will also be cleared.
+ * This is mostly useful in a nontransaction, since a backend transaction is
+ * aborted automatically when an error occurs.
+ *
+ * Detaches from the transaction when done.
+ */
+ void flush(); //[t70]
+
+ /// Cancel ongoing query, if any.
+ /** May cancel any or all of the queries that have been inserted at this point
+ * whose results have not yet been retrieved. If the pipeline lives in a
+ * backend transaction, that transaction may be left in a nonfunctional state
+ * in which it can only be aborted.
+ *
+ * Therefore, either use this function in a nontransaction, or abort the
+ * transaction after calling it.
+ */
+ void cancel();
+
+ /// Is result for given query available?
+ bool is_finished(query_id) const; //[t71]
+
+ /// Retrieve result for given query.
+ /** If the query failed for whatever reason, this will throw an exception.
+ * The function will block if the query has not finished yet.
+ * @warning If results are retrieved out-of-order, i.e. in a different order
+ * than the one in which their queries were inserted, errors may "propagate"
+ * to subsequent queries.
+ */
+ result retrieve(query_id qid) //[t71]
+ { return retrieve(m_queries.find(qid)).second; }
+
+ /// Retrieve oldest unretrieved result (possibly wait for one)
+ /** @return The query's identifier and its result set */
+ std::pair<query_id, result> retrieve(); //[t69]
+
+ bool empty() const noexcept { return m_queries.empty(); } //[t69]
+
+ /// Set maximum number of queries to retain before issuing them to the backend
+ /** The pipeline will perform better if multiple queries are issued at once,
+ * but retaining queries until the results are needed (as opposed to issuing
+ * them to the backend immediately) may negate any performance benefits the
+ * pipeline can offer.
+ *
+ * Recommended practice is to set this value no higher than the number of
+ * queries you intend to insert at a time.
+ * @param retain_max A nonnegative "retention capacity;" passing zero will
+ * cause queries to be issued immediately
+ * @return Old retention capacity
+ */
+ int retain(int retain_max=2); //[t70]
+
+
+ /// Resume retained query emission (harmless when not needed)
+ void resume(); //[t70]
+
+private:
+ class PQXX_PRIVATE Query
+ {
+ public:
+ explicit Query(const std::string &q) : m_query{q}, m_res{} {}
+
+ const result &get_result() const noexcept { return m_res; }
+ void set_result(const result &r) noexcept { m_res = r; }
+ const std::string &get_query() const noexcept { return m_query; }
+
+ private:
+ std::string m_query;
+ result m_res;
+ };
+
+ using QueryMap = std::map<query_id,Query>;
+
+ void attach();
+ void detach();
+
+ /// Upper bound to query id's
+ static constexpr query_id qid_limit() noexcept
+ {
+ // Parenthesise this to work around an eternal Visual C++ problem:
+ // Without the extra parentheses, unless NOMINMAX is defined, the
+ // preprocessor will mistake this "max" for its annoying built-in macro
+ // of the same name.
+ return (std::numeric_limits<query_id>::max)();
+ }
+
+ /// Create new query_id
+ PQXX_PRIVATE query_id generate_id();
+
+ bool have_pending() const noexcept
+ { return m_issuedrange.second != m_issuedrange.first; }
+
+ PQXX_PRIVATE void issue();
+
+ /// The given query failed; never issue anything beyond that
+ void set_error_at(query_id qid) noexcept
+ { if (qid < m_error) m_error = qid; }
+
+ /// Throw pqxx::internal_error.
+ [[noreturn]] PQXX_PRIVATE void internal_error(const std::string &err);
+
+ PQXX_PRIVATE bool obtain_result(bool expect_none=false);
+
+ PQXX_PRIVATE void obtain_dummy();
+ PQXX_PRIVATE void get_further_available_results();
+ PQXX_PRIVATE void check_end_results();
+
+ /// Receive any results that happen to be available; it's not urgent
+ PQXX_PRIVATE void receive_if_available();
+
+ /// Receive results, up to stop if possible
+ PQXX_PRIVATE void receive(pipeline::QueryMap::const_iterator stop);
+ std::pair<pipeline::query_id, result>
+ retrieve(pipeline::QueryMap::iterator);
+
+ QueryMap m_queries;
+ std::pair<QueryMap::iterator,QueryMap::iterator> m_issuedrange;
+ int m_retain = 0;
+ int m_num_waiting = 0;
+ query_id m_q_id = 0;
+
+ /// Is there a "dummy query" pending?
+ bool m_dummy_pending = false;
+
+ /// Point at which an error occurred; no results beyond it will be available
+ query_id m_error = qid_limit();
+};
+
+} // namespace
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/pqxx b/contrib/libs/libpqxx/include/pqxx/pqxx
new file mode 100644
index 0000000000..9cc33ad121
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/pqxx
@@ -0,0 +1,19 @@
+/// Convenience header: include all libpqxx definitions.
+#include "pqxx/array"
+#include "pqxx/binarystring"
+#include "pqxx/connection"
+#include "pqxx/cursor"
+#include "pqxx/errorhandler"
+#include "pqxx/except"
+#include "pqxx/largeobject"
+#include "pqxx/nontransaction"
+#include "pqxx/notification"
+#include "pqxx/pipeline"
+#include "pqxx/prepared_statement"
+#include "pqxx/result"
+#include "pqxx/robusttransaction"
+#include "pqxx/stream_from"
+#include "pqxx/stream_to"
+#include "pqxx/subtransaction"
+#include "pqxx/transaction"
+#include "pqxx/transactor"
diff --git a/contrib/libs/libpqxx/include/pqxx/prepared_statement b/contrib/libs/libpqxx/include/pqxx/prepared_statement
new file mode 100644
index 0000000000..20c645f301
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/prepared_statement
@@ -0,0 +1,6 @@
+/** Helper classes for defining and executing prepared statements.
+ *
+ * See the connection_base hierarchy for more about prepared statements
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/prepared_statement.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/prepared_statement.hxx b/contrib/libs/libpqxx/include/pqxx/prepared_statement.hxx
new file mode 100644
index 0000000000..604d40665a
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/prepared_statement.hxx
@@ -0,0 +1,177 @@
+/** Helper classes for defining and executing prepared statements.
+ *
+ * See the connection_base hierarchy for more about prepared statements.
+ *
+ * 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_PREPARED_STATEMENT
+#define PQXX_H_PREPARED_STATEMENT
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/types.hxx"
+#include "pqxx/internal/statement_parameters.hxx"
+
+
+
+namespace pqxx
+{
+/// Dedicated namespace for helper types related to prepared statements.
+namespace prepare
+{
+/// Pass a number of statement parameters only known at runtime.
+/** When you call any of the @c exec_params functions, the number of arguments
+ * is normally known at compile time. This helper function supports the case
+ * where it is not.
+ *
+ * Use this function to pass a variable number of parameters, based on a
+ * sequence ranging from @c begin to @c end exclusively.
+ *
+ * The technique combines with the regular static parameters. You can use it
+ * to insert dynamic parameter lists in any place, or places, among the call's
+ * parameters. You can even insert multiple dynamic sequences.
+ *
+ * @param begin A pointer or iterator for iterating parameters.
+ * @param end A pointer or iterator for iterating parameters.
+ * @return An object representing the parameters.
+ */
+template<typename IT> inline pqxx::internal::dynamic_params<IT>
+make_dynamic_params(IT begin, IT end)
+{
+ return pqxx::internal::dynamic_params<IT>(begin, end);
+}
+
+
+/// Pass a number of statement parameters only known at runtime.
+/** When you call any of the @c exec_params functions, the number of arguments
+ * is normally known at compile time. This helper function supports the case
+ * where it is not.
+ *
+ * Use this function to pass a variable number of parameters, based on a
+ * container of parameter values.
+ *
+ * The technique combines with the regular static parameters. You can use it
+ * to insert dynamic parameter lists in any place, or places, among the call's
+ * parameters. You can even insert multiple dynamic containers.
+ *
+ * @param container A container of parameter values.
+ * @return An object representing the parameters.
+ */
+template<typename C>
+inline pqxx::internal::dynamic_params<typename C::const_iterator>
+make_dynamic_params(const C &container)
+{
+ return pqxx::internal::dynamic_params<typename C::const_iterator>(container);
+}
+} // namespace prepare
+} // namespace pqxx
+
+namespace pqxx
+{
+namespace prepare
+{
+/// Helper class for passing parameters to, and executing, prepared statements
+/** @deprecated As of 6.0, use @c transaction_base::exec_prepared and friends.
+ */
+class PQXX_LIBEXPORT invocation : internal::statement_parameters
+{
+public:
+ PQXX_DEPRECATED invocation(transaction_base &, const std::string &statement);
+ invocation &operator=(const invocation &) =delete;
+
+ /// Execute!
+ result exec() const;
+
+ /// Execute and return result in binary format
+ result exec_binary() const;
+
+ /// Has a statement of this name been defined?
+ bool exists() const;
+
+ /// Pass null parameter.
+ invocation &operator()() { add_param(); return *this; }
+
+ /// Pass parameter value.
+ /**
+ * @param v parameter value; will be represented as a string internally.
+ */
+ template<typename T> invocation &operator()(const T &v)
+ { add_param(v, true); return *this; }
+
+ /// Pass binary parameter value for a BYTEA field.
+ /**
+ * @param v binary string; will be passed on directly in binary form.
+ */
+ invocation &operator()(const binarystring &v)
+ { add_binary_param(v, true); return *this; }
+
+ /// Pass parameter value.
+ /**
+ * @param v parameter value (will be represented as a string internally).
+ * @param nonnull replaces value with null if set to false.
+ */
+ template<typename T> invocation &operator()(const T &v, bool nonnull)
+ { add_param(v, nonnull); return *this; }
+
+ /// Pass binary parameter value for a BYTEA field.
+ /**
+ * @param v binary string; will be passed on directly in binary form.
+ * @param nonnull determines whether to pass a real value, or nullptr.
+ */
+ invocation &operator()(const binarystring &v, bool nonnull)
+ { add_binary_param(v, nonnull); return *this; }
+
+ /// Pass C-style parameter string, or null if pointer is null.
+ /**
+ * This version is for passing C-style strings; it's a template, so any
+ * pointer type that @c to_string accepts will do.
+ *
+ * @param v parameter value (will be represented as a C++ string internally)
+ * @param nonnull replaces value with null if set to @c false
+ */
+ template<typename T> invocation &operator()(T *v, bool nonnull=true)
+ { add_param(v, nonnull); return *this; }
+
+ /// Pass C-style string parameter, or null if pointer is null.
+ /** This duplicates the pointer-to-template-argument-type version of the
+ * operator, but helps compilers with less advanced template implementations
+ * disambiguate calls where C-style strings are passed.
+ */
+ invocation &operator()(const char *v, bool nonnull=true)
+ { add_param(v, nonnull); return *this; }
+
+private:
+ transaction_base &m_home;
+ const std::string m_statement;
+
+ invocation &setparam(const std::string &, bool nonnull);
+
+ result internal_exec(result_format format) const;
+};
+
+
+namespace internal
+{
+/// Internal representation of a prepared statement definition.
+struct PQXX_LIBEXPORT prepared_def
+{
+ /// Text of prepared query.
+ std::string definition;
+ /// Has this prepared statement been prepared in the current session?
+ bool registered = false;
+
+ prepared_def() =default;
+ explicit prepared_def(const std::string &);
+};
+
+} // namespace pqxx::prepare::internal
+} // namespace pqxx::prepare
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/result b/contrib/libs/libpqxx/include/pqxx/result
new file mode 100644
index 0000000000..d61e588681
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/result
@@ -0,0 +1,11 @@
+/** pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/result.hxx"
+
+// Now include some types which depend on result, but which the user will
+// expect to see defined after including this header.
+#include "pqxx/result_iterator.hxx"
+#include "pqxx/field.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/result.hxx b/contrib/libs/libpqxx/include/pqxx/result.hxx
new file mode 100644
index 0000000000..b1f5ce3f4c
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/result.hxx
@@ -0,0 +1,249 @@
+/** Definitions for the pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
+ *
+ * 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_RESULT
+#define PQXX_H_RESULT
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include <ios>
+#include <memory>
+#include <stdexcept>
+
+#include "pqxx/except.hxx"
+#include "pqxx/types.hxx"
+#include "pqxx/util.hxx"
+
+#include "pqxx/internal/encodings.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+namespace internal
+{
+PQXX_LIBEXPORT void clear_result(const pq::PGresult *);
+
+namespace gate
+{
+class result_connection;
+class result_creation;
+class result_row;
+class result_sql_cursor;
+} // namespace internal::gate
+} // namespace internal
+
+
+enum class result_format
+{
+ text = 0,
+ binary = 1
+};
+
+
+/// Result set containing data returned by a query or command.
+/** This behaves as a container (as defined by the C++ standard library) and
+ * provides random access const iterators to iterate over its rows. A row
+ * can also be accessed by indexing a result R by the row's zero-based
+ * number:
+ *
+ * @code
+ * for (result::size_type i=0; i < R.size(); ++i) Process(R[i]);
+ * @endcode
+ *
+ * Result sets in libpqxx are lightweight, reference-counted wrapper objects
+ * which are relatively small and cheap to copy. Think of a result object as
+ * a "smart pointer" to an underlying result set.
+ *
+ * @warning The result set that a result object points to is not thread-safe.
+ * If you copy a result object, it still refers to the same underlying result
+ * set. So never copy, destroy, query, or otherwise access a result while
+ * another thread may be copying, destroying, querying, or otherwise accessing
+ * the same result set--even if it is doing so through a different result
+ * object!
+ */
+class PQXX_LIBEXPORT result
+{
+public:
+ using size_type = result_size_type;
+ using difference_type = result_difference_type;
+ using reference = row;
+ using const_iterator = const_result_iterator;
+ using pointer = const_iterator;
+ using iterator = const_iterator;
+ using const_reverse_iterator = const_reverse_result_iterator;
+ using reverse_iterator = const_reverse_iterator;
+
+ result() noexcept : //[t03]
+ m_data(make_data_pointer()),
+ m_query(),
+ m_encoding(internal::encoding_group::MONOBYTE)
+ {}
+ result(const result &rhs) noexcept =default; //[t01]
+
+ result &operator=(const result &rhs) noexcept =default; //[t10]
+
+ /**
+ * @name Comparisons
+ */
+ //@{
+ bool operator==(const result &) const noexcept; //[t70]
+ bool operator!=(const result &rhs) const noexcept //[t70]
+ { return not operator==(rhs); }
+ //@}
+
+ const_reverse_iterator rbegin() const; //[t75]
+ const_reverse_iterator crbegin() const;
+ const_reverse_iterator rend() const; //[t75]
+ const_reverse_iterator crend() const;
+
+ const_iterator begin() const noexcept; //[t01]
+ const_iterator cbegin() const noexcept;
+ inline const_iterator end() const noexcept; //[t01]
+ inline const_iterator cend() const noexcept;
+
+ reference front() const noexcept; //[t74]
+ reference back() const noexcept; //[t75]
+
+ PQXX_PURE size_type size() const noexcept; //[t02]
+ PQXX_PURE bool empty() const noexcept; //[t11]
+ size_type capacity() const noexcept { return size(); } //[t20]
+
+ void swap(result &) noexcept; //[t77]
+
+ const row operator[](size_type i) const noexcept; //[t02]
+ const row at(size_type) const; //[t10]
+
+ void clear() noexcept { m_data.reset(); m_query = nullptr; } //[t20]
+
+ /**
+ * @name Column information
+ */
+ //@{
+ /// Number of columns in result.
+ PQXX_PURE row_size_type columns() const noexcept; //[t11]
+
+ /// Number of given column (throws exception if it doesn't exist).
+ row_size_type column_number(const char ColName[]) const; //[t11]
+
+ /// Number of given column (throws exception if it doesn't exist).
+ row_size_type column_number(const std::string &Name) const //[t11]
+ {return column_number(Name.c_str());}
+
+ /// Name of column with this number (throws exception if it doesn't exist)
+ const char *column_name(row_size_type Number) const; //[t11]
+
+ /// Type of given column
+ oid column_type(row_size_type ColNum) const; //[t07]
+ /// Type of given column
+ oid column_type(int ColNum) const //[t07]
+ { return column_type(row_size_type(ColNum)); }
+
+ /// Type of given column
+ oid column_type(const std::string &ColName) const //[t07]
+ { return column_type(column_number(ColName)); }
+
+ /// Type of given column
+ oid column_type(const char ColName[]) const //[t07]
+ { return column_type(column_number(ColName)); }
+
+ /// What table did this column come from?
+ oid column_table(row_size_type ColNum) const; //[t02]
+
+ /// What table did this column come from?
+ oid column_table(int ColNum) const //[t02]
+ { return column_table(row_size_type(ColNum)); }
+
+ /// What table did this column come from?
+ oid column_table(const std::string &ColName) const //[t02]
+ { return column_table(column_number(ColName)); }
+
+ /// What column in its table did this column come from?
+ row_size_type table_column(row_size_type ColNum) const; //[t93]
+
+ /// What column in its table did this column come from?
+ row_size_type table_column(int ColNum) const //[t93]
+ { return table_column(row_size_type(ColNum)); }
+
+ /// What column in its table did this column come from?
+ row_size_type table_column(const std::string &ColName) const //[t93]
+ { return table_column(column_number(ColName)); }
+ //@}
+
+ /// Query that produced this result, if available (empty string otherwise)
+ PQXX_PURE const std::string &query() const noexcept; //[t70]
+
+ /// If command was @c INSERT of 1 row, return oid of inserted row
+ /** @return Identifier of inserted row if exactly one row was inserted, or
+ * oid_none otherwise.
+ */
+ PQXX_PURE oid inserted_oid() const; //[t13]
+
+ /// If command was @c INSERT, @c UPDATE, or @c DELETE: number of affected rows
+ /** @return Number of affected rows if last command was @c INSERT, @c UPDATE,
+ * or @c DELETE; zero for all other commands.
+ */
+ PQXX_PURE size_type affected_rows() const; //[t07]
+
+
+private:
+ using data_pointer = std::shared_ptr<const internal::pq::PGresult>;
+
+ /// Underlying libpq result set.
+ data_pointer m_data;
+
+ /// Factory for data_pointer.
+ static data_pointer make_data_pointer(
+ const internal::pq::PGresult *res=nullptr)
+ { return data_pointer{res, internal::clear_result}; }
+
+ /// Query string.
+ std::shared_ptr<std::string> m_query;
+
+ internal::encoding_group m_encoding;
+
+ static const std::string s_empty_string;
+
+ friend class pqxx::field;
+ PQXX_PURE const char *GetValue(size_type Row, row_size_type Col) const;
+ PQXX_PURE bool get_is_null(size_type Row, row_size_type Col) const;
+ PQXX_PURE field_size_type get_length(
+ size_type,
+ row_size_type) const noexcept;
+
+ friend class pqxx::internal::gate::result_creation;
+ result(
+ internal::pq::PGresult *rhs,
+ const std::string &Query,
+ internal::encoding_group enc);
+
+ PQXX_PRIVATE void check_status() const;
+
+ friend class pqxx::internal::gate::result_connection;
+ friend class pqxx::internal::gate::result_row;
+ bool operator!() const noexcept { return not m_data.get(); }
+ operator bool() const noexcept { return m_data.get() != nullptr; }
+
+ [[noreturn]] PQXX_PRIVATE void ThrowSQLError(
+ const std::string &Err,
+ const std::string &Query) const;
+ PQXX_PRIVATE PQXX_PURE int errorposition() const;
+ PQXX_PRIVATE std::string StatusError() const;
+
+ friend class pqxx::internal::gate::result_sql_cursor;
+ PQXX_PURE const char *cmd_status() const noexcept;
+};
+} // namespace pqxx
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/result_iterator.hxx b/contrib/libs/libpqxx/include/pqxx/result_iterator.hxx
new file mode 100644
index 0000000000..b8e54d23ec
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/result_iterator.hxx
@@ -0,0 +1,245 @@
+/** Definitions for the pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
+ *
+ * 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_RESULT_ITERATOR
+#define PQXX_H_RESULT_ITERATOR
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/row.hxx"
+
+
+/* Result iterator.
+ *
+ * Don't include this header from your own application; it is included for you
+ * by other libpqxx headers.
+ */
+
+namespace pqxx
+{
+/// Iterator for rows in a result. Use as result::const_iterator.
+/** A result, once obtained, cannot be modified. Therefore there is no
+ * plain iterator type for result. However its const_iterator type can be
+ * used to inspect its rows without changing them.
+ */
+class PQXX_LIBEXPORT const_result_iterator : public row
+{
+public:
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = const row;
+ using pointer = const row *;
+ using reference = row;
+ using size_type = result_size_type;
+ using difference_type = result_difference_type;
+
+ const_result_iterator() noexcept : row{result(), 0} {}
+ const_result_iterator(const row &t) noexcept : row{t} {}
+
+ /**
+ * @name Dereferencing operators
+ */
+ //@{
+ /** The iterator "points to" its own row, which is also itself. This
+ * allows a result to be addressed as a two-dimensional container without
+ * going through the intermediate step of dereferencing the iterator. I
+ * hope this works out to be similar to C pointer/array semantics in useful
+ * cases.
+ *
+ * IIRC Alex Stepanov, the inventor of the STL, once remarked that having
+ * this as standard behaviour for pointers would be useful in some
+ * algorithms. So even if this makes me look foolish, I would seem to be in
+ * distinguished company.
+ */
+ pointer operator->() const { return this; } //[t12]
+ reference operator*() const { return row{*this}; } //[t12]
+ //@}
+
+ /**
+ * @name Manipulations
+ */
+ //@{
+ const_result_iterator operator++(int); //[t12]
+ const_result_iterator &operator++() { ++m_index; return *this; } //[t01]
+ const_result_iterator operator--(int); //[t12]
+ const_result_iterator &operator--() { --m_index; return *this; } //[t12]
+
+ const_result_iterator &operator+=(difference_type i) //[t12]
+ { m_index += i; return *this; }
+ const_result_iterator &operator-=(difference_type i) //[t12]
+ { m_index -= i; return *this; }
+ //@}
+
+ /**
+ * @name Comparisons
+ */
+ //@{
+ bool operator==(const const_result_iterator &i) const //[t12]
+ {return m_index==i.m_index;}
+ bool operator!=(const const_result_iterator &i) const //[t12]
+ {return m_index!=i.m_index;}
+ bool operator<(const const_result_iterator &i) const //[t12]
+ {return m_index<i.m_index;}
+ bool operator<=(const const_result_iterator &i) const //[t12]
+ {return m_index<=i.m_index;}
+ bool operator>(const const_result_iterator &i) const //[t12]
+ {return m_index>i.m_index;}
+ bool operator>=(const const_result_iterator &i) const //[t12]
+ {return m_index>=i.m_index;}
+ //@}
+
+ /**
+ * @name Arithmetic operators
+ */
+ //@{
+ inline const_result_iterator operator+(difference_type) const; //[t12]
+ friend const_result_iterator operator+( //[t12]
+ difference_type,
+ const_result_iterator);
+ inline const_result_iterator operator-(difference_type) const; //[t12]
+ inline difference_type operator-(const_result_iterator) const; //[t12]
+ //@}
+
+private:
+ friend class pqxx::result;
+ const_result_iterator(const pqxx::result *r, result_size_type i) noexcept :
+ row{*r, i} {}
+};
+
+
+/// Reverse iterator for result. Use as result::const_reverse_iterator.
+class PQXX_LIBEXPORT const_reverse_result_iterator :
+ private const_result_iterator
+{
+public:
+ using super = const_result_iterator;
+ using iterator_type = const_result_iterator;
+ using iterator_type::iterator_category;
+ using iterator_type::difference_type;
+ using iterator_type::pointer;
+ using value_type = iterator_type::value_type;
+ using reference = iterator_type::reference;
+
+ const_reverse_result_iterator( //[t75]
+ const const_reverse_result_iterator &rhs) :
+ const_result_iterator{rhs} {}
+ explicit const_reverse_result_iterator( //[t75]
+ const const_result_iterator &rhs) :
+ const_result_iterator{rhs} { super::operator--(); }
+
+ PQXX_PURE const_result_iterator base() const noexcept; //[t75]
+
+ /**
+ * @name Dereferencing operators
+ */
+ //@{
+ using const_result_iterator::operator->; //[t75]
+ using const_result_iterator::operator*; //[t75]
+ //@}
+
+ /**
+ * @name Manipulations
+ */
+ //@{
+ const_reverse_result_iterator &operator=( //[t75]
+ const const_reverse_result_iterator &r)
+ { iterator_type::operator=(r); return *this; }
+ const_reverse_result_iterator &operator++() //[t75]
+ { iterator_type::operator--(); return *this; }
+ const_reverse_result_iterator operator++(int); //[t75]
+ const_reverse_result_iterator &operator--() //[t75]
+ { iterator_type::operator++(); return *this; }
+ const_reverse_result_iterator operator--(int); //[t75]
+ const_reverse_result_iterator &operator+=(difference_type i) //[t75]
+ { iterator_type::operator-=(i); return *this; }
+ const_reverse_result_iterator &operator-=(difference_type i) //[t75]
+ { iterator_type::operator+=(i); return *this; }
+ //@}
+
+ /**
+ * @name Arithmetic operators
+ */
+ //@{
+ const_reverse_result_iterator operator+(difference_type i) const //[t75]
+ { return const_reverse_result_iterator(base() - i); }
+ const_reverse_result_iterator operator-(difference_type i) //[t75]
+ { return const_reverse_result_iterator(base() + i); }
+ difference_type operator-( //[t75]
+ const const_reverse_result_iterator &rhs) const
+ { return rhs.const_result_iterator::operator-(*this); }
+ //@}
+
+ /**
+ * @name Comparisons
+ */
+ //@{
+ bool operator==( //[t75]
+ const const_reverse_result_iterator &rhs) const noexcept
+ { return iterator_type::operator==(rhs); }
+ bool operator!=( //[t75]
+ const const_reverse_result_iterator &rhs) const noexcept
+ { return not operator==(rhs); }
+
+ bool operator<(const const_reverse_result_iterator &rhs) const //[t75]
+ { return iterator_type::operator>(rhs); }
+ bool operator<=(const const_reverse_result_iterator &rhs) const //[t75]
+ { return iterator_type::operator>=(rhs); }
+ bool operator>(const const_reverse_result_iterator &rhs) const //[t75]
+ { return iterator_type::operator<(rhs); }
+ bool operator>=(const const_reverse_result_iterator &rhs) const //[t75]
+ { return iterator_type::operator<=(rhs); }
+ //@}
+};
+
+
+inline const_result_iterator
+const_result_iterator::operator+(result::difference_type o) const
+{
+ return const_result_iterator{
+ &m_result, size_type(result::difference_type(m_index) + o)};
+}
+
+inline const_result_iterator
+operator+(result::difference_type o, const_result_iterator i)
+ { return i + o; }
+
+inline const_result_iterator
+const_result_iterator::operator-(result::difference_type o) const
+{
+ return const_result_iterator{
+ &m_result,
+ result_size_type(result::difference_type(m_index) - o)};
+}
+
+inline result::difference_type
+const_result_iterator::operator-(const_result_iterator i) const
+ { return result::difference_type(num() - i.num()); }
+
+inline const_result_iterator result::end() const noexcept
+ { return const_result_iterator{this, size()}; }
+
+
+inline const_result_iterator result::cend() const noexcept
+ { return end(); }
+
+
+inline const_reverse_result_iterator
+operator+(
+ result::difference_type n,
+ const const_reverse_result_iterator &i)
+ { return const_reverse_result_iterator{i.base() - n}; }
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/robusttransaction b/contrib/libs/libpqxx/include/pqxx/robusttransaction
new file mode 100644
index 0000000000..4d8c99fc33
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/robusttransaction
@@ -0,0 +1,6 @@
+/** pqxx::robusttransaction class.
+ *
+ * pqxx::robusttransaction is a slower but safer transaction class.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/robusttransaction.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx b/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
new file mode 100644
index 0000000000..c4c16323b1
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/robusttransaction.hxx
@@ -0,0 +1,168 @@
+/** Definition of the pqxx::robusttransaction class.
+ *
+ * pqxx::robusttransaction is a slower but safer transaction class.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/robusttransaction instead.
+ *
+ * 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_ROBUSTTRANSACTION
+#define PQXX_H_ROBUSTTRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/dbtransaction.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+
+namespace internal
+{
+/// Helper base class for the @c robusttransaction class template.
+class PQXX_LIBEXPORT PQXX_NOVTABLE basic_robusttransaction :
+ public dbtransaction
+{
+public:
+ /// Isolation level is read_committed by default.
+ using isolation_tag = isolation_traits<read_committed>;
+
+ virtual ~basic_robusttransaction() =0; //[t16]
+
+protected:
+ basic_robusttransaction(
+ connection_base &C,
+ const std::string &IsolationLevel,
+ const std::string &table_name=std::string{}); //[t16]
+
+private:
+ using IDType = unsigned long;
+ IDType m_record_id = 0;
+ std::string m_xid;
+ std::string m_log_table;
+ std::string m_sequence;
+ int m_backendpid = -1;
+
+ virtual void do_begin() override; //[t18]
+ virtual void do_commit() override; //[t16]
+ virtual void do_abort() override; //[t18]
+
+ PQXX_PRIVATE void CreateLogTable();
+ PQXX_PRIVATE void CreateTransactionRecord();
+ PQXX_PRIVATE std::string sql_delete() const;
+ PQXX_PRIVATE void DeleteTransactionRecord() noexcept;
+ PQXX_PRIVATE bool CheckTransactionRecord();
+};
+} // namespace internal
+
+
+/**
+ * @ingroup transaction
+ *
+ * @{
+ */
+
+/// Slightly slower, better-fortified version of transaction
+/** robusttransaction is similar to transaction, but spends more effort (and
+ * performance!) to deal with the hopefully rare case that the connection to
+ * the backend is lost just as the current transaction is being committed. In
+ * this case, there is no way to determine whether the backend managed to
+ * commit the transaction before noticing the loss of connection.
+ *
+ * In such cases, this class tries to reconnect to the database and figure out
+ * what happened. It will need to store and manage some information (pretty
+ * much a user-level transaction log) in the back-end for each and every
+ * transaction just on the off chance that this problem might occur.
+ * This service level was made optional since you may not want to pay this
+ * overhead where it is not necessary. Certainly the use of this class makes
+ * no sense for local connections, or for transactions that read the database
+ * but never modify it, or for noncritical database manipulations.
+ *
+ * Besides being slower, it's theoretically possible that robusttransaction
+ * actually fails more instead of less often than a normal transaction. This is
+ * due to the added work and complexity. What robusttransaction tries to
+ * achieve is to be more deterministic, not more successful per se.
+ *
+ * When a user first uses a robusttransaction in a database, the class will
+ * attempt to create a log table there to keep vital transaction-related state
+ * information in. This table, located in that same database, will be called
+ * pqxxlog_*user*, where *user* is the PostgreSQL username for that user. If
+ * the log table can not be created, the transaction fails immediately.
+ *
+ * If the user does not have permission to create the log table, the database
+ * administrator may create one for him beforehand, and give ownership (or at
+ * least full insert/update rights) to the user. The table must contain two
+ * non-unique fields (which will never be null): "name" (of text type,
+ * @c varchar(256) by default) and "date" (of @c timestamp type). Older
+ * versions of robusttransaction also added a unique "id" field; this field is
+ * now obsolete and the log table's implicit oids are used instead. The log
+ * tables' names may be made configurable in a future version of libpqxx.
+ *
+ * The transaction log table contains records describing unfinished
+ * transactions, i.e. ones that have been started but not, as far as the client
+ * knows, committed or aborted. This can mean any of the following:
+ *
+ * <ol>
+ * <li> The transaction is in progress. Since backend transactions can't run
+ * for extended periods of time, this can only be the case if the log record's
+ * timestamp (compared to the server's clock) is not very old, provided of
+ * course that the server's system clock hasn't just made a radical jump.
+ * <li> The client's connection to the server was lost, just when the client was
+ * committing the transaction, and the client so far has not been able to
+ * re-establish the connection to verify whether the transaction was actually
+ * completed or rolled back by the server. This is a serious (and luckily a
+ * rare) condition and requires manual inspection of the database to determine
+ * what happened. The robusttransaction will emit clear and specific warnings
+ * to this effect, and will identify the log record describing the transaction
+ * in question.
+ * <li> The transaction was completed (either by commit or by rollback), but the
+ * client's connection was durably lost just as it tried to clean up the log
+ * record. Again, robusttransaction will emit a clear and specific warning to
+ * tell you about this and request that the record be deleted as soon as
+ * possible.
+ * <li> The client has gone offline at any time while in one of the preceding
+ * states. This also requires manual intervention, but the client obviously is
+ * not able to issue a warning.
+ * </ol>
+ *
+ * It is safe to drop a log table when it is not in use (ie., it is empty or all
+ * records in it represent states 2-4 above). Each robusttransaction will
+ * attempt to recreate the table at its next time of use.
+ */
+template<isolation_level ISOLATIONLEVEL=read_committed>
+class robusttransaction : public internal::basic_robusttransaction
+{
+public:
+ using isolation_tag = isolation_traits<ISOLATIONLEVEL>;
+
+ /// Constructor
+ /** Creates robusttransaction of given name
+ * @param C Connection that this robusttransaction should live inside.
+ * @param Name optional human-readable name for this transaction
+ */
+ explicit robusttransaction(
+ connection_base &C,
+ const std::string &Name=std::string{}) :
+ namedclass{fullname("robusttransaction",isolation_tag::name()), Name},
+ internal::basic_robusttransaction(C, isolation_tag::name())
+ { Begin(); }
+
+ virtual ~robusttransaction() noexcept
+ { End(); }
+};
+
+/**
+ * @}
+ */
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/row.hxx b/contrib/libs/libpqxx/include/pqxx/row.hxx
new file mode 100644
index 0000000000..2d8543795f
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/row.hxx
@@ -0,0 +1,403 @@
+/** Definitions for the pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/result instead.
+ *
+ * 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_ROW
+#define PQXX_H_ROW
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/except.hxx"
+#include "pqxx/field.hxx"
+#include "pqxx/result.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+/// Reference to one row in a result.
+/** A row represents one row (also called a row) in a query result set.
+ * It also acts as a container mapping column numbers or names to field
+ * values (see below):
+ *
+ * @code
+ * cout << row["date"].c_str() << ": " << row["name"].c_str() << endl;
+ * @endcode
+ *
+ * The row itself acts like a (non-modifyable) container, complete with its
+ * own const_iterator and const_reverse_iterator.
+ */
+class PQXX_LIBEXPORT row
+{
+public:
+ using size_type = row_size_type;
+ using difference_type = row_difference_type;
+ using const_iterator = const_row_iterator;
+ using iterator = const_iterator;
+ using reference = field;
+ using pointer = const_row_iterator;
+ using const_reverse_iterator = const_reverse_row_iterator;
+ using reverse_iterator = const_reverse_iterator;
+
+ row() =default;
+
+ /// @deprecated Do not use this constructor. It will become private.
+ row(result r, size_t i) noexcept;
+
+ ~row() noexcept =default; // Yes Scott Meyers, you're absolutely right[1]
+
+ /**
+ * @name Comparison
+ */
+ //@{
+ PQXX_PURE bool operator==(const row &) const noexcept; //[t75]
+ bool operator!=(const row &rhs) const noexcept //[t75]
+ { return not operator==(rhs); }
+ //@}
+
+ const_iterator begin() const noexcept; //[t82]
+ const_iterator cbegin() const noexcept;
+ const_iterator end() const noexcept; //[t82]
+ const_iterator cend() const noexcept;
+
+ /**
+ * @name Field access
+ */
+ //@{
+ reference front() const noexcept; //[t74]
+ reference back() const noexcept; //[t75]
+
+ const_reverse_row_iterator rbegin() const; //[t82]
+ const_reverse_row_iterator crbegin() const;
+ const_reverse_row_iterator rend() const; //[t82]
+ const_reverse_row_iterator crend() const;
+
+ reference operator[](size_type) const noexcept; //[t11]
+ reference operator[](int) const noexcept; //[t02]
+ /** Address field by name.
+ * @warning This is much slower than indexing by number, or iterating.
+ */
+ reference operator[](const char[]) const; //[t11]
+ /** Address field by name.
+ * @warning This is much slower than indexing by number, or iterating.
+ */
+ reference operator[](const std::string &) const; //[t11]
+ reference at(size_type) const; //[t11]
+ reference at(int) const; //[t11]
+ /** Address field by name.
+ * @warning This is much slower than indexing by number, or iterating.
+ */
+ reference at(const char[]) const; //[t11]
+ /** Address field by name.
+ * @warning This is much slower than indexing by number, or iterating.
+ */
+ reference at(const std::string &) const; //[t11]
+ //@}
+
+ size_type size() const noexcept //[t11]
+ { return m_end-m_begin; }
+
+ void swap(row &) noexcept; //[t11]
+
+ /// Row number, assuming this is a real row and not end()/rend().
+ size_t rownumber() const noexcept { return size_t(m_index); } //[t11]
+
+ /**
+ * @name Column information
+ */
+ //@{
+ /// Number of given column (throws exception if it doesn't exist)
+ size_type column_number(const std::string &ColName) const //[t30]
+ { return column_number(ColName.c_str()); }
+
+ /// Number of given column (throws exception if it doesn't exist)
+ size_type column_number(const char[]) const; //[t30]
+
+ /// Type of given column
+ oid column_type(size_type) const; //[t07]
+
+ /// Type of given column
+ oid column_type(int ColNum) const //[t07]
+ { return column_type(size_type(ColNum)); }
+
+ /// Type of given column
+ oid column_type(const std::string &ColName) const //[t07]
+ { return column_type(column_number(ColName)); }
+
+ /// Type of given column
+ oid column_type(const char ColName[]) const //[t07]
+ { return column_type(column_number(ColName)); }
+
+ /// What table did this column come from?
+ oid column_table(size_type ColNum) const; //[t02]
+
+ /// What table did this column come from?
+ oid column_table(int ColNum) const //[t02]
+ { return column_table(size_type(ColNum)); }
+ /// What table did this column come from?
+ oid column_table(const std::string &ColName) const //[t02]
+ { return column_table(column_number(ColName)); }
+
+ /// What column number in its table did this result column come from?
+ /** A meaningful answer can be given only if the column in question comes
+ * directly from a column in a table. If the column is computed in any
+ * other way, a logic_error will be thrown.
+ *
+ * @param ColNum a zero-based column number in this result set
+ * @return a zero-based column number in originating table
+ */
+ size_type table_column(size_type) const; //[t93]
+
+ /// What column number in its table did this result column come from?
+ size_type table_column(int ColNum) const //[t93]
+ { return table_column(size_type(ColNum)); }
+
+ /// What column number in its table did this result column come from?
+ size_type table_column(const std::string &ColName) const //[t93]
+ { return table_column(column_number(ColName)); }
+ //@}
+
+ size_t num() const { return rownumber(); } //[t01]
+
+ /** Produce a slice of this row, containing the given range of columns.
+ *
+ * The slice runs from the range's starting column to the range's end
+ * column, exclusive. It looks just like a normal result row, except
+ * slices can be empty.
+ *
+ * @warning Slicing is a relatively new feature, and not all software may be
+ * prepared to deal with empty slices. If there is any chance that your
+ * program might be creating empty slices and passing them to code that may
+ * not be designed with the possibility of empty rows in mind, be sure to
+ * test for that case.
+ */
+ row slice(size_type Begin, size_type End) const;
+
+ // Is this an empty slice?
+ PQXX_PURE bool empty() const noexcept;
+
+protected:
+ friend class field;
+ /// Result set of which this is one row.
+ result m_result;
+ /// Row number.
+ /**
+ * You'd expect this to be a size_t, but due to the way reverse iterators
+ * are related to regular iterators, it must be allowed to underflow to -1.
+ */
+ long m_index = 0;
+ /// First column in slice. This row ignores lower-numbered columns.
+ size_type m_begin = 0;
+ /// End column in slice. This row only sees lower-numbered columns.
+ size_type m_end = 0;
+};
+
+
+/// Iterator for fields in a row. Use as row::const_iterator.
+class PQXX_LIBEXPORT const_row_iterator : public field
+{
+public:
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = const field;
+ using pointer = const field *;
+ using size_type = row_size_type;
+ using difference_type = row_difference_type;
+ using reference = field;
+
+ const_row_iterator(const row &T, row_size_type C) noexcept : //[t82]
+ field{T, C} {}
+ const_row_iterator(const field &F) noexcept : field{F} {} //[t82]
+
+ /**
+ * @name Dereferencing operators
+ */
+ //@{
+ pointer operator->() const { return this; } //[t82]
+ reference operator*() const { return field{*this}; } //[t82]
+ //@}
+
+ /**
+ * @name Manipulations
+ */
+ //@{
+ const_row_iterator operator++(int); //[t82]
+ const_row_iterator &operator++() { ++m_col; return *this; } //[t82]
+ const_row_iterator operator--(int); //[t82]
+ const_row_iterator &operator--() { --m_col; return *this; } //[t82]
+
+ const_row_iterator &operator+=(difference_type i) //[t82]
+ { m_col = size_type(difference_type(m_col) + i); return *this; }
+ const_row_iterator &operator-=(difference_type i) //[t82]
+ { m_col = size_type(difference_type(m_col) - i); return *this; }
+ //@}
+
+ /**
+ * @name Comparisons
+ */
+ //@{
+ bool operator==(const const_row_iterator &i) const //[t82]
+ {return col()==i.col();}
+ bool operator!=(const const_row_iterator &i) const //[t82]
+ {return col()!=i.col();}
+ bool operator<(const const_row_iterator &i) const //[t82]
+ {return col()<i.col();}
+ bool operator<=(const const_row_iterator &i) const //[t82]
+ {return col()<=i.col();}
+ bool operator>(const const_row_iterator &i) const //[t82]
+ {return col()>i.col();}
+ bool operator>=(const const_row_iterator &i) const //[t82]
+ {return col()>=i.col();}
+ //@}
+
+ /**
+ * @name Arithmetic operators
+ */
+ //@{
+ inline const_row_iterator operator+(difference_type) const; //[t82]
+
+ friend const_row_iterator operator+( //[t82]
+ difference_type,
+ const_row_iterator);
+
+ inline const_row_iterator operator-(difference_type) const; //[t82]
+ inline difference_type operator-(const_row_iterator) const; //[t82]
+ //@}
+};
+
+
+/// Reverse iterator for a row. Use as row::const_reverse_iterator.
+class PQXX_LIBEXPORT const_reverse_row_iterator : private const_row_iterator
+{
+public:
+ using super = const_row_iterator;
+ using iterator_type = const_row_iterator;
+ using iterator_type::iterator_category;
+ using iterator_type::difference_type;
+ using iterator_type::pointer;
+ using value_type = iterator_type::value_type;
+ using reference = iterator_type::reference;
+
+ const_reverse_row_iterator(const const_reverse_row_iterator &r) : //[t82]
+ const_row_iterator{r} {}
+ explicit
+ const_reverse_row_iterator(const super &rhs) noexcept : //[t82]
+ const_row_iterator{rhs} { super::operator--(); }
+
+ PQXX_PURE iterator_type base() const noexcept; //[t82]
+
+ /**
+ * @name Dereferencing operators
+ */
+ //@{
+ using iterator_type::operator->; //[t82]
+ using iterator_type::operator*; //[t82]
+ //@}
+
+ /**
+ * @name Manipulations
+ */
+ //@{
+ const_reverse_row_iterator &
+ operator=(const const_reverse_row_iterator &r) //[t82]
+ { iterator_type::operator=(r); return *this; }
+ const_reverse_row_iterator operator++() //[t82]
+ { iterator_type::operator--(); return *this; }
+ const_reverse_row_iterator operator++(int); //[t82]
+ const_reverse_row_iterator &operator--() //[t82]
+ { iterator_type::operator++(); return *this; }
+ const_reverse_row_iterator operator--(int); //[t82]
+ const_reverse_row_iterator &operator+=(difference_type i) //[t82]
+ { iterator_type::operator-=(i); return *this; }
+ const_reverse_row_iterator &operator-=(difference_type i) //[t82]
+ { iterator_type::operator+=(i); return *this; }
+ //@}
+
+ /**
+ * @name Arithmetic operators
+ */
+ //@{
+ const_reverse_row_iterator operator+(difference_type i) const //[t82]
+ { return const_reverse_row_iterator{base()-i}; }
+ const_reverse_row_iterator operator-(difference_type i) //[t82]
+ { return const_reverse_row_iterator{base()+i}; }
+ difference_type
+ operator-(const const_reverse_row_iterator &rhs) const //[t82]
+ { return rhs.const_row_iterator::operator-(*this); }
+ //@}
+
+ /**
+ * @name Comparisons
+ */
+ //@{
+ bool operator==(const const_reverse_row_iterator &rhs) const noexcept //[t82]
+ { return iterator_type::operator==(rhs); }
+ bool operator!=(const const_reverse_row_iterator &rhs) const noexcept //[t82]
+ { return !operator==(rhs); }
+
+ bool operator<(const const_reverse_row_iterator &rhs) const //[t82]
+ { return iterator_type::operator>(rhs); }
+ bool operator<=(const const_reverse_row_iterator &rhs) const //[t82]
+ { return iterator_type::operator>=(rhs); }
+ bool operator>(const const_reverse_row_iterator &rhs) const //[t82]
+ { return iterator_type::operator<(rhs); }
+ bool operator>=(const const_reverse_row_iterator &rhs) const //[t82]
+ { return iterator_type::operator<=(rhs); }
+ //@}
+};
+
+
+inline const_row_iterator
+const_row_iterator::operator+(difference_type o) const
+{
+ return const_row_iterator{
+ row(home(), idx()),
+ size_type(difference_type(col()) + o)};
+}
+
+inline const_row_iterator
+operator+(const_row_iterator::difference_type o, const_row_iterator i)
+ { return i + o; }
+
+inline const_row_iterator
+const_row_iterator::operator-(difference_type o) const
+{
+ return const_row_iterator{
+ row(home(), idx()),
+ size_type(difference_type(col()) - o)};
+}
+
+inline const_row_iterator::difference_type
+const_row_iterator::operator-(const_row_iterator i) const
+ { return difference_type(num() - i.num()); }
+
+
+} // namespace pqxx
+
+
+/*
+[1] Scott Meyers, in one of his essential books, "Effective C++" and "More
+Effective C++", points out that it is good style to have any class containing
+a member of pointer type define a destructor--just to show that it knows what
+it is doing with the pointer. This helps prevent nasty memory leak / double
+deletion bugs typically resulting from programmers' omission to deal with such
+issues in their destructors.
+
+The @c -Weffc++ option in gcc generates warnings for noncompliance with Scott's
+style guidelines, and hence necessitates the definition of this destructor,
+trivial as it may be.
+*/
+
+
+#include "pqxx/compiler-internal-post.hxx"
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/strconv b/contrib/libs/libpqxx/include/pqxx/strconv
new file mode 100644
index 0000000000..b70bf39bf4
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/strconv
@@ -0,0 +1,4 @@
+/** String conversion definitions.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/strconv.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/strconv.hxx b/contrib/libs/libpqxx/include/pqxx/strconv.hxx
new file mode 100644
index 0000000000..0cb120d876
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/strconv.hxx
@@ -0,0 +1,341 @@
+/** String conversion definitions.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stringconv instead.
+ *
+ * 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_STRINGCONV
+#define PQXX_H_STRINGCONV
+
+#include "pqxx/compiler-public.hxx"
+
+#include <limits>
+#include <sstream>
+#include <stdexcept>
+
+
+namespace pqxx
+{
+
+/**
+ * @defgroup stringconversion String conversion
+ *
+ * The PostgreSQL server accepts and represents data in string form. It has
+ * its own formats for various data types. The string conversions define how
+ * various C++ types translate to and from their respective PostgreSQL text
+ * representations.
+ *
+ * Each conversion is defined by a specialisation of the @c string_traits
+ * template. This template implements some basic functions to support the
+ * conversion, ideally in both directions.
+ *
+ * If you need to convert a type which is not supported out of the box, define
+ * your own @c string_traits specialisation for that type, similar to the ones
+ * defined here. Any conversion code which "sees" your specialisation will now
+ * support your conversion. In particular, you'll be able to read result
+ * fields into a variable of the new type.
+ *
+ * There is a macro to help you define conversions for individual enumeration
+ * types. The conversion will represent enumeration values as numeric strings.
+ */
+//@{
+
+/// Traits class for use in string conversions
+/** Specialize this template for a type that you wish to add to_string and
+ * from_string support for.
+ */
+template<typename T, typename = void> struct string_traits;
+
+namespace internal
+{
+/// Throw exception for attempt to convert null to given type.
+[[noreturn]] PQXX_LIBEXPORT void throw_null_conversion(
+ const std::string &type);
+
+/// Give a human-readable name for a type, at compile time.
+/** Each instantiation contains a static member called @c value which is the
+ * type's name, as a string.
+ *
+ * This template should not be around for long. C++14's variable templates
+ * make it easier (eliminating the cumbersome struct) and C++20's introspection
+ * should obviate it completely.
+ */
+template<typename TYPE> struct type_name;
+#define PQXX_DECLARE_TYPE_NAME(TYPE) \
+ template<> struct type_name<TYPE> \
+ { static constexpr const char *value = #TYPE; }
+
+PQXX_DECLARE_TYPE_NAME(bool);
+PQXX_DECLARE_TYPE_NAME(short);
+PQXX_DECLARE_TYPE_NAME(unsigned short);
+PQXX_DECLARE_TYPE_NAME(int);
+PQXX_DECLARE_TYPE_NAME(unsigned int);
+PQXX_DECLARE_TYPE_NAME(long);
+PQXX_DECLARE_TYPE_NAME(unsigned long);
+PQXX_DECLARE_TYPE_NAME(long long);
+PQXX_DECLARE_TYPE_NAME(unsigned long long);
+PQXX_DECLARE_TYPE_NAME(float);
+PQXX_DECLARE_TYPE_NAME(double);
+PQXX_DECLARE_TYPE_NAME(long double);
+PQXX_DECLARE_TYPE_NAME(char *);
+PQXX_DECLARE_TYPE_NAME(const char *);
+PQXX_DECLARE_TYPE_NAME(std::string);
+PQXX_DECLARE_TYPE_NAME(const std::string);
+PQXX_DECLARE_TYPE_NAME(std::stringstream);
+#undef PQXX_DECLARE_TYPE_NAME
+
+template<size_t N> struct type_name<char[N]>
+{ static constexpr const char *value = "char[]"; };
+
+
+/// Helper: string traits implementation for built-in types.
+/** These types all look much alike, so they can share much of their traits
+ * classes (though templatised, of course).
+ *
+ * The actual `to_string` and `from_string` are implemented in the library,
+ * but the rest is defined inline.
+ */
+template<typename TYPE> struct PQXX_LIBEXPORT builtin_traits
+{
+ static constexpr const char *name() noexcept
+ { return internal::type_name<TYPE>::value; }
+ static constexpr bool has_null() noexcept { return false; }
+ static bool is_null(TYPE) { return false; }
+ [[noreturn]] static TYPE null() { throw_null_conversion(name()); }
+ static void from_string(const char Str[], TYPE &Obj);
+ static std::string to_string(TYPE Obj);
+};
+} // namespace pqxx::internal
+
+
+/// Helper: declare a string_traits specialisation for a builtin type.
+#define PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(TYPE) \
+ template<> struct PQXX_LIBEXPORT string_traits<TYPE> : \
+ internal::builtin_traits<TYPE> {};
+
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(bool)
+
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(short)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned short)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(int)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned int)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long long)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(unsigned long long)
+
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(float)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(double)
+PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION(long double)
+
+#undef PQXX_DECLARE_STRING_TRAITS_SPECIALIZATION
+
+
+/// Helper class for defining enum conversions.
+/** The conversion will convert enum values to numeric strings, and vice versa.
+ *
+ * To define a string conversion for an enum type, derive a @c string_traits
+ * specialisation for the enum from this struct.
+ *
+ * There's usually an easier way though: the @c PQXX_DECLARE_ENUM_CONVERSION
+ * macro. Use @c enum_traits manually only if you need to customise your
+ * traits type in more detail, e.g. if your enum has a "null" value built in.
+ */
+template<typename ENUM>
+struct enum_traits
+{
+ using underlying_type = typename std::underlying_type<ENUM>::type;
+ using underlying_traits = string_traits<underlying_type>;
+
+ static constexpr bool has_null() noexcept { return false; }
+ [[noreturn]] static ENUM null()
+ { internal::throw_null_conversion("enum type"); }
+
+ static void from_string(const char Str[], ENUM &Obj)
+ {
+ underlying_type tmp;
+ underlying_traits::from_string(Str, tmp);
+ Obj = ENUM(tmp);
+ }
+
+ static std::string to_string(ENUM Obj)
+ { return underlying_traits::to_string(underlying_type(Obj)); }
+};
+
+
+/// Macro: Define a string conversion for an enum type.
+/** This specialises the @c pqxx::string_traits template, so use it in the
+ * @c ::pqxx namespace.
+ *
+ * For example:
+ *
+ * #include <iostream>
+ * #include <pqxx/strconv>
+ * enum X { xa, xb };
+ * namespace pqxx { PQXX_DECLARE_ENUM_CONVERSION(x); }
+ * int main() { std::cout << to_string(xa) << std::endl; }
+ */
+#define PQXX_DECLARE_ENUM_CONVERSION(ENUM) \
+template<> \
+struct string_traits<ENUM> : pqxx::enum_traits<ENUM> \
+{ \
+ static constexpr const char *name() noexcept { return #ENUM; } \
+ [[noreturn]] static ENUM null() \
+ { internal::throw_null_conversion(name()); } \
+}
+
+
+/// String traits for C-style string ("pointer to const char")
+template<> struct PQXX_LIBEXPORT string_traits<const char *>
+{
+ static constexpr const char *name() noexcept { return "const char *"; }
+ static constexpr bool has_null() noexcept { return true; }
+ static bool is_null(const char *t) { return t == nullptr; }
+ static const char *null() { return nullptr; }
+ static void from_string(const char Str[], const char *&Obj) { Obj = Str; }
+ static std::string to_string(const char *Obj) { return Obj; }
+};
+
+/// String traits for non-const C-style string ("pointer to char")
+template<> struct PQXX_LIBEXPORT string_traits<char *>
+{
+ static constexpr const char *name() noexcept { return "char *"; }
+ static constexpr bool has_null() noexcept { return true; }
+ static bool is_null(const char *t) { return t == nullptr; }
+ static const char *null() { return nullptr; }
+
+ // Don't allow this conversion since it breaks const-safety.
+ // static void from_string(const char Str[], char *&Obj);
+
+ static std::string to_string(char *Obj) { return Obj; }
+};
+
+/// String traits for C-style string constant ("array of char")
+template<size_t N> struct PQXX_LIBEXPORT string_traits<char[N]>
+{
+ static constexpr const char *name() noexcept { return "char[]"; }
+ static constexpr bool has_null() noexcept { return true; }
+ static bool is_null(const char t[]) { return t == nullptr; }
+ static const char *null() { return nullptr; }
+ static std::string to_string(const char Obj[]) { return Obj; }
+};
+
+template<> struct PQXX_LIBEXPORT string_traits<std::string>
+{
+ static constexpr const char *name() noexcept { return "string"; }
+ static constexpr bool has_null() noexcept { return false; }
+ static bool is_null(const std::string &) { return false; }
+ [[noreturn]] static std::string null()
+ { internal::throw_null_conversion(name()); }
+ static void from_string(const char Str[], std::string &Obj) { Obj=Str; }
+ static std::string to_string(const std::string &Obj) { return Obj; }
+};
+
+template<> struct PQXX_LIBEXPORT string_traits<const std::string>
+{
+ static constexpr const char *name() noexcept { return "const string"; }
+ static constexpr bool has_null() noexcept { return false; }
+ static bool is_null(const std::string &) { return false; }
+ [[noreturn]] static const std::string null()
+ { internal::throw_null_conversion(name()); }
+ static const std::string to_string(const std::string &Obj) { return Obj; }
+};
+
+template<> struct PQXX_LIBEXPORT string_traits<std::stringstream>
+{
+ static constexpr const char *name() noexcept { return "stringstream"; }
+ static constexpr bool has_null() noexcept { return false; }
+ static bool is_null(const std::stringstream &) { return false; }
+ [[noreturn]] static std::stringstream null()
+ { internal::throw_null_conversion(name()); }
+ static void from_string(const char Str[], std::stringstream &Obj)
+ { Obj.clear(); Obj << Str; }
+ static std::string to_string(const std::stringstream &Obj)
+ { return Obj.str(); }
+};
+
+
+// TODO: Implement date conversions.
+
+/// Attempt to convert postgres-generated string to given built-in type
+/** If the form of the value found in the string does not match the expected
+ * type, e.g. if a decimal point is found when converting to an integer type,
+ * the conversion fails. Overflows (e.g. converting "9999999999" to a 16-bit
+ * C++ type) are also treated as errors. If in some cases this behaviour should
+ * be inappropriate, convert to something bigger such as @c long @c int first
+ * and then truncate the resulting value.
+ *
+ * Only the simplest possible conversions are supported. No fancy features
+ * such as hexadecimal or octal, spurious signs, or exponent notation will work.
+ * No whitespace is stripped away. Only the kinds of strings that come out of
+ * PostgreSQL and out of to_string() can be converted.
+ */
+template<typename T>
+ inline void from_string(const char Str[], T &Obj)
+{
+ if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
+ string_traits<T>::from_string(Str, Obj);
+}
+
+
+/// Conversion with known string length (for strings that may contain nuls)
+/** This is only used for strings, where embedded nul bytes should not determine
+ * the end of the string.
+ *
+ * For all other types, this just uses the regular, nul-terminated version of
+ * from_string().
+ */
+template<typename T> inline void from_string(const char Str[], T &Obj, size_t)
+{
+ return from_string(Str, Obj);
+}
+
+template<>
+ inline void from_string<std::string>( //[t00]
+ const char Str[],
+ std::string &Obj,
+ size_t len)
+{
+ if (Str == nullptr) throw std::runtime_error{"Attempt to read null string."};
+ Obj.assign(Str, len);
+}
+
+template<typename T>
+ inline void from_string(const std::string &Str, T &Obj) //[t45]
+ { from_string(Str.c_str(), Obj); }
+
+template<typename T>
+ inline void from_string(const std::stringstream &Str, T &Obj) //[t00]
+ { from_string(Str.str(), Obj); }
+
+template<> inline void
+from_string(const std::string &Str, std::string &Obj) //[t46]
+ { Obj = Str; }
+
+
+namespace internal
+{
+/// Compute numeric value of given textual digit (assuming that it is a digit)
+constexpr int digit_to_number(char c) noexcept { return c-'0'; }
+constexpr char number_to_digit(int i) noexcept
+ { return static_cast<char>(i+'0'); }
+} // namespace pqxx::internal
+
+
+/// Convert built-in type to a readable string that PostgreSQL will understand
+/** No special formatting is done, and any locale settings are ignored. The
+ * resulting string will be human-readable and in a format suitable for use in
+ * SQL queries.
+ */
+template<typename T> inline std::string to_string(const T &Obj)
+ { return string_traits<T>::to_string(Obj); }
+
+//@}
+
+} // namespace pqxx
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/stream_base.hxx b/contrib/libs/libpqxx/include/pqxx/stream_base.hxx
new file mode 100644
index 0000000000..d4af37fb07
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/stream_base.hxx
@@ -0,0 +1,62 @@
+/** Definition of the pqxx::stream_base class.
+ *
+ * pqxx::stream_base provides optimized batch access to a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_base instead.
+ *
+ * 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_STREAM_BASE
+#define PQXX_H_STREAM_BASE
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/transaction_base.hxx"
+#include "pqxx/util.hxx"
+
+#include <string>
+
+
+namespace pqxx
+{
+
+class PQXX_LIBEXPORT PQXX_NOVTABLE stream_base :
+ public internal::transactionfocus
+{
+public:
+ explicit stream_base(transaction_base &);
+ // TODO: Can we get rid of the vtable?
+ virtual ~stream_base() noexcept =default;
+ virtual void complete() = 0;
+ operator bool() const noexcept;
+ bool operator!() const noexcept;
+protected:
+ bool m_finished;
+ virtual void close();
+ template<typename C> static std::string columnlist(const C &);
+ template<typename I> static std::string columnlist(I begin, I end);
+private:
+ stream_base();
+ stream_base(const stream_base&);
+ stream_base & operator=(const stream_base &);
+};
+
+template<typename C> std::string stream_base::columnlist(const C &c)
+{
+ return columnlist(std::begin(c), std::end(c));
+}
+
+template<typename I> std::string stream_base::columnlist(I begin, I end)
+{
+ return separated_list(",", begin, end);
+}
+
+} // namespace pqxx
+
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/stream_from b/contrib/libs/libpqxx/include/pqxx/stream_from
new file mode 100644
index 0000000000..71dbb7dfe7
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/stream_from
@@ -0,0 +1,6 @@
+/** pqxx::stream_from class.
+ *
+ * pqxx::stream_from enables optimized batch reads from a database table.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/stream_from.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/stream_from.hxx b/contrib/libs/libpqxx/include/pqxx/stream_from.hxx
new file mode 100644
index 0000000000..bc6bcc7231
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/stream_from.hxx
@@ -0,0 +1,210 @@
+/** Definition of the pqxx::stream_from class.
+ *
+ * pqxx::stream_from enables optimized batch reads from a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead.
+ *
+ * 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_STREAM_FROM
+#define PQXX_H_STREAM_FROM
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/transaction_base.hxx"
+#include "pqxx/stream_base.hxx"
+#include "pqxx/internal/type_utils.hxx"
+
+#include <string>
+
+
+namespace pqxx
+{
+
+/// Efficiently pull data directly out of a table.
+class PQXX_LIBEXPORT stream_from : public stream_base
+{
+public:
+ stream_from(
+ transaction_base &,
+ const std::string &table_name
+ );
+ template<typename Columns> stream_from(
+ transaction_base &,
+ const std::string &table_name,
+ const Columns& columns
+ );
+ template<typename Iter> stream_from(
+ transaction_base &,
+ const std::string &table_name,
+ Iter columns_begin,
+ Iter columns_end
+ );
+
+ ~stream_from() noexcept;
+
+ void complete() override;
+
+ bool get_raw_line(std::string &);
+ template<typename Tuple> stream_from & operator>>(Tuple &);
+
+private:
+ internal::encoding_group m_copy_encoding;
+ std::string m_current_line;
+ bool m_retry_line;
+
+ void set_up(transaction_base &, const std::string &table_name);
+ void set_up(
+ transaction_base &,
+ const std::string &table_name,
+ const std::string &columns
+ );
+
+ void close() override;
+
+ bool extract_field(
+ const std::string &,
+ std::string::size_type &,
+ std::string &
+ ) const;
+
+ template<typename Tuple, std::size_t I> auto tokenize_ith(
+ const std::string &,
+ Tuple &,
+ std::string::size_type,
+ std::string &
+ ) const -> typename std::enable_if<(
+ std::tuple_size<Tuple>::value > I
+ )>::type;
+ template<typename Tuple, std::size_t I> auto tokenize_ith(
+ const std::string &,
+ Tuple &,
+ std::string::size_type,
+ std::string &
+ ) const -> typename std::enable_if<(
+ std::tuple_size<Tuple>::value <= I
+ )>::type;
+
+ template<typename T> void extract_value(
+ const std::string &line,
+ T& t,
+ std::string::size_type &here,
+ std::string &workspace
+ ) const;
+};
+
+
+template<typename Columns> stream_from::stream_from(
+ transaction_base &tb,
+ const std::string &table_name,
+ const Columns& columns
+) : stream_from{
+ tb,
+ table_name,
+ std::begin(columns),
+ std::end(columns)
+} {}
+
+
+template<typename Iter> stream_from::stream_from(
+ transaction_base &tb,
+ const std::string &table_name,
+ Iter columns_begin,
+ Iter columns_end
+) :
+ namedclass{"stream_from", table_name},
+ stream_base{tb}
+{
+ set_up(
+ tb,
+ table_name,
+ columnlist(columns_begin, columns_end)
+ );
+}
+
+
+template<typename Tuple> stream_from & stream_from::operator>>(
+ Tuple &t
+)
+{
+ if (m_retry_line or get_raw_line(m_current_line))
+ {
+ std::string workspace;
+ try
+ {
+ tokenize_ith<Tuple, 0>(m_current_line, t, 0, workspace);
+ m_retry_line = false;
+ }
+ catch (...)
+ {
+ m_retry_line = true;
+ throw;
+ }
+ }
+ return *this;
+}
+
+
+template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
+ const std::string &line,
+ Tuple &t,
+ std::string::size_type here,
+ std::string &workspace
+) const -> typename std::enable_if<(
+ std::tuple_size<Tuple>::value > I
+)>::type
+{
+ if (here >= line.size())
+ throw usage_error{"Too few fields to extract from stream_from line."};
+
+ extract_value(line, std::get<I>(t), here, workspace);
+ tokenize_ith<Tuple, I+1>(line, t, here, workspace);
+}
+
+
+template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
+ const std::string &line,
+ Tuple & /* t */,
+ std::string::size_type here,
+ std::string & /* workspace */
+) const -> typename std::enable_if<(
+ std::tuple_size<Tuple>::value <= I
+)>::type
+{
+ // Zero-column line may still have a trailing newline
+ if (
+ here < line.size() and
+ not (here == line.size() - 1 and line[here] == '\n'))
+ throw usage_error{"Not all fields extracted from stream_from line"};
+}
+
+
+template<typename T> void stream_from::extract_value(
+ const std::string &line,
+ T& t,
+ std::string::size_type &here,
+ std::string &workspace
+) const
+{
+ if (extract_field(line, here, workspace))
+ from_string<T>(workspace, t);
+ else
+ t = internal::null_value<T>();
+}
+
+template<> void stream_from::extract_value<std::nullptr_t>(
+ const std::string &line,
+ std::nullptr_t&,
+ std::string::size_type &here,
+ std::string &workspace
+) const;
+
+} // namespace pqxx
+
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/stream_to b/contrib/libs/libpqxx/include/pqxx/stream_to
new file mode 100644
index 0000000000..a5100969d0
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/stream_to
@@ -0,0 +1,6 @@
+/** pqxx::stream_to class.
+ *
+ * pqxx::stream_to enables optimized batch updates to a database table.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/stream_to.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/stream_to.hxx b/contrib/libs/libpqxx/include/pqxx/stream_to.hxx
new file mode 100644
index 0000000000..cf23f980f5
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/stream_to.hxx
@@ -0,0 +1,192 @@
+/** Definition of the pqxx::stream_to class.
+ *
+ * pqxx::stream_to enables optimized batch updates to a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_to.hxx instead.
+ *
+ * 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_STREAM_TO
+#define PQXX_H_STREAM_TO
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/transaction_base.hxx"
+#include "pqxx/stream_base.hxx"
+#include "pqxx/stream_from.hxx"
+#include "pqxx/internal/type_utils.hxx"
+
+#include <string>
+
+
+namespace pqxx
+{
+
+/// Efficiently write data directly to a database table.
+/** If you wish to insert rows of data into a table, you can compose INSERT
+ * statements and execute them. But it's slow and tedious, and you need to
+ * worry about quoting and escaping the data.
+ *
+ * If you're just inserting a single row, it probably won't matter much. You
+ * can use prepared or parameterised statements to take care of the escaping
+ * for you. But if you're inserting large numbers of rows you will want
+ * something better.
+ *
+ * Inserting rows one by one tends to take a lot of time, especially when you
+ * are working with a remote database server over the network. Every single
+ * row involves sending the data over the network, and waiting for a reply.
+ * Do it "in bulk" using @c stream_to, and you may find that it goes many times
+ * faster, sometimes even by orders of magnitude.
+ *
+ * Here's how it works: you create a @c stream_to stream to start writing to
+ * your table. You will probably want to specify the columns. Then, you
+ * feed your data into the stream one row at a time. And finally, you call the
+ * stream's @c complete() to tell it to finalise the operation, wait for
+ * completion, and check for errors.
+ *
+ * You insert data using the @c << ("shift-left") operator. Each row must be
+ * something that can be iterated in order to get its constituent fields: a
+ * @c std::tuple, a @c std::vector, or anything else with a @c begin and
+ * @c end. It could be a class of your own. Of course the fields have to
+ * match the columns you specified when creating the stream.
+ *
+ * There is also a matching stream_from for reading data in bulk.
+ */
+class PQXX_LIBEXPORT stream_to : public stream_base
+{
+public:
+ /// Create a stream, without specifying columns.
+ /** Fields will be inserted in whatever order the columns have in the
+ * database.
+ *
+ * You'll probably want to specify the columns, so that the mapping between
+ * your data fields and the table is explicit in your code, and not hidden
+ * in an "implicit contract" between your code and your schema.
+ */
+ stream_to(transaction_base &, const std::string &table_name);
+
+ /// Create a stream, specifying column names as a container of strings.
+ template<typename Columns> stream_to(
+ transaction_base &,
+ const std::string &table_name,
+ const Columns& columns
+ );
+
+ /// Create a stream, specifying column names as a sequence of strings.
+ template<typename Iter> stream_to(
+ transaction_base &,
+ const std::string &table_name,
+ Iter columns_begin,
+ Iter columns_end
+ );
+
+ ~stream_to() noexcept;
+
+ /// Complete the operation, and check for errors.
+ /** Always call this to close the stream in an orderly fashion, even after
+ * an error. (In the case of an error, abort the transaction afterwards.)
+ *
+ * The only circumstance where it's safe to skip this is after an error, if
+ * you're discarding the entire connection right away.
+ */
+ void complete() override;
+
+ /// Insert a row of data.
+ /** The data can be any type that can be iterated. Each iterated item
+ * becomes a field in the row, in the same order as the columns you
+ * specified when creating the stream.
+ *
+ * Each field will be converted into the database's format using
+ * @c pqxx::to_string.
+ */
+ template<typename Tuple> stream_to & operator<<(const Tuple &);
+
+ /// Stream a `stream_from` straight into a `stream_to`.
+ /** This can be useful when copying between different databases. If the
+ * source and the destination are on the same database, you'll get better
+ * performance doing it all in a regular query.
+ */
+ stream_to &operator<<(stream_from &);
+
+private:
+ /// Write a row of data, as a line of text.
+ void write_raw_line(const std::string &);
+
+ void set_up(transaction_base &, const std::string &table_name);
+ void set_up(
+ transaction_base &,
+ const std::string &table_name,
+ const std::string &columns
+ );
+
+ void close() override;
+};
+
+
+template<typename Columns> inline stream_to::stream_to(
+ transaction_base &tb,
+ const std::string &table_name,
+ const Columns& columns
+) : stream_to{
+ tb,
+ table_name,
+ std::begin(columns),
+ std::end(columns)
+}
+{}
+
+
+template<typename Iter> inline stream_to::stream_to(
+ transaction_base &tb,
+ const std::string &table_name,
+ Iter columns_begin,
+ Iter columns_end
+) :
+ namedclass{"stream_from", table_name},
+ stream_base{tb}
+{
+ set_up(
+ tb,
+ table_name,
+ columnlist(columns_begin, columns_end)
+ );
+}
+
+
+namespace internal
+{
+
+class PQXX_LIBEXPORT TypedCopyEscaper
+{
+ static std::string escape(const std::string &);
+public:
+ template<typename T> std::string operator()(const T* t) const
+ {
+ return string_traits<T>::is_null(*t) ? "\\N" : escape(to_string(*t));
+ }
+};
+
+// Explicit specialization so we don't need a string_traits<> for nullptr_t
+template<> inline std::string TypedCopyEscaper::operator()<std::nullptr_t>(
+ const std::nullptr_t*
+) const
+{ return "\\N"; }
+
+} // namespace pqxx::internal
+
+
+template<typename Tuple> stream_to & stream_to::operator<<(const Tuple &t)
+{
+ write_raw_line(separated_list("\t", t, internal::TypedCopyEscaper()));
+ return *this;
+}
+
+} // namespace pqxx
+
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/subtransaction b/contrib/libs/libpqxx/include/pqxx/subtransaction
new file mode 100644
index 0000000000..364ccab3fc
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/subtransaction
@@ -0,0 +1,6 @@
+/** pqxx::subtransaction class.
+ *
+ * pqxx::subtransaction is a nested transaction, i.e. one inside a transaction.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/subtransaction.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/subtransaction.hxx b/contrib/libs/libpqxx/include/pqxx/subtransaction.hxx
new file mode 100644
index 0000000000..2b353e63db
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/subtransaction.hxx
@@ -0,0 +1,105 @@
+/** Definition of the pqxx::subtransaction class.
+ *
+ * pqxx::subtransaction is a nested transaction, i.e. one within a transaction.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/subtransaction instead.
+ *
+ * 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_SUBTRANSACTION
+#define PQXX_H_SUBTRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/dbtransaction.hxx"
+
+
+/* Methods tested in eg. self-test program test1 are marked with "//[t01]"
+ */
+
+
+namespace pqxx
+{
+
+/**
+ * @ingroup transaction
+ */
+/// "Transaction" nested within another transaction
+/** A subtransaction can be executed inside a backend transaction, or inside
+ * another subtransaction. This can be useful when, for example, statements in
+ * a transaction may harmlessly fail and you don't want them to abort the entire
+ * transaction. Here's an example of how a temporary table may be dropped
+ * before re-creating it, without failing if the table did not exist:
+ *
+ * @code
+ * void do_job(connection_base &C)
+ * {
+ * const string temptable = "fleetingtable";
+ *
+ * // Since we're dealing with a temporary table here, disallow automatic
+ * // recovery of the connection in case it breaks.
+ * C.inhibit_reactivation(true);
+ *
+ * work W(C, "do_job");
+ * do_firstpart(W);
+ *
+ * // Attempt to delete our temporary table if it already existed
+ * try
+ * {
+ * subtransaction S(W, "droptemp");
+ * S.exec0("DROP TABLE " + temptable);
+ * S.commit();
+ * }
+ * catch (const undefined_table &)
+ * {
+ * // Table did not exist. Which is what we were hoping to achieve anyway.
+ * // Carry on without regrets.
+ * }
+ *
+ * // S may have gone into a failed state and been destroyed, but the
+ * // upper-level transaction W is still fine. We can continue to use it.
+ * W.exec("CREATE TEMP TABLE " + temptable + "(bar integer, splat varchar)");
+ *
+ * do_lastpart(W);
+ * }
+ * @endcode
+ *
+ * (This is just an example. If you really wanted to do drop a table without an
+ * error if it doesn't exist, you'd use DROP TABLE IF EXISTS.)
+ *
+ * There are no isolation levels inside a transaction. They are not needed
+ * because all actions within the same backend transaction are always performed
+ * sequentially anyway.
+ */
+class PQXX_LIBEXPORT subtransaction :
+ public internal::transactionfocus,
+ public dbtransaction
+{
+public:
+ /// Nest a subtransaction nested in another transaction.
+ explicit subtransaction( //[t88]
+ dbtransaction &T, const std::string &Name=std::string{});
+
+ /// Nest a subtransaction in another subtransaction.
+ explicit subtransaction(
+ subtransaction &T, const std::string &Name=std::string{});
+
+ virtual ~subtransaction() noexcept
+ { End(); }
+
+private:
+ virtual void do_begin() override; //[t88]
+ virtual void do_commit() override; //[t88]
+ virtual void do_abort() override; //[t88]
+
+ dbtransaction &m_parent;
+};
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/tablereader b/contrib/libs/libpqxx/include/pqxx/tablereader
new file mode 100644
index 0000000000..daa5ec93e8
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablereader
@@ -0,0 +1,6 @@
+/** pqxx::tablereader class.
+ *
+ * pqxx::tablereader enables optimized batch reads from a database table.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/tablereader.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/tablereader.hxx b/contrib/libs/libpqxx/include/pqxx/tablereader.hxx
new file mode 100644
index 0000000000..f5300cbeb0
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablereader.hxx
@@ -0,0 +1,118 @@
+/** Definition of the pqxx::tablereader class.
+ *
+ * pqxx::tablereader enables optimized batch reads from a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/tablereader instead.
+ *
+ * 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_TABLEREADER
+#define PQXX_H_TABLEREADER
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/result.hxx"
+#include "pqxx/tablestream.hxx"
+
+
+namespace pqxx
+{
+/// @deprecated Use stream_from instead.
+/** Efficiently pull data directly out of a table.
+ * @warning This class does not work reliably with multibyte encodings. Using
+ * it with some multi-byte encodings may pose a security risk.
+ */
+class PQXX_LIBEXPORT tablereader : public tablestream
+{
+public:
+ PQXX_DEPRECATED tablereader(
+ transaction_base &,
+ const std::string &Name,
+ const std::string &Null=std::string{});
+ template<typename ITER>
+ PQXX_DEPRECATED tablereader(
+ transaction_base &,
+ const std::string &Name,
+ ITER begincolumns,
+ ITER endcolumns);
+ template<typename ITER>
+ PQXX_DEPRECATED tablereader(
+ transaction_base &,
+ const std::string &Name,
+ ITER begincolumns,
+ ITER endcolumns,
+ const std::string &Null);
+ ~tablereader() noexcept;
+ template<typename TUPLE> tablereader &operator>>(TUPLE &);
+ operator bool() const noexcept { return not m_done; }
+ bool operator!() const noexcept { return m_done; }
+ bool get_raw_line(std::string &Line);
+ template<typename TUPLE>
+ void tokenize(std::string, TUPLE &) const;
+ virtual void complete() override;
+private:
+ void set_up(
+ transaction_base &T,
+ const std::string &RName,
+ const std::string &Columns=std::string{});
+ PQXX_PRIVATE void reader_close();
+ std::string extract_field(
+ const std::string &,
+ std::string::size_type &) const;
+ bool m_done;
+};
+
+
+template<typename ITER> inline
+tablereader::tablereader(
+ transaction_base &T,
+ const std::string &Name,
+ ITER begincolumns,
+ ITER endcolumns) :
+ namedclass{Name, "tablereader"},
+ tablestream{T, std::string{}},
+ m_done{true}
+{
+ set_up(T, Name, columnlist(begincolumns, endcolumns));
+}
+
+
+template<typename ITER> inline
+tablereader::tablereader(
+ transaction_base &T,
+ const std::string &Name,
+ ITER begincolumns,
+ ITER endcolumns,
+ const std::string &Null) :
+ namedclass{Name, "tablereader"},
+ tablestream{T, Null},
+ m_done{true}
+{
+ set_up(T, Name, columnlist(begincolumns, endcolumns));
+}
+
+
+template<typename TUPLE>
+inline void tablereader::tokenize(std::string Line, TUPLE &T) const
+{
+ std::back_insert_iterator<TUPLE> ins = std::back_inserter(T);
+ std::string::size_type here = 0;
+ while (here < Line.size()) *ins++ = extract_field(Line, here);
+}
+
+
+template<typename TUPLE>
+inline tablereader &pqxx::tablereader::operator>>(TUPLE &T)
+{
+ std::string Line;
+ if (get_raw_line(Line)) tokenize(Line, T);
+ return *this;
+}
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/tablestream b/contrib/libs/libpqxx/include/pqxx/tablestream
new file mode 100644
index 0000000000..57d700e800
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablestream
@@ -0,0 +1,6 @@
+/** pqxx::tablestream class.
+ *
+ * pqxx::tablestream provides optimized batch access to a database table.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/tablestream.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/tablestream.hxx b/contrib/libs/libpqxx/include/pqxx/tablestream.hxx
new file mode 100644
index 0000000000..1803604bec
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablestream.hxx
@@ -0,0 +1,59 @@
+/** Definition of the pqxx::tablestream class.
+ *
+ * pqxx::tablestream provides optimized batch access to a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/tablestream instead.
+ *
+ * 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_TABLESTREAM
+#define PQXX_H_TABLESTREAM
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+#include "pqxx/transaction_base.hxx"
+
+
+namespace pqxx
+{
+/// Base class for obsolete tablereader/tablewriter classes.
+/** @deprecated Use stream_from and stream_to instead.
+ */
+class PQXX_LIBEXPORT PQXX_NOVTABLE tablestream :
+ public internal::transactionfocus
+{
+public:
+ explicit tablestream(
+ transaction_base &Trans,
+ const std::string &Null=std::string{});
+ virtual ~tablestream() noexcept =0;
+ virtual void complete() =0;
+protected:
+ const std::string &NullStr() const { return m_null; }
+ bool is_finished() const noexcept { return m_finished; }
+ void base_close();
+ template<typename ITER>
+ static std::string columnlist(ITER colbegin, ITER colend);
+private:
+ std::string m_null;
+ bool m_finished = false;
+
+ tablestream() =delete;
+ tablestream(const tablestream &) =delete;
+ tablestream &operator=(const tablestream &) =delete;
+};
+
+
+template<typename ITER> inline
+std::string tablestream::columnlist(ITER colbegin, ITER colend)
+{
+ return separated_list(",", colbegin, colend);
+}
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/tablewriter b/contrib/libs/libpqxx/include/pqxx/tablewriter
new file mode 100644
index 0000000000..80bdf59b2b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablewriter
@@ -0,0 +1,6 @@
+/** pqxx::tablewriter class.
+ *
+ * pqxx::tablewriter enables optimized batch updates to a database table.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/tablewriter.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/tablewriter.hxx b/contrib/libs/libpqxx/include/pqxx/tablewriter.hxx
new file mode 100644
index 0000000000..32e7a98b7c
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/tablewriter.hxx
@@ -0,0 +1,209 @@
+/** Definition of the pqxx::tablewriter class.
+ *
+ * pqxx::tablewriter enables optimized batch updates to a database table.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/tablewriter.hxx instead.
+ *
+ * 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_TABLEWRITER
+#define PQXX_H_TABLEWRITER
+
+#include <iterator>
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/tablestream.hxx"
+
+
+namespace pqxx
+{
+/// @deprecated Use stream_to instead.
+/** Efficiently write data directly to a database table.
+ * @warning This class does not work reliably with multibyte encodings. Using
+ * it with some multi-byte encodings may pose a security risk.
+ */
+class PQXX_LIBEXPORT tablewriter : public tablestream
+{
+public:
+ PQXX_DEPRECATED tablewriter(
+ transaction_base &,
+ const std::string &WName,
+ const std::string &Null=std::string{});
+ template<typename ITER>
+ PQXX_DEPRECATED tablewriter(
+ transaction_base &,
+ const std::string &WName,
+ ITER begincolumns,
+ ITER endcolumns);
+ template<typename ITER>
+ PQXX_DEPRECATED tablewriter(
+ transaction_base &T,
+ const std::string &WName,
+ ITER begincolumns,
+ ITER endcolumns,
+ const std::string &Null);
+ ~tablewriter() noexcept;
+ template<typename IT> void insert(IT Begin, IT End);
+ template<typename TUPLE> void insert(const TUPLE &);
+ template<typename IT> void push_back(IT Begin, IT End);
+ template<typename TUPLE> void push_back(const TUPLE &);
+ template<typename SIZE> void reserve(SIZE) {}
+ template<typename TUPLE> tablewriter &operator<<(const TUPLE &);
+ tablewriter &operator<<(tablereader &);
+ template<typename IT> std::string generate(IT Begin, IT End) const;
+ template<typename TUPLE> std::string generate(const TUPLE &) const;
+ virtual void complete() override;
+ void write_raw_line(const std::string &);
+private:
+ void set_up(
+ transaction_base &,
+ const std::string &WName,
+ const std::string &Columns = std::string{});
+ PQXX_PRIVATE void writer_close();
+};
+} // namespace pqxx
+
+
+namespace std
+{
+template<>
+ class back_insert_iterator<pqxx::tablewriter>
+{
+public:
+ using iterator_category = output_iterator_tag;
+
+ explicit back_insert_iterator(pqxx::tablewriter &W) noexcept :
+ m_writer{&W} {}
+
+ back_insert_iterator &
+ operator=(const back_insert_iterator &rhs) noexcept
+ {
+ m_writer = rhs.m_writer;
+ return *this;
+ }
+
+ template<typename TUPLE>
+ back_insert_iterator &operator=(const TUPLE &T)
+ {
+ m_writer->insert(T);
+ return *this;
+ }
+
+ back_insert_iterator &operator++() { return *this; }
+ back_insert_iterator &operator++(int) { return *this; }
+ back_insert_iterator &operator*() { return *this; }
+
+private:
+ pqxx::tablewriter *m_writer;
+};
+} // namespace std
+
+
+namespace pqxx
+{
+template<typename ITER> inline tablewriter::tablewriter(
+ transaction_base &T,
+ const std::string &WName,
+ ITER begincolumns,
+ ITER endcolumns) :
+ namedclass{"tablewriter", WName},
+ tablestream{T, std::string{}}
+{
+ set_up(T, WName, columnlist(begincolumns, endcolumns));
+}
+
+
+template<typename ITER> inline tablewriter::tablewriter(
+ transaction_base &T,
+ const std::string &WName,
+ ITER begincolumns,
+ ITER endcolumns,
+ const std::string &Null) :
+ namedclass{"tablewriter", WName},
+ tablestream{T, Null}
+{
+ set_up(T, WName, columnlist(begincolumns, endcolumns));
+}
+
+
+namespace internal
+{
+PQXX_LIBEXPORT std::string escape(
+ const std::string &s,
+ const std::string &null);
+
+inline std::string escape_any(
+ const std::string &s,
+ const std::string &null)
+{ return escape(s, null); }
+
+inline std::string escape_any(
+ const char s[],
+ const std::string &null)
+{ return s ? escape(std::string{s}, null) : "\\N"; }
+
+template<typename T> inline std::string escape_any(
+ const T &t,
+ const std::string &null)
+{ return escape(to_string(t), null); }
+
+
+template<typename IT> class Escaper
+{
+ const std::string &m_null;
+public:
+ explicit Escaper(const std::string &null) : m_null{null} {}
+ std::string operator()(IT i) const { return escape_any(*i, m_null); }
+};
+}
+
+
+template<typename IT>
+inline std::string tablewriter::generate(IT Begin, IT End) const
+{
+ return separated_list("\t", Begin, End, internal::Escaper<IT>{NullStr()});
+}
+template<typename TUPLE>
+inline std::string tablewriter::generate(const TUPLE &T) const
+{
+ return generate(std::begin(T), std::end(T));
+}
+
+template<typename IT> inline void tablewriter::insert(IT Begin, IT End)
+{
+ write_raw_line(generate(Begin, End));
+}
+
+template<typename TUPLE> inline void tablewriter::insert(const TUPLE &T)
+{
+ insert(std::begin(T), std::end(T));
+}
+
+template<typename IT>
+inline void tablewriter::push_back(IT Begin, IT End)
+{
+ insert(Begin, End);
+}
+
+template<typename TUPLE>
+inline void tablewriter::push_back(const TUPLE &T)
+{
+ insert(std::begin(T), std::end(T));
+}
+
+template<typename TUPLE>
+inline tablewriter &tablewriter::operator<<(const TUPLE &T)
+{
+ insert(T);
+ return *this;
+}
+
+} // namespace pqxx
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/transaction b/contrib/libs/libpqxx/include/pqxx/transaction
new file mode 100644
index 0000000000..755cd4179b
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transaction
@@ -0,0 +1,6 @@
+/** pqxx::transaction class.
+ *
+ * pqxx::transaction represents a standard database transaction.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/transaction.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/transaction.hxx b/contrib/libs/libpqxx/include/pqxx/transaction.hxx
new file mode 100644
index 0000000000..6c0b1da0b2
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transaction.hxx
@@ -0,0 +1,116 @@
+/** Definition of the pqxx::transaction class.
+ * pqxx::transaction represents a standard database transaction.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction instead.
+ *
+ * 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_TRANSACTION
+#define PQXX_H_TRANSACTION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/dbtransaction.hxx"
+
+
+/* Methods tested in eg. self-test program test1 are marked with "//[t01]"
+ */
+
+
+namespace pqxx
+{
+
+namespace internal
+{
+/// Helper base class for the @c transaction class template.
+class PQXX_LIBEXPORT basic_transaction : public dbtransaction
+{
+protected:
+ basic_transaction( //[t01]
+ connection_base &C,
+ const std::string &IsolationLevel,
+ readwrite_policy);
+
+private:
+ virtual void do_commit() override; //[t01]
+};
+} // namespace internal
+
+
+/**
+ * @ingroup transaction
+ */
+//@{
+
+/// Standard back-end transaction, templatized on isolation level
+/** This is the type you'll normally want to use to represent a transaction on
+ * the database.
+ *
+ * While you may choose to create your own transaction object to interface to
+ * the database backend, it is recommended that you wrap your transaction code
+ * into a transactor code instead and let the transaction be created for you.
+ * @see pqxx/transactor.hxx
+ *
+ * If you should find that using a transactor makes your code less portable or
+ * too complex, go ahead, create your own transaction anyway.
+ *
+ * Usage example: double all wages
+ *
+ * @code
+ * extern connection C;
+ * work T(C);
+ * try
+ * {
+ * T.exec("UPDATE employees SET wage=wage*2");
+ * T.commit(); // NOTE: do this inside try block
+ * }
+ * catch (const exception &e)
+ * {
+ * cerr << e.what() << endl;
+ * T.abort(); // Usually not needed; same happens when T's life ends.
+ * }
+ * @endcode
+ */
+template<
+ isolation_level ISOLATIONLEVEL=read_committed,
+ readwrite_policy READWRITE=read_write>
+class transaction : public internal::basic_transaction
+{
+public:
+ using isolation_tag = isolation_traits<ISOLATIONLEVEL>;
+
+ /// Create a transaction.
+ /**
+ * @param C Connection for this transaction to operate on
+ * @param TName Optional name for transaction; must begin with a letter and
+ * may contain letters and digits only
+ */
+ explicit transaction(connection_base &C, const std::string &TName): //[t01]
+ namedclass{fullname("transaction", isolation_tag::name()), TName},
+ internal::basic_transaction(C, isolation_tag::name(), READWRITE)
+ { Begin(); }
+
+ explicit transaction(connection_base &C) : //[t01]
+ transaction(C, "") {}
+
+ virtual ~transaction() noexcept
+ { End(); }
+};
+
+
+/// The default transaction type.
+using work = transaction<>;
+
+/// Read-only transaction.
+using read_transaction = transaction<read_committed, read_only>;
+
+//@}
+}
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/transaction_base b/contrib/libs/libpqxx/include/pqxx/transaction_base
new file mode 100644
index 0000000000..929c50d226
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transaction_base
@@ -0,0 +1,7 @@
+/** Base for the transaction classes.
+ *
+ * pqxx::transaction_base defines the interface for any abstract class that
+ * represents a database transaction.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/transaction_base.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/transaction_base.hxx b/contrib/libs/libpqxx/include/pqxx/transaction_base.hxx
new file mode 100644
index 0000000000..06c2788d5a
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transaction_base.hxx
@@ -0,0 +1,664 @@
+/** Common code and definitions for the transaction classes.
+ *
+ * pqxx::transaction_base defines the interface for any abstract class that
+ * represents a database transaction.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
+ *
+ * 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_TRANSACTION_BASE
+#define PQXX_H_TRANSACTION_BASE
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+/* End-user programs need not include this file, unless they define their own
+ * transaction classes. This is not something the typical program should want
+ * to do.
+ *
+ * However, reading this file is worthwhile because it defines the public
+ * interface for the available transaction classes such as transaction and
+ * nontransaction.
+ */
+
+#include "pqxx/connection_base.hxx"
+#include "pqxx/internal/encoding_group.hxx"
+#include "pqxx/isolation.hxx"
+#include "pqxx/result.hxx"
+#include "pqxx/row.hxx"
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+namespace internal
+{
+class sql_cursor;
+
+class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
+{
+public:
+ explicit transactionfocus(transaction_base &t) :
+ namedclass{"transactionfocus"},
+ m_trans{t},
+ m_registered{false}
+ {
+ }
+
+ transactionfocus() =delete;
+ transactionfocus(const transactionfocus &) =delete;
+ transactionfocus &operator=(const transactionfocus &) =delete;
+
+protected:
+ void register_me();
+ void unregister_me() noexcept;
+ void reg_pending_error(const std::string &) noexcept;
+ bool registered() const noexcept { return m_registered; }
+
+ transaction_base &m_trans;
+
+private:
+ bool m_registered;
+};
+
+
+/// Helper class to construct an invocation of a parameterised statement.
+/** @deprecated Use @c exec_params and friends instead.
+ */
+class PQXX_LIBEXPORT parameterized_invocation : statement_parameters
+{
+public:
+ PQXX_DEPRECATED parameterized_invocation(
+ connection_base &, const std::string &query);
+
+ parameterized_invocation &operator()() { add_param(); return *this; }
+ parameterized_invocation &operator()(const binarystring &v)
+ { add_binary_param(v, true); return *this; }
+ template<typename T> parameterized_invocation &operator()(const T &v)
+ { add_param(v, true); return *this; }
+ parameterized_invocation &operator()(const binarystring &v, bool nonnull)
+ { add_binary_param(v, nonnull); return *this; }
+ template<typename T>
+ parameterized_invocation &operator()(const T &v, bool nonnull)
+ { add_param(v, nonnull); return *this; }
+
+ result exec();
+
+private:
+ /// Not allowed
+ parameterized_invocation &operator=(const parameterized_invocation &)
+ =delete;
+
+ connection_base &m_home;
+ const std::string m_query;
+};
+} // namespace internal
+
+
+namespace internal
+{
+namespace gate
+{
+class transaction_subtransaction;
+class transaction_tablereader;
+class transaction_sql_cursor;
+class transaction_stream_from;
+class transaction_tablewriter;
+class transaction_stream_to;
+class transaction_transactionfocus;
+} // namespace internal::gate
+} // namespace internal
+
+
+/**
+ * @defgroup transaction Transaction classes
+ *
+ * All database access goes through instances of these classes.
+ * However, not all implementations of this interface need to provide
+ * full transactional integrity.
+ *
+ * Several implementations of this interface are shipped with libpqxx, including
+ * the plain transaction class, the entirely unprotected nontransaction, and the
+ * more cautious robusttransaction.
+ */
+
+/// Interface definition (and common code) for "transaction" classes.
+/**
+ * @ingroup transaction
+ *
+ * Abstract base class for all transaction types.
+ */
+class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
+ public virtual internal::namedclass
+{
+public:
+ /// If nothing else is known, our isolation level is at least read_committed
+ using isolation_tag = isolation_traits<read_committed>;
+
+ transaction_base() =delete;
+ transaction_base(const transaction_base &) =delete;
+ transaction_base &operator=(const transaction_base &) =delete;
+
+ virtual ~transaction_base() =0; //[t01]
+
+ /// Commit the transaction
+ /** Unless this function is called explicitly, the transaction will not be
+ * committed (actually the nontransaction implementation breaks this rule,
+ * hence the name).
+ *
+ * Once this function returns, the whole transaction will typically be
+ * irrevocably completed in the database. There is also, however, a minute
+ * risk that the connection to the database may be lost at just the wrong
+ * moment. In that case, libpqxx may be unable to determine whether the
+ * transaction was completed or aborted and an in_doubt_error will be thrown
+ * to make this fact known to the caller. The robusttransaction
+ * implementation takes some special precautions to reduce this risk.
+ */
+ void commit(); //[t01]
+
+ /// Abort the transaction
+ /** No special effort is required to call this function; it will be called
+ * implicitly when the transaction is destructed.
+ */
+ void abort(); //[t10]
+
+ /**
+ * @ingroup escaping-functions
+ */
+ //@{
+ /// Escape string for use as SQL string literal in this transaction
+ std::string esc(const char str[]) const { return conn().esc(str); }
+ /// Escape string for use as SQL string literal in this transaction
+ std::string esc(const char str[], size_t maxlen) const
+ { return conn().esc(str, maxlen); }
+ /// Escape string for use as SQL string literal in this transaction
+ std::string esc(const std::string &str) const { return conn().esc(str); }
+
+ /// Escape binary data for use as SQL string literal in this transaction
+ /** Raw, binary data is treated differently from regular strings. Binary
+ * strings are never interpreted as text, so they may safely include byte
+ * values or byte sequences that don't happen to represent valid characters in
+ * the character encoding being used.
+ *
+ * The binary string does not stop at the first zero byte, as is the case with
+ * textual strings. Instead, they may contain zero bytes anywhere. If it
+ * happens to contain bytes that look like quote characters, or other things
+ * that can disrupt their use in SQL queries, they will be replaced with
+ * special escape sequences.
+ */
+ std::string esc_raw(const unsigned char data[], size_t len) const //[t62]
+ { return conn().esc_raw(data, len); }
+ /// Escape binary data for use as SQL string literal in this transaction
+ std::string esc_raw(const std::string &) const; //[t62]
+
+ /// Unescape binary data, e.g. from a table field or notification payload.
+ /** Takes a binary string as escaped by PostgreSQL, and returns a restored
+ * copy of the original binary data.
+ */
+ std::string unesc_raw(const std::string &text) const
+ { return conn().unesc_raw(text); }
+
+ /// Unescape binary data, e.g. from a table field or notification payload.
+ /** Takes a binary string as escaped by PostgreSQL, and returns a restored
+ * copy of the original binary data.
+ */
+ std::string unesc_raw(const char *text) const
+ { return conn().unesc_raw(text); }
+
+ /// Represent object as SQL string, including quoting & escaping.
+ /** Nulls are recognized and represented as SQL nulls. */
+ template<typename T> std::string quote(const T &t) const
+ { return conn().quote(t); }
+
+ /// Binary-escape and quote a binarystring for use as an SQL constant.
+ std::string quote_raw(const unsigned char str[], size_t len) const
+ { return conn().quote_raw(str, len); }
+
+ std::string quote_raw(const std::string &str) const;
+
+ /// Escape an SQL identifier for use in a query.
+ std::string quote_name(const std::string &identifier) const
+ { return conn().quote_name(identifier); }
+
+ /// Escape string for literal LIKE match.
+ std::string esc_like(const std::string &str, char escape_char='\\') const
+ { return conn().esc_like(str, escape_char); }
+ //@}
+
+ /// Execute query
+ /** Perform a query in this transaction.
+ *
+ * This is one of the most important functions in libpqxx.
+ *
+ * Most libpqxx exceptions can be thrown from here, including sql_error,
+ * broken_connection, and many sql_error subtypes such as
+ * feature_not_supported or insufficient_privilege. But any exception thrown
+ * by the C++ standard library may also occur here. All exceptions will be
+ * derived from std::exception, however, and all libpqxx-specific exception
+ * types are derived from pqxx::pqxx_exception.
+ *
+ * @param Query Query or command to execute
+ * @param Desc Optional identifier for query, to help pinpoint SQL errors
+ * @return A result set describing the query's or command's result
+ */
+ result exec(
+ const std::string &Query,
+ const std::string &Desc=std::string{}); //[t01]
+
+ result exec(
+ const std::stringstream &Query,
+ const std::string &Desc=std::string{})
+ { return exec(Query.str(), Desc); }
+
+ /// Execute query, which should zero rows of data.
+ /** Works like exec, but fails if the result contains data. It still returns
+ * a result, however, which may contain useful metadata.
+ *
+ * @throw unexpected_rows If the query returned the wrong number of rows.
+ */
+ result exec0(
+ const std::string &Query,
+ const std::string &Desc=std::string{})
+ { return exec_n(0, Query, Desc); }
+
+ /// Execute query returning a single row of data.
+ /** Works like exec, but requires the result to contain exactly one row.
+ * The row can be addressed directly, without the need to find the first row
+ * in a result set.
+ *
+ * @throw unexpected_rows If the query returned the wrong number of rows.
+ */
+ row exec1(const std::string &Query, const std::string &Desc=std::string{})
+ { return exec_n(1, Query, Desc).front(); }
+
+ /// Execute query, expect given number of rows.
+ /** Works like exec, but checks that the number of rows is exactly what's
+ * expected.
+ *
+ * @throw unexpected_rows If the query returned the wrong number of rows.
+ */
+ result exec_n(
+ size_t rows,
+ const std::string &Query,
+ const std::string &Desc=std::string{});
+
+ /**
+ * @name Parameterized statements
+ *
+ * You'll often need parameters in the queries you execute: "select the
+ * car with this licence plate." If the parameter is a string, you need to
+ * quote it and escape any special characters inside it, or it may become a
+ * target for an SQL injection attack. If it's an integer (for example),
+ * you need to convert it to a string, but in the database's format, without
+ * locale-specific niceties like "," separators between the thousands.
+ *
+ * Parameterised statements are an easier and safer way to do this. They're
+ * like prepared statements, but for a single use. You don't need to name
+ * them, and you don't need to prepare them first.
+ *
+ * Your query will include placeholders like @c $1 and $2 etc. in the places
+ * where you want the arguments to go. Then, you pass the argument values
+ * and the actual query is constructed for you.
+ *
+ * Pass the exact right number of parameters, and in the right order. The
+ * parameters in the query don't have to be neatly ordered from @c $1 to
+ * @c $2 to @c $3 - but you must pass the argument for @c $1 first, the one
+ * for @c $2 second, etc.
+ *
+ * @warning Beware of "nul" bytes. Any string you pass as a parameter will
+ * end at the first char with value zero. If you pass a @c std::string that
+ * contains a zero byte, the last byte in the value will be the one just
+ * before the zero.
+ */
+ //@{
+ /// Execute an SQL statement with parameters.
+ template<typename ...Args>
+ result exec_params(const std::string &query, Args &&...args)
+ {
+ return internal_exec_params(
+ query, internal::params(std::forward<Args>(args)...));
+ }
+
+ // Execute parameterised statement, expect a single-row result.
+ /** @throw unexpected_rows if the result does not consist of exactly one row.
+ */
+ template<typename ...Args>
+ row exec_params1(const std::string &query, Args&&... args)
+ {
+ return exec_params_n(1, query, std::forward<Args>(args)...).front();
+ }
+
+ // Execute parameterised statement, expect a result with zero rows.
+ /** @throw unexpected_rows if the result contains rows.
+ */
+ template<typename ...Args>
+ result exec_params0(const std::string &query, Args &&...args)
+ {
+ return exec_params_n(0, query, std::forward<Args>(args)...);
+ }
+
+ // Execute parameterised statement, expect exactly a given number of rows.
+ /** @throw unexpected_rows if the result contains the wrong number of rows.
+ */
+ template<typename ...Args>
+ result exec_params_n(size_t rows, const std::string &query, Args &&...args)
+ {
+ const auto r = exec_params(query, std::forward<Args>(args)...);
+ check_rowcount_params(rows, r.size());
+ return r;
+ }
+
+ /// Parameterize a statement. @deprecated Use @c exec_params instead.
+ /* Use this to build up a parameterized statement invocation, then invoke it
+ * using @c exec()
+ *
+ * Example: @c trans.parameterized("SELECT $1 + 1")(1).exec();
+ *
+ * This is the old, pre-C++11 way of handling parameterised statements. As
+ * of libpqxx 6.0, it's made much easier using variadic templates.
+ */
+ PQXX_DEPRECATED internal::parameterized_invocation
+ parameterized(const std::string &query);
+ //@}
+
+ /**
+ * @name Prepared statements
+ *
+ * These are very similar to parameterised statements. The difference is
+ * that you prepare them in advance, giving them identifying names. You can
+ * then call them by these names, passing in the argument values appropriate
+ * for that call.
+ *
+ * You prepare a statement on the connection, using
+ * @c pqxx::connection_base::prepare(). But you then call the statement in a
+ * transaction, using the functions you see here.
+ *
+ * Never try to prepare, execute, or unprepare a prepared statement manually
+ * using direct SQL queries. Always use the functions provided by libpqxx.
+ *
+ * See \ref prepared for a full discussion.
+ *
+ * @warning Beware of "nul" bytes. Any string you pass as a parameter will
+ * end at the first char with value zero. If you pass a @c std::string that
+ * contains a zero byte, the last byte in the value will be the one just
+ * before the zero. If you need a zero byte, consider using
+ * pqxx::binarystring and/or SQL's @c bytea type.
+ */
+ //@{
+
+ /// Execute a prepared statement, with optional arguments.
+ template<typename ...Args>
+ result exec_prepared(const std::string &statement, Args&&... args)
+ {
+ return internal_exec_prepared(
+ statement, internal::params(std::forward<Args>(args)...), result_format::text);
+ }
+
+ /// Execute a prepared statement, with optional arguments.
+ template<typename ...Args>
+ result exec_prepared_binary(const std::string &statement, Args&&... args)
+ {
+ return internal_exec_prepared(
+ statement, internal::params(std::forward<Args>(args)...), result_format::binary);
+ }
+
+ /// Execute a prepared statement, and expect a single-row result.
+ /** @throw pqxx::unexpected_rows if the result was not exactly 1 row.
+ */
+ template<typename ...Args>
+ row exec_prepared1(const std::string &statement, Args&&... args)
+ {
+ return exec_prepared_n(1, statement, std::forward<Args>(args)...).front();
+ }
+
+ /// Execute a prepared statement, and expect a result with zero rows.
+ /** @throw pqxx::unexpected_rows if the result contained rows.
+ */
+ template<typename ...Args>
+ result exec_prepared0(const std::string &statement, Args&&... args)
+ {
+ return exec_prepared_n(0, statement, std::forward<Args>(args)...);
+ }
+
+ /// Execute a prepared statement, expect a result with given number of rows.
+ /** @throw pqxx::unexpected_rows if the result did not contain exactly the
+ * given number of rows.
+ */
+ template<typename ...Args>
+ result exec_prepared_n(
+ size_t rows,
+ const std::string &statement,
+ Args&&... args)
+ {
+ const auto r = exec_prepared(statement, std::forward<Args>(args)...);
+ check_rowcount_prepared(statement, rows, r.size());
+ return r;
+ }
+
+ /// Execute prepared statement. @deprecated Use exec_prepared instead.
+ /** Just like param_declaration is a helper class that lets you tag parameter
+ * declarations onto the statement declaration, the invocation class returned
+ * here lets you tag parameter values onto the call:
+ *
+ * @code
+ * result run_mystatement(transaction_base &T)
+ * {
+ * return T.exec_prepared("mystatement", "param1", 2, nullptr, 4);
+ * }
+ * @endcode
+ *
+ * Here, parameter 1 (written as "<tt>$1</tt>" in the statement's body) is a
+ * string that receives the value "param1"; the second parameter is an integer
+ * with the value 2; the third receives a null, making its type irrelevant;
+ * and number 4 again is an integer. The ultimate invocation of exec() is
+ * essential; if you forget this, nothing happens.
+ *
+ * To see whether any prepared statement has been defined under a given name,
+ * use:
+ *
+ * @code
+ * T.prepared("mystatement").exists()
+ * @endcode
+ *
+ * @warning Do not try to execute a prepared statement manually through direct
+ * SQL statements. This is likely not to work, and even if it does, is likely
+ * to be slower than using the proper libpqxx functions. Also, libpqxx knows
+ * how to emulate prepared statements if some part of the infrastructure does
+ * not support them.
+ *
+ * @warning Actual definition of the prepared statement on the backend may be
+ * deferred until its first use, which means that any errors in the prepared
+ * statement may not show up until it is executed--and perhaps abort the
+ * ongoing transaction in the process.
+ *
+ * If you leave out the statement name, the call refers to the nameless
+ * statement instead.
+ */
+ PQXX_DEPRECATED prepare::invocation
+ prepared(const std::string &statement=std::string{});
+
+ //@}
+
+ /**
+ * @name Error/warning output
+ */
+ //@{
+ /// Have connection process warning message
+ void process_notice(const char Msg[]) const //[t14]
+ { m_conn.process_notice(Msg); }
+ /// Have connection process warning message
+ void process_notice(const std::string &Msg) const //[t14]
+ { m_conn.process_notice(Msg); }
+ //@}
+
+ /// Connection this transaction is running in
+ connection_base &conn() const { return m_conn; } //[t04]
+
+ /// Set session variable in this connection
+ /** The new value is typically forgotten if the transaction aborts.
+ * However nontransaction is an exception to this rule: in that case the set
+ * value will be kept regardless. Also, if the connection ever needs to be
+ * recovered, a value you set in a nontransaction will not be restored.
+ * @param Var The variable to set
+ * @param Val The new value to store in the variable
+ */
+ void set_variable(const std::string &Var, const std::string &Val); //[t61]
+
+ /// Get currently applicable value of variable
+ /** First consults an internal cache of variables that have been set (whether
+ * in the ongoing transaction or in the connection) using the set_variable
+ * functions. If it is not found there, the database is queried.
+ *
+ * @warning Do not mix the set_variable with raw "SET" queries, and do not
+ * try to set or get variables while a pipeline or table stream is active.
+ *
+ * @warning This function used to be declared as @c const but isn't anymore.
+ */
+ std::string get_variable(const std::string &); //[t61]
+
+protected:
+ /// Create a transaction (to be called by implementation classes only)
+ /** The optional name, if nonempty, must begin with a letter and may contain
+ * letters and digits only.
+ *
+ * @param c The connection that this transaction is to act on.
+ * @param direct Running directly in connection context (i.e. not nested)?
+ */
+ explicit transaction_base(connection_base &c, bool direct=true);
+
+ /// Begin transaction (to be called by implementing class)
+ /** Will typically be called from implementing class' constructor.
+ */
+ void Begin();
+
+ /// End transaction. To be called by implementing class' destructor
+ void End() noexcept;
+
+ /// To be implemented by derived implementation class: start transaction
+ virtual void do_begin() =0;
+ /// To be implemented by derived implementation class: perform query
+ virtual result do_exec(const char Query[]) =0;
+ /// To be implemented by derived implementation class: commit transaction
+ virtual void do_commit() =0;
+ /// To be implemented by derived implementation class: abort transaction
+ virtual void do_abort() =0;
+
+ // For use by implementing class:
+
+ /// Execute query on connection directly
+ /**
+ * @param C Query or command to execute
+ * @param Retries Number of times to retry the query if it fails. Be
+ * extremely careful with this option; if you retry in the middle of a
+ * transaction, you may be setting up a new connection transparently and
+ * executing the latter part of the transaction without a backend transaction
+ * being active (and with the former part aborted).
+ */
+ result direct_exec(const char C[], int Retries=0);
+
+ /// Forget about any reactivation-blocking resources we tried to allocate
+ void reactivation_avoidance_clear() noexcept
+ {m_reactivation_avoidance.clear();}
+
+protected:
+ /// Resources allocated in this transaction that make reactivation impossible
+ /** This number may be negative!
+ */
+ internal::reactivation_avoidance_counter m_reactivation_avoidance;
+
+private:
+ /* A transaction goes through the following stages in its lifecycle:
+ * <ul>
+ * <li> nascent: the transaction hasn't actually begun yet. If our connection
+ * fails at this stage, it may recover and the transaction can attempt to
+ * establish itself again.
+ * <li> active: the transaction has begun. Since no commit command has been
+ * issued, abortion is implicit if the connection fails now.
+ * <li> aborted: an abort has been issued; the transaction is terminated and
+ * its changes to the database rolled back. It will accept no further
+ * commands.
+ * <li> committed: the transaction has completed successfully, meaning that a
+ * commit has been issued. No further commands are accepted.
+ * <li> in_doubt: the connection was lost at the exact wrong time, and there
+ * is no way of telling whether the transaction was committed or aborted.
+ * </ul>
+ *
+ * Checking and maintaining state machine logic is the responsibility of the
+ * base class (ie., this one).
+ */
+ enum Status
+ {
+ st_nascent,
+ st_active,
+ st_aborted,
+ st_committed,
+ st_in_doubt
+ };
+
+ /// Make sure transaction is opened on backend, if appropriate
+ PQXX_PRIVATE void activate();
+
+ PQXX_PRIVATE void CheckPendingError();
+
+ template<typename T> bool parm_is_null(T *p) const noexcept
+ { return p == nullptr; }
+ template<typename T> bool parm_is_null(T) const noexcept
+ { return false; }
+
+ result internal_exec_prepared(
+ const std::string &statement,
+ const internal::params &args,
+ result_format format);
+
+ result internal_exec_params(
+ const std::string &query,
+ const internal::params &args);
+
+ /// Throw unexpected_rows if prepared statement returned wrong no. of rows.
+ void check_rowcount_prepared(
+ const std::string &statement,
+ size_t expected_rows,
+ size_t actual_rows);
+
+ /// Throw unexpected_rows if wrong row count from parameterised statement.
+ void check_rowcount_params(
+ size_t expected_rows, size_t actual_rows);
+
+ friend class pqxx::internal::gate::transaction_transactionfocus;
+ PQXX_PRIVATE void register_focus(internal::transactionfocus *);
+ PQXX_PRIVATE void unregister_focus(internal::transactionfocus *) noexcept;
+ PQXX_PRIVATE void register_pending_error(const std::string &) noexcept;
+
+ friend class pqxx::internal::gate::transaction_tablereader;
+ friend class pqxx::internal::gate::transaction_stream_from;
+ PQXX_PRIVATE void BeginCopyRead(const std::string &, const std::string &);
+ bool read_copy_line(std::string &);
+
+ friend class pqxx::internal::gate::transaction_tablewriter;
+ friend class pqxx::internal::gate::transaction_stream_to;
+ PQXX_PRIVATE void BeginCopyWrite(
+ const std::string &Table,
+ const std::string &Columns);
+ void write_copy_line(const std::string &);
+ void end_copy_write();
+
+ friend class pqxx::internal::gate::transaction_subtransaction;
+
+ connection_base &m_conn;
+
+ internal::unique<internal::transactionfocus> m_focus;
+ Status m_status = st_nascent;
+ bool m_registered = false;
+ std::map<std::string, std::string> m_vars;
+ std::string m_pending_error;
+};
+
+} // namespace pqxx
+
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/transactor b/contrib/libs/libpqxx/include/pqxx/transactor
new file mode 100644
index 0000000000..658551f9b6
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transactor
@@ -0,0 +1,6 @@
+/** pqxx::transactor class.
+ *
+ * pqxx::transactor is a framework-style wrapper for safe transactions.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/transactor.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/transactor.hxx b/contrib/libs/libpqxx/include/pqxx/transactor.hxx
new file mode 100644
index 0000000000..5aba0193cb
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/transactor.hxx
@@ -0,0 +1,274 @@
+/* Transactor framework, a wrapper for safely retryable transactions.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transactor instead.
+ *
+ * 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_TRANSACTOR
+#define PQXX_H_TRANSACTOR
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+#include "pqxx/connection_base.hxx"
+#include "pqxx/transaction.hxx"
+
+
+// Methods tested in eg. test module test01 are marked with "//[t01]".
+
+namespace pqxx
+{
+/**
+ * @defgroup transactor Transactor framework
+ *
+ * Sometimes a transaction can fail for completely transient reasons, such as a
+ * conflict with another transaction in SERIALIZABLE isolation. The right way
+ * to handle those failures is often just to re-run the transaction from
+ * scratch.
+ *
+ * For example, your REST API might be handling each HTTP request in its own
+ * database transaction, and if this kind of transient failure happens, you
+ * simply want to "replay" the whole request, in a fresh transaction.
+ *
+ * You won't necessarily want to execute the exact same SQL commands with the
+ * exact same data. Some of your SQL statements may depend on state that can
+ * vary between retries. So instead of dumbly replaying the SQL, you re-run
+ * the same application code that produced those SQL commands.
+ *
+ * The transactor framework makes it a little easier for you to do this safely,
+ * and avoid typical pitfalls. You encapsulate the work that you want to do
+ * into a callable that you pass to the @c perform function.
+ *
+ * Here's how it works. You write your transaction code as a lambda or
+ * function, which creates its own transaction object, does its work, and
+ * commits at the end. You pass that callback to @c pqxx::perform, which runs
+ * it for you.
+ *
+ * If there's a failure inside your callback, there will be an exception. Your
+ * transaction object goes out of scope and gets destroyed, so that it aborts
+ * implicitly. Seeing this, @c perform tries running your callback again. It
+ * stops doing that when the callback succeeds, or when it has failed too many
+ * times, or when there's an error that leaves the database in an unknown
+ * state, such as a lost connection just while we're waiting for the database
+ * to confirm a commit. It all depends on the type of exception.
+ *
+ * The callback takes no arguments. If you're using lambdas, the easy way to
+ * pass arguments is for the lambda to "capture" them from your variables. Or,
+ * if you're using functions, you may want to use @c std::bind.
+ *
+ * Once your callback succeeds, it can return a result, and @c perform will
+ * return that result back to you.
+ */
+//@{
+
+/// Simple way to execute a transaction with automatic retry.
+/**
+ * Executes your transaction code as a callback. Repeats it until it completes
+ * normally, or it throws an error other than the few libpqxx-generated
+ * exceptions that the framework understands, or after a given number of failed
+ * attempts, or if the transaction ends in an "in-doubt" state.
+ *
+ * (An in-doubt state is one where libpqxx cannot determine whether the server
+ * finally committed a transaction or not. This can happen if the network
+ * connection to the server is lost just while we're waiting for its reply to
+ * a "commit" statement. The server may have completed the commit, or not, but
+ * it can't tell you because there's no longer a connection.
+ *
+ * Using this still takes a bit of care. If your callback makes use of data
+ * from the database, you'll probably have to query that data within your
+ * callback. If the attempt to perform your callback fails, and the framework
+ * tries again, you'll be in a new transaction and the data in the database may
+ * have changed under your feet.
+ *
+ * Also be careful about changing variables or data structures from within
+ * your callback. The run may still fail, and perhaps get run again. The
+ * ideal way to do it (in most cases) is to return your result from your
+ * callback, and change your program's data state only after @c perform
+ * completes successfully.
+ *
+ * @param callback Transaction code that can be called with no arguments.
+ * @param attempts Maximum number of times to attempt performing callback.
+ * Must be greater than zero.
+ * @return Whatever your callback returns.
+ */
+template<typename TRANSACTION_CALLBACK>
+inline auto perform(const TRANSACTION_CALLBACK &callback, int attempts=3)
+ -> decltype(callback())
+{
+ if (attempts <= 0)
+ throw std::invalid_argument{
+ "Zero or negative number of attempts passed to pqxx::perform()."};
+
+ for (; attempts > 0; --attempts)
+ {
+ try
+ {
+ return callback();
+ }
+ catch (const in_doubt_error &)
+ {
+ // Not sure whether transaction went through or not. The last thing in
+ // the world that we should do now is try again!
+ throw;
+ }
+ catch (const statement_completion_unknown &)
+ {
+ // Not sure whether our last statement succeeded. Don't risk running it
+ // again.
+ throw;
+ }
+ catch (const broken_connection &)
+ {
+ // Connection failed. Definitely worth retrying.
+ if (attempts <= 1) throw;
+ continue;
+ }
+ catch (const transaction_rollback &)
+ {
+ // Some error that may well be transient, such as serialization failure
+ // or deadlock. Worth retrying.
+ if (attempts <= 1) throw;
+ continue;
+ }
+ }
+ throw pqxx::internal_error{"No outcome reached on perform()."};
+}
+
+/// @deprecated Pre-C++11 wrapper for automatically retrying transactions.
+/**
+ * Pass an object of your transactor-based class to connection_base::perform()
+ * to execute the transaction code embedded in it.
+ *
+ * connection_base::perform() is actually a template, specializing itself to any
+ * transactor type you pass to it. This means you will have to pass it a
+ * reference of your object's ultimate static type; runtime polymorphism is
+ * not allowed. Hence the absence of virtual methods in transactor. The
+ * exact methods to be called at runtime *must* be resolved at compile time.
+ *
+ * Your transactor-derived class must define a copy constructor. This will be
+ * used to create a "clean" copy of your transactor for every attempt that
+ * perform() makes to run it.
+ */
+template<typename TRANSACTION=transaction<read_committed>> class transactor
+{
+public:
+ using argument_type = TRANSACTION;
+ PQXX_DEPRECATED explicit transactor( //[t04]
+ const std::string &TName="transactor") :
+ m_name{TName} { }
+
+ /// Overridable transaction definition; insert your database code here
+ /** The operation will be retried if the connection to the backend is lost or
+ * the operation fails, but not if the connection is broken in such a way as
+ * to leave the library in doubt as to whether the operation succeeded. In
+ * that case, an in_doubt_error will be thrown.
+ *
+ * Recommended practice is to allow this operator to modify only the
+ * transactor itself, and the dedicated transaction object it is passed as an
+ * argument. This is what makes side effects, retrying etc. controllable in
+ * the transactor framework.
+ * @param T Dedicated transaction context created to perform this operation.
+ */
+ void operator()(TRANSACTION &T); //[t04]
+
+ // Overridable member functions, called by connection_base::perform() if an
+ // attempt to run transaction fails/succeeds, respectively, or if the
+ // connection is lost at just the wrong moment, goes into an indeterminate
+ // state. Use these to patch up runtime state to match events, if needed, or
+ // to report failure conditions.
+
+ /// Optional overridable function to be called if transaction is aborted
+ /** This need not imply complete failure; the transactor will automatically
+ * retry the operation a number of times before giving up. on_abort() will be
+ * called for each of the failed attempts.
+ *
+ * One parameter is passed in by the framework: an error string describing why
+ * the transaction failed. This will also be logged to the connection's
+ * notice processor.
+ */
+ void on_abort(const char[]) noexcept {} //[t13]
+
+ /// Optional overridable function to be called after successful commit
+ /** If your on_commit() throws an exception, the actual back-end transaction
+ * will remain committed, so any changes in the database remain regardless of
+ * how this function terminates.
+ */
+ void on_commit() {} //[t07]
+
+ /// Overridable function to be called when "in doubt" about outcome
+ /** This may happen if the connection to the backend is lost while attempting
+ * to commit. In that case, the backend may have committed the transaction
+ * but is unable to confirm this to the frontend; or the transaction may have
+ * failed, causing it to be rolled back, but again without acknowledgement to
+ * the client program. The best way to deal with this situation is typically
+ * to wave red flags in the user's face and ask him to investigate.
+ *
+ * The robusttransaction class is intended to reduce the chances of this
+ * error occurring, at a certain cost in performance.
+ * @see robusttransaction
+ */
+ void on_doubt() noexcept {} //[t13]
+
+ /// The transactor's name.
+ std::string name() const { return m_name; } //[t13]
+
+private:
+ std::string m_name;
+};
+
+
+template<typename TRANSACTOR>
+inline void connection_base::perform(
+ const TRANSACTOR &T,
+ int Attempts)
+{
+ if (Attempts <= 0) return;
+
+ bool Done = false;
+
+ // Make attempts to perform T
+ do
+ {
+ --Attempts;
+
+ // Work on a copy of T2 so we can restore the starting situation if need be
+ TRANSACTOR T2{T};
+ try
+ {
+ typename TRANSACTOR::argument_type X{*this, T2.name()};
+ T2(X);
+ X.commit();
+ Done = true;
+ }
+ catch (const in_doubt_error &)
+ {
+ // Not sure whether transaction went through or not. The last thing in
+ // the world that we should do now is retry.
+ T2.on_doubt();
+ throw;
+ }
+ catch (const std::exception &e)
+ {
+ // Could be any kind of error.
+ T2.on_abort(e.what());
+ if (Attempts <= 0) throw;
+ continue;
+ }
+ catch (...)
+ {
+ // Don't try to forge ahead if we don't even know what happened
+ T2.on_abort("Unknown exception");
+ throw;
+ }
+
+ T2.on_commit();
+ } while (not Done);
+}
+} // namespace pqxx
+//@}
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/types.hxx b/contrib/libs/libpqxx/include/pqxx/types.hxx
new file mode 100644
index 0000000000..49d1a0d1f0
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/types.hxx
@@ -0,0 +1,57 @@
+/**
+ * Basic type aliases and forward declarations.
+ *
+ * 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_TYPES
+#define PQXX_H_TYPES
+
+#include <cstddef>
+
+namespace pqxx
+{
+/// Number of rows in a result set.
+using result_size_type = unsigned long;
+
+/// Difference between result sizes.
+using result_difference_type = signed long;
+
+/// Number of fields in a row of database data.
+using row_size_type = unsigned int;
+
+/// Difference between row sizes.
+using row_difference_type = signed int;
+
+/// Number of bytes in a field of database data.
+using field_size_type = std::size_t;
+
+/// Number of bytes in a large object. (Unusual: it's signed.)
+using large_object_size_type = long;
+
+
+// Forward declarations, to help break compilation dependencies.
+// These won't necessarily include all classes in libpqxx.
+class binarystring;
+class connectionpolicy;
+class connection_base;
+class const_result_iterator;
+class const_reverse_result_iterator;
+class const_reverse_row_iterator;
+class const_row_iterator;
+class dbtransaction;
+class field;
+class largeobjectaccess;
+class notification_receiver;
+class range_error;
+class result;
+class row;
+class tablereader;
+class transaction_base;
+
+} // namespace pqxx
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/util b/contrib/libs/libpqxx/include/pqxx/util
new file mode 100644
index 0000000000..6ec38ac111
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/util
@@ -0,0 +1,5 @@
+/** Various utility definitions for libpqxx.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type
+#include "pqxx/util.hxx"
+
diff --git a/contrib/libs/libpqxx/include/pqxx/util.hxx b/contrib/libs/libpqxx/include/pqxx/util.hxx
new file mode 100644
index 0000000000..86a9134c38
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/util.hxx
@@ -0,0 +1,309 @@
+/** Various utility definitions for libpqxx.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
+ *
+ * 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_UTIL
+#define PQXX_H_UTIL
+
+#include "pqxx/compiler-public.hxx"
+
+#include <cstdio>
+#include <cctype>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+#include <typeinfo>
+#include <vector>
+
+#include "pqxx/strconv.hxx"
+
+
+/// The home of all libpqxx classes, functions, templates, etc.
+namespace pqxx {}
+
+#include <pqxx/internal/libpq-forward.hxx>
+
+
+namespace pqxx
+{
+/// Suppress compiler warning about an unused item.
+template<typename T> inline void ignore_unused(T) {}
+
+
+/// Descriptor of library's thread-safety model.
+/** This describes what the library knows about various risks to thread-safety.
+ */
+struct PQXX_LIBEXPORT thread_safety_model
+{
+ /// @deprecated Is error reporting thread-safe? Now always true.
+ bool have_safe_strerror = true;
+
+ /// Is the underlying libpq build thread-safe?
+ bool safe_libpq;
+
+ /// @deprecated Query cancel is always thread-safe now.
+ bool safe_query_cancel = true;
+
+ /// @deprecated Always thread-safe to copy a 'result' or 'binarystring' now.
+ bool safe_result_copy = true;
+
+ /// Is Kerberos thread-safe?
+ /** @warning Is currently always @c false.
+ *
+ * If your application uses Kerberos, all accesses to libpqxx or Kerberos must
+ * be serialized. Confine their use to a single thread, or protect it with a
+ * global lock.
+ */
+ bool safe_kerberos;
+
+ /// A human-readable description of any thread-safety issues.
+ std::string description;
+};
+
+
+/// Describe thread safety available in this build.
+PQXX_LIBEXPORT thread_safety_model describe_thread_safety() noexcept;
+
+
+/// The "null" oid.
+constexpr oid oid_none = 0;
+
+
+/**
+ * @defgroup utility Utility functions
+ */
+//@{
+
+/// Represent sequence of values as a string, joined by a given separator.
+/**
+ * Use this to turn e.g. the numbers 1, 2, and 3 into a string "1, 2, 3".
+ *
+ * @param sep separator string (to be placed between items)
+ * @param begin beginning of items sequence
+ * @param end end of items sequence
+ * @param access functor defining how to dereference sequence elements
+ */
+template<typename ITER, typename ACCESS> inline
+std::string separated_list( //[t00]
+ const std::string &sep,
+ ITER begin,
+ ITER end,
+ ACCESS access)
+{
+ std::string result;
+ if (begin != end)
+ {
+ result = to_string(access(begin));
+ for (++begin; begin != end; ++begin)
+ {
+ result += sep;
+ result += to_string(access(begin));
+ }
+ }
+ return result;
+}
+
+
+/// Render sequence as a string, using given separator between items.
+template<typename ITER> inline std::string
+separated_list(const std::string &sep, ITER begin, ITER end) //[t00]
+ { return separated_list(sep, begin, end, [](ITER i){ return *i; }); }
+
+
+/// Render items in a container as a string, using given separator.
+template<typename CONTAINER> inline auto
+separated_list(const std::string &sep, const CONTAINER &c) //[t10]
+ /*
+ Always std::string; necessary because SFINAE doesn't work with the
+ contents of function bodies, so the check for iterability has to be in
+ the signature.
+ */
+ -> typename std::enable_if<
+ (
+ not std::is_void<decltype(std::begin(c))>::value
+ and not std::is_void<decltype(std::end(c))>::value
+ ),
+ std::string
+ >::type
+{
+ return separated_list(sep, std::begin(c), std::end(c));
+}
+
+
+/// Render items in a tuple as a string, using given separator.
+template<
+ typename TUPLE,
+ std::size_t INDEX=0,
+ typename ACCESS,
+ typename std::enable_if<
+ (INDEX == std::tuple_size<TUPLE>::value-1),
+ int
+ >::type=0
+>
+inline std::string
+separated_list(
+ const std::string & /* sep */,
+ const TUPLE &t,
+ const ACCESS& access
+)
+{
+ return to_string(access(&std::get<INDEX>(t)));
+}
+
+template<
+ typename TUPLE,
+ std::size_t INDEX=0,
+ typename ACCESS,
+ typename std::enable_if<
+ (INDEX < std::tuple_size<TUPLE>::value-1),
+ int
+ >::type=0
+>
+inline std::string
+separated_list(const std::string &sep, const TUPLE &t, const ACCESS& access)
+{
+ return
+ to_string(access(&std::get<INDEX>(t))) +
+ sep +
+ separated_list<TUPLE, INDEX+1>(sep, t, access);
+}
+
+template<
+ typename TUPLE,
+ std::size_t INDEX=0,
+ typename std::enable_if<
+ (INDEX <= std::tuple_size<TUPLE>::value),
+ int
+ >::type=0
+>
+inline std::string
+separated_list(const std::string &sep, const TUPLE &t)
+{
+ return separated_list(sep, t, [](const TUPLE &tup){return *tup;});
+}
+//@}
+
+
+/// Private namespace for libpqxx's internal use; do not access.
+/** This namespace hides definitions internal to libpqxx. These are not
+ * supposed to be used by client programs, and they may change at any time
+ * without notice.
+ *
+ * Conversely, if you find something in this namespace tremendously useful, by
+ * all means do lodge a request for its publication.
+ *
+ * @warning Here be dragons!
+ */
+namespace internal
+{
+PQXX_LIBEXPORT void freepqmem(const void *) noexcept;
+template<typename P> inline void freepqmem_templated(P *p) noexcept
+{
+ freepqmem(p);
+}
+
+PQXX_LIBEXPORT void freemallocmem(const void *) noexcept;
+template<typename P> inline void freemallocmem_templated(P *p) noexcept
+{
+ freemallocmem(p);
+}
+
+
+/// Helper base class: object descriptions for error messages and such.
+/**
+ * Classes derived from namedclass have a class name (such as "transaction"),
+ * an optional object name (such as "delete-old-logs"), and a description
+ * generated from the two names (such as "transaction delete-old-logs").
+ *
+ * The class name is dynamic here, in order to support inheritance hierarchies
+ * where the exact class name may not be known statically.
+ *
+ * In inheritance hierarchies, make namedclass a virtual base class so that
+ * each class in the hierarchy can specify its own class name in its
+ * constructors.
+ */
+class PQXX_LIBEXPORT namedclass
+{
+public:
+ explicit namedclass(const std::string &Classname) :
+ m_classname{Classname},
+ m_name{}
+ {
+ }
+
+ namedclass(const std::string &Classname, const std::string &Name) :
+ m_classname{Classname},
+ m_name{Name}
+ {
+ }
+
+ /// Object name, or the empty string if no name was given.
+ const std::string &name() const noexcept { return m_name; } //[t01]
+
+ /// Class name.
+ const std::string &classname() const noexcept //[t73]
+ { return m_classname; }
+
+ /// Combination of class name and object name; or just class name.
+ std::string description() const;
+
+private:
+ std::string m_classname, m_name;
+};
+
+
+PQXX_PRIVATE void CheckUniqueRegistration(
+ const namedclass *New, const namedclass *Old);
+PQXX_PRIVATE void CheckUniqueUnregistration(
+ const namedclass *New, const namedclass *Old);
+
+
+/// Ensure proper opening/closing of GUEST objects related to a "host" object
+/** Only a single GUEST may exist for a single host at any given time. GUEST
+ * must be derived from namedclass.
+ */
+template<typename GUEST>
+class unique
+{
+public:
+ unique() =default;
+ unique(const unique &) =delete;
+ unique &operator=(const unique &) =delete;
+
+ GUEST *get() const noexcept { return m_guest; }
+
+ void register_guest(GUEST *G)
+ {
+ CheckUniqueRegistration(G, m_guest);
+ m_guest = G;
+ }
+
+ void unregister_guest(GUEST *G)
+ {
+ CheckUniqueUnregistration(G, m_guest);
+ m_guest = nullptr;
+ }
+
+private:
+ GUEST *m_guest = nullptr;
+};
+
+
+/// Sleep for the given number of seconds
+/** May return early, e.g. when interrupted by a signal. Completes instantly if
+ * a zero or negative sleep time is requested.
+ */
+PQXX_LIBEXPORT void sleep_seconds(int);
+
+} // namespace internal
+} // namespace pqxx
+
+#endif
diff --git a/contrib/libs/libpqxx/include/pqxx/version b/contrib/libs/libpqxx/include/pqxx/version
new file mode 100644
index 0000000000..5f7ab6a14e
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/version
@@ -0,0 +1,4 @@
+/** libpqxx version info.
+ */
+// Actual definitions in .hxx file so editors and such recognize file type.
+#include "pqxx/version.hxx"
diff --git a/contrib/libs/libpqxx/include/pqxx/version.hxx b/contrib/libs/libpqxx/include/pqxx/version.hxx
new file mode 100644
index 0000000000..6fe982d433
--- /dev/null
+++ b/contrib/libs/libpqxx/include/pqxx/version.hxx
@@ -0,0 +1,57 @@
+/** Version info for libpqxx.
+ *
+ * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/version instead.
+ *
+ * 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_VERSION
+
+#include "pqxx/compiler-public.hxx"
+#include "pqxx/compiler-internal-pre.hxx"
+
+/// Full libpqxx version string.
+#define PQXX_VERSION "6.4.4"
+/// Library ABI version.
+#define PQXX_ABI "6.4"
+
+/// Major version number.
+#define PQXX_VERSION_MAJOR 6
+/// Minor version number.
+#define PQXX_VERSION_MINOR 4
+
+namespace pqxx
+{
+namespace internal
+{
+/// Library version check stub.
+/** Helps detect version mismatches between libpqxx headers and the libpqxx
+ * library binary.
+ *
+ * Sometimes users run into trouble linking their code against libpqxx because
+ * they build their own libpqxx, but the system also has a different version
+ * installed. The declarations in the headers against which they compile their
+ * code will differ from the ones used to build the libpqxx version they're
+ * using, leading to confusing link errors. The solution is to generate a link
+ * error when the libpqxx binary is not the same version as the libpqxx headers
+ * used to compile the code.
+ *
+ * This is a template declaration, but its only actual definition is a
+ * sepcialisation for the current library version. The definition is in the
+ * libpqxx binary, so it's based on the version as found in the binary. The
+ * headers contain a call to the function, specialised on the libpqxx version
+ * as found in the headers. (The library build process will use its own local
+ * headers even if another version of the headers is installed on the system.)
+ *
+ * If the libpqxx binary was compiled for a different version than the user's
+ * code, linking will fail with an error: @c check_library_version will not
+ * exist for the given version number.
+ */
+template<int, int> PQXX_LIBEXPORT int check_library_version() noexcept;
+}
+}
+#include "pqxx/compiler-internal-post.hxx"
+#endif
diff --git a/contrib/libs/libpqxx/src/array.cxx b/contrib/libs/libpqxx/src/array.cxx
new file mode 100644
index 0000000000..c16c7ae586
--- /dev/null
+++ b/contrib/libs/libpqxx/src/array.cxx
@@ -0,0 +1,312 @@
+/** Handling of SQL arrays.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <utility>
+
+#include "pqxx/array"
+#include "pqxx/except"
+
+
+namespace pqxx
+{
+/// Scan to next glyph in the buffer. Assumes there is one.
+std::string::size_type array_parser::scan_glyph(
+ std::string::size_type pos) const
+{
+ assert(pos < m_end);
+ return m_scan(m_input, m_end, pos);
+}
+
+
+/// Scan to next glyph in a substring. Assumes there is one.
+std::string::size_type array_parser::scan_glyph(
+ std::string::size_type pos,
+ std::string::size_type end) const
+{
+ assert(pos < end);
+ assert(end <= m_end);
+ return m_scan(m_input, end, pos);
+}
+
+
+/// Find the end of a single-quoted SQL string in an SQL array.
+/** Returns the offset of the first character after the closing quote.
+ */
+std::string::size_type array_parser::scan_single_quoted_string() const
+{
+ auto here = m_pos, next = scan_glyph(here);
+ assert(next < m_end);
+ assert(next - here == 1);
+ assert(m_input[here] == '\'');
+ for (
+ here = next, next = scan_glyph(here);
+ here < m_end;
+ here = next, next = scan_glyph(here)
+ )
+ {
+ if (next - here == 1) switch (m_input[here])
+ {
+ case '\'':
+ // SQL escapes single quotes by doubling them. Terrible idea, but it's
+ // what we have. Inspect the next character to find out whether this is
+ // the closing quote, or an escaped one inside the string.
+ here = next;
+ // (We can read beyond this quote because the array will always end in
+ // a closing brace.)
+ next = scan_glyph(here);
+
+ if ((here + 1 < next) or (m_input[here] != '\''))
+ {
+ // Our lookahead character is not an escaped quote. It's the first
+ // character outside our string. So, return it.
+ return here;
+ }
+
+ // We've just scanned an escaped quote. Keep going.
+ break;
+
+ case '\\':
+ // Backslash escape. Skip ahead by one more character.
+ here = next;
+ next = scan_glyph(here);
+ break;
+ }
+ }
+ throw argument_error{"Null byte in SQL string: " + std::string{m_input}};
+}
+
+
+/// Parse a single-quoted SQL string: un-quote it and un-escape it.
+std::string array_parser::parse_single_quoted_string(
+ std::string::size_type end) const
+{
+ // There have to be at least 2 characters: the opening and closing quotes.
+ assert(m_pos + 1 < end);
+ assert(m_input[m_pos] == '\'');
+ assert(m_input[end - 1] == '\'');
+
+ std::string output;
+ // Maximum output size is same as the input size, minus the opening and
+ // closing quotes. In the worst case, the real number could be half that.
+ // Usually it'll be a pretty close estimate.
+ output.reserve(end - m_pos - 2);
+ for (
+ auto here = m_pos + 1, next = scan_glyph(here, end);
+ here < end - 1;
+ here = next, next = scan_glyph(here, end)
+ )
+ {
+ if (
+ next - here == 1 and
+ (m_input[here] == '\'' or m_input[here] == '\\')
+ )
+ {
+ // Skip escape.
+ here = next;
+ next = scan_glyph(here, end);
+ }
+
+ output.append(m_input + here, m_input + next);
+ }
+
+ return output;
+}
+
+
+/// Find the end of a double-quoted SQL string in an SQL array.
+std::string::size_type array_parser::scan_double_quoted_string() const
+{
+ auto here = m_pos;
+ assert(here < m_end);
+ auto next = scan_glyph(here);
+ assert(next - here == 1);
+ assert(m_input[here] == '"');
+ for (
+ here = next, next = scan_glyph(here);
+ here < m_end;
+ here = next, next = scan_glyph(here)
+ )
+ {
+ if (next - here == 1) switch (m_input[here])
+ {
+ case '\\':
+ // Backslash escape. Skip ahead by one more character.
+ here = next;
+ next = scan_glyph(here);
+ break;
+
+ case '"':
+ // Closing quote. Return the position right after.
+ return next;
+ }
+ }
+ throw argument_error{"Null byte in SQL string: " + std::string{m_input}};
+}
+
+
+/// Parse a double-quoted SQL string: un-quote it and un-escape it.
+std::string array_parser::parse_double_quoted_string(
+ std::string::size_type end) const
+{
+ // There have to be at least 2 characters: the opening and closing quotes.
+ assert(m_pos + 1 < end);
+ assert(m_input[m_pos] == '"');
+ assert(m_input[end - 1] == '"');
+
+ std::string output;
+ // Maximum output size is same as the input size, minus the opening and
+ // closing quotes. In the worst case, the real number could be half that.
+ // Usually it'll be a pretty close estimate.
+ output.reserve(std::size_t(end - m_pos - 2));
+
+ for (
+ auto here = scan_glyph(m_pos, end), next = scan_glyph(here, end);
+ here < end - 1;
+ here = next, next = scan_glyph(here, end)
+ )
+ {
+ if ((next - here == 1) and (m_input[here] == '\\'))
+ {
+ // Skip escape.
+ here = next;
+ next = scan_glyph(here, end);
+ }
+
+ output.append(m_input + here, m_input + next);
+ }
+
+ return output;
+}
+
+
+/// Find the end of an unquoted string in an SQL array.
+/** Assumes UTF-8 or an ASCII-superset single-byte encoding.
+ */
+std::string::size_type array_parser::scan_unquoted_string() const
+{
+ auto here = m_pos, next = scan_glyph(here);
+ assert(here < m_end);
+ assert((next - here > 1) or (m_input[here] != '\''));
+ assert((next - here > 1) or (m_input[here] != '"'));
+
+ while (
+ (next - here) > 1 or
+ (
+ m_input[here] != ',' and
+ m_input[here] != ';' and
+ m_input[here] != '}'
+ )
+ )
+ {
+ here = next;
+ next = scan_glyph(here);
+ }
+ return here;
+}
+
+
+/// Parse an unquoted SQL string.
+/** Here, the special unquoted value NULL means a null value, not a string
+ * that happens to spell "NULL".
+ */
+std::string array_parser::parse_unquoted_string(
+ std::string::size_type end) const
+{
+ return std::string{m_input + m_pos, m_input + end};
+}
+
+
+array_parser::array_parser(
+ const char input[],
+ internal::encoding_group enc) :
+ m_input(input),
+ m_end(input == nullptr ? 0 : std::strlen(input)),
+ m_scan(internal::get_glyph_scanner(enc)),
+ m_pos(0)
+{
+}
+
+
+std::pair<array_parser::juncture, std::string>
+array_parser::get_next()
+{
+ juncture found;
+ std::string value;
+ std::string::size_type end;
+
+ if (m_input == nullptr or (m_pos >= m_end))
+ return std::make_pair(juncture::done, value);
+
+ if (scan_glyph(m_pos) - m_pos > 1)
+ {
+ // Non-ASCII unquoted string.
+ end = scan_unquoted_string();
+ value = parse_unquoted_string(end);
+ found = juncture::string_value;
+ }
+ else switch (m_input[m_pos])
+ {
+ case '\0':
+ // TODO: Maybe just raise an error?
+ found = juncture::done;
+ end = m_pos;
+ break;
+ case '{':
+ found = juncture::row_start;
+ end = scan_glyph(m_pos);
+ break;
+ case '}':
+ found = juncture::row_end;
+ end = scan_glyph(m_pos);
+ break;
+ case '\'':
+ found = juncture::string_value;
+ end = scan_single_quoted_string();
+ value = parse_single_quoted_string(end);
+ break;
+ case '"':
+ found = juncture::string_value;
+ end = scan_double_quoted_string();
+ value = parse_double_quoted_string(end);
+ break;
+ default:
+ end = scan_unquoted_string();
+ value = parse_unquoted_string(end);
+ if (value == "NULL")
+ {
+ // In this one situation, as a special case, NULL means a null field,
+ // not a string that happens to spell "NULL".
+ value.clear();
+ found = juncture::null_value;
+ }
+ else
+ {
+ // The normal case: we just parsed an unquoted string. The value is
+ // what we need.
+ found = juncture::string_value;
+ }
+ break;
+ }
+
+ // Skip a trailing field separator, if present.
+ if (end < m_end)
+ {
+ auto next = scan_glyph(end);
+ if (next - end == 1 and (m_input[end] == ',' or m_input[end] == ';'))
+ end = next;
+ }
+
+ m_pos = end;
+ return std::make_pair(found, value);
+}
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/src/binarystring.cxx b/contrib/libs/libpqxx/src/binarystring.cxx
new file mode 100644
index 0000000000..0091f48baf
--- /dev/null
+++ b/contrib/libs/libpqxx/src/binarystring.cxx
@@ -0,0 +1,150 @@
+/** Implementation of bytea (binary string) conversions.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+#include <stdexcept>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/binarystring"
+#include "pqxx/field"
+
+
+using namespace pqxx::internal;
+
+namespace
+{
+using unsigned_char = unsigned char;
+using buffer = std::pair<unsigned char *, size_t>;
+
+
+buffer to_buffer(const void *data, size_t len)
+{
+ void *const output{malloc(len + 1)};
+ if (output == nullptr) throw std::bad_alloc{};
+ static_cast<char *>(output)[len] = '\0';
+ memcpy(static_cast<char *>(output), data, len);
+ return buffer{static_cast<unsigned char *>(output), len};
+}
+
+
+buffer to_buffer(const std::string &source)
+{
+ return to_buffer(source.c_str(), source.size());
+}
+
+
+
+buffer unescape(const unsigned char escaped[])
+{
+#ifdef _WIN32
+ /* On Windows only, the return value from PQunescapeBytea() must be freed
+ * using PQfreemem. Copy to a buffer allocated by libpqxx, so that the
+ * binarystring's buffer can be freed uniformly,
+ */
+ size_t unescaped_len = 0;
+ // TODO: Use make_unique once we require C++14. Sooo much easier.
+ std::unique_ptr<unsigned char, void(*)(unsigned char *)> A(
+ PQunescapeBytea(const_cast<unsigned char *>(escaped), &unescaped_len),
+ freepqmem_templated<unsigned char>);
+ void *data = A.get();
+ if (data == nullptr) throw std::bad_alloc{};
+ return to_buffer(data, unescaped_len);
+#else
+ /* On non-Windows platforms, it's okay to free libpq-allocated memory using
+ * free(). No extra copy needed.
+ */
+ buffer unescaped;
+ unescaped.first = PQunescapeBytea(
+ const_cast<unsigned char *>(escaped), &unescaped.second);
+ if (unescaped.first == nullptr) throw std::bad_alloc{};
+ return unescaped;
+#endif
+}
+
+} // namespace
+
+
+pqxx::binarystring::binarystring(const field &F) :
+ m_buf{make_smart_pointer()},
+ m_size{0}
+{
+ buffer unescaped{unescape(reinterpret_cast<const_pointer>(F.c_str()))};
+ m_buf = make_smart_pointer(unescaped.first);
+ m_size = unescaped.second;
+}
+
+
+pqxx::binarystring::binarystring(const std::string &s) :
+ m_buf{make_smart_pointer()},
+ m_size{s.size()}
+{
+ m_buf = make_smart_pointer(to_buffer(s).first);
+}
+
+
+pqxx::binarystring::binarystring(const void *binary_data, size_t len) :
+ m_buf{make_smart_pointer()},
+ m_size{len}
+{
+ m_buf = make_smart_pointer(to_buffer(binary_data, len).first);
+}
+
+
+bool pqxx::binarystring::operator==(const binarystring &rhs) const noexcept
+{
+ if (rhs.size() != size()) return false;
+ return std::memcmp(data(), rhs.data(), size()) == 0;
+}
+
+
+pqxx::binarystring &pqxx::binarystring::operator=(const binarystring &rhs)
+{
+ m_buf = rhs.m_buf;
+ m_size = rhs.m_size;
+ return *this;
+}
+
+
+pqxx::binarystring::const_reference pqxx::binarystring::at(size_type n) const
+{
+ if (n >= m_size)
+ {
+ if (m_size == 0)
+ throw std::out_of_range{"Accessing empty binarystring"};
+ throw std::out_of_range{
+ "binarystring index out of range: " +
+ to_string(n) + " (should be below " + to_string(m_size) + ")"};
+ }
+ return data()[n];
+}
+
+
+void pqxx::binarystring::swap(binarystring &rhs)
+{
+ m_buf.swap(rhs.m_buf);
+
+ // This part very obviously can't go wrong, so do it last
+ const auto s = m_size;
+ m_size = rhs.m_size;
+ rhs.m_size = s;
+}
+
+
+std::string pqxx::binarystring::str() const
+{
+ return std::string{get(), m_size};
+}
diff --git a/contrib/libs/libpqxx/src/connection.cxx b/contrib/libs/libpqxx/src/connection.cxx
new file mode 100644
index 0000000000..982b6d60f9
--- /dev/null
+++ b/contrib/libs/libpqxx/src/connection.cxx
@@ -0,0 +1,182 @@
+/** Implementation of the pqxx::connection and sibling classes.
+ *
+ * Different ways of setting up a backend connection.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <stdexcept>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/connection"
+
+
+pqxx::connectionpolicy::connectionpolicy(const std::string &opts) :
+ m_options{opts}
+{
+}
+
+
+pqxx::connectionpolicy::~connectionpolicy() noexcept
+{
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connectionpolicy::normalconnect(handle orig)
+{
+ if (orig) return orig;
+ orig = PQconnectdb(options().c_str());
+ if (orig == nullptr) throw std::bad_alloc{};
+ if (PQstatus(orig) != CONNECTION_OK)
+ {
+ const std::string msg{PQerrorMessage(orig)};
+ PQfinish(orig);
+ throw broken_connection{msg};
+ }
+ return orig;
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connectionpolicy::do_startconnect(handle orig)
+{
+ return orig;
+}
+
+pqxx::connectionpolicy::handle
+pqxx::connectionpolicy::do_completeconnect(handle orig)
+{
+ return orig;
+}
+
+pqxx::connectionpolicy::handle
+pqxx::connectionpolicy::do_dropconnect(handle orig) noexcept
+{
+ return orig;
+}
+
+pqxx::connectionpolicy::handle
+pqxx::connectionpolicy::do_disconnect(handle orig) noexcept
+{
+ orig = do_dropconnect(orig);
+ if (orig) PQfinish(orig);
+ return nullptr;
+}
+
+
+bool pqxx::connectionpolicy::is_ready(handle h) const noexcept
+{
+ return h != nullptr;
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connect_direct::do_startconnect(handle orig)
+{
+ if (orig) return orig;
+ orig = normalconnect(orig);
+ if (PQstatus(orig) != CONNECTION_OK)
+ {
+ const std::string msg{PQerrorMessage(orig)};
+ do_disconnect(orig);
+ throw broken_connection{msg};
+ }
+ return orig;
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connect_lazy::do_completeconnect(handle orig)
+{
+ return normalconnect(orig);
+}
+
+
+pqxx::connect_async::connect_async(const std::string &opts) :
+ connectionpolicy{opts},
+ m_connecting{false}
+{
+}
+
+pqxx::connectionpolicy::handle
+pqxx::connect_async::do_startconnect(handle orig)
+{
+ if (orig != nullptr) return orig; // Already connecting or connected.
+ m_connecting = false;
+ orig = PQconnectStart(options().c_str());
+ if (orig == nullptr) throw std::bad_alloc{};
+ if (PQstatus(orig) == CONNECTION_BAD)
+ {
+ do_dropconnect(orig);
+ throw broken_connection{std::string{PQerrorMessage(orig)}};
+ }
+ m_connecting = true;
+ return orig;
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connect_async::do_completeconnect(handle orig)
+{
+ const bool makenew = (orig == nullptr);
+ if (makenew) orig = do_startconnect(orig);
+ if (not m_connecting) return orig;
+
+ // Our "attempt to connect" state ends here, for better or for worse
+ m_connecting = false;
+
+ PostgresPollingStatusType pollstatus = PGRES_POLLING_WRITING;
+
+ do
+ {
+ switch (pollstatus)
+ {
+ case PGRES_POLLING_FAILED:
+ if (makenew) do_disconnect(orig);
+ throw broken_connection{std::string{PQerrorMessage(orig)}};
+
+ case PGRES_POLLING_READING:
+ internal::wait_read(orig);
+ break;
+
+ case PGRES_POLLING_WRITING:
+ internal::wait_write(orig);
+ break;
+
+ case PGRES_POLLING_OK:
+ break;
+
+ default:
+ // Meaningless, really, but deals with the obsolete PGRES_POLLING_ACTIVE
+ // without requiring it to be defined.
+ break;
+ }
+ pollstatus = PQconnectPoll(orig);
+ } while (pollstatus != PGRES_POLLING_OK);
+
+ return orig;
+}
+
+
+pqxx::connectionpolicy::handle
+pqxx::connect_async::do_dropconnect(handle orig) noexcept
+{
+ m_connecting = false;
+ return orig;
+}
+
+
+bool pqxx::connect_async::is_ready(handle h) const noexcept
+{
+ return h != nullptr and not m_connecting;
+}
diff --git a/contrib/libs/libpqxx/src/connection_base.cxx b/contrib/libs/libpqxx/src/connection_base.cxx
new file mode 100644
index 0000000000..345e3414ee
--- /dev/null
+++ b/contrib/libs/libpqxx/src/connection_base.cxx
@@ -0,0 +1,1475 @@
+/** Implementation of the pqxx::connection_base abstract base class.
+ *
+ * pqxx::connection_base encapsulates a frontend to backend connection.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+
+#if defined(_WIN32)
+// Includes for WSAPoll().
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mstcpip.h>
+#elif defined(HAVE_POLL)
+// Include for poll().
+#include <poll.h>
+#elif defined(HAVE_SYS_SELECT_H)
+// Include for select() on (recent) POSIX systems.
+#include <sys/select.h>
+#else
+// Includes for select() according to various older standards.
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#endif
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/binarystring"
+#include "pqxx/connection"
+#include "pqxx/connection_base"
+#include "pqxx/nontransaction"
+#include "pqxx/pipeline"
+#include "pqxx/result"
+#include "pqxx/strconv"
+#include "pqxx/transaction"
+#include "pqxx/notification"
+
+#include "pqxx/internal/gates/connection-reactivation_avoidance_exemption.hxx"
+#include "pqxx/internal/gates/errorhandler-connection.hxx"
+#include "pqxx/internal/gates/result-creation.hxx"
+#include "pqxx/internal/gates/result-connection.hxx"
+
+using namespace pqxx;
+using namespace pqxx::internal;
+using namespace pqxx::prepare;
+
+
+extern "C"
+{
+// The PQnoticeProcessor that receives an error or warning from libpq and sends
+// it to the appropriate connection for processing.
+void pqxx_notice_processor(void *conn, const char *msg) noexcept
+{
+ reinterpret_cast<pqxx::connection_base *>(conn)->process_notice(msg);
+}
+
+
+// There's no way in libpq to disable a connection's notice processor. So,
+// set an inert one to get the same effect.
+void inert_notice_processor(void *, const char *) noexcept {}
+}
+
+
+std::string pqxx::encrypt_password(
+ const std::string &user, const std::string &password)
+{
+ std::unique_ptr<char, void (*)(char *)> p{
+ PQencryptPassword(password.c_str(), user.c_str()),
+ freepqmem_templated<char>};
+ return std::string{p.get()};
+}
+
+
+void pqxx::connection_base::init()
+{
+ m_conn = m_policy.do_startconnect(m_conn);
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ if (m_policy.is_ready(m_conn)) activate();
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+}
+
+
+pqxx::result pqxx::connection_base::make_result(
+ internal::pq::PGresult *rhs,
+ const std::string &query)
+{
+ return gate::result_creation::create(
+ rhs,
+ query,
+ internal::enc_group(encoding_id()));
+}
+
+
+int pqxx::connection_base::backendpid() const noexcept
+{
+ return m_conn ? PQbackendPID(m_conn) : 0;
+}
+
+
+namespace
+{
+PQXX_PURE int socket_of(const ::pqxx::internal::pq::PGconn *c) noexcept
+{
+ return c ? PQsocket(c) : -1;
+}
+}
+
+
+int pqxx::connection_base::sock() const noexcept
+{
+ return socket_of(m_conn);
+}
+
+
+void pqxx::connection_base::activate()
+{
+ if (not is_open())
+ {
+ if (m_inhibit_reactivation)
+ throw broken_connection{
+ "Could not reactivate connection; "
+ "reactivation is inhibited"};
+
+ // If any objects were open that didn't survive the closing of our
+ // connection, don't try to reactivate
+ if (m_reactivation_avoidance.get()) return;
+
+ try
+ {
+ m_conn = m_policy.do_startconnect(m_conn);
+ m_conn = m_policy.do_completeconnect(m_conn);
+ m_completed = true; // (But retracted if error is thrown below)
+
+ if (not is_open()) throw broken_connection{};
+
+ set_up_state();
+ }
+ catch (const broken_connection &e)
+ {
+ disconnect();
+ m_completed = false;
+ throw broken_connection{e.what()};
+ }
+ catch (const std::exception &)
+ {
+ m_completed = false;
+ throw;
+ }
+ }
+}
+
+
+void pqxx::connection_base::deactivate()
+{
+ if (m_conn == nullptr) return;
+
+ if (m_trans.get())
+ throw usage_error{
+ "Attempt to deactivate connection while " +
+ m_trans.get()->description() + " still open"};
+
+ if (m_reactivation_avoidance.get())
+ {
+ process_notice(
+ "Attempt to deactivate connection while it is in a state "
+ "that cannot be fully recovered later (ignoring)");
+ return;
+ }
+
+ m_completed = false;
+ m_conn = m_policy.do_disconnect(m_conn);
+}
+
+
+void pqxx::connection_base::simulate_failure()
+{
+ if (m_conn)
+ {
+ m_conn = m_policy.do_disconnect(m_conn);
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ inhibit_reactivation(true);
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ }
+}
+
+
+int pqxx::connection_base::protocol_version() const noexcept
+{
+ return m_conn ? PQprotocolVersion(m_conn) : 0;
+}
+
+
+int pqxx::connection_base::server_version() const noexcept
+{
+ return m_serverversion;
+}
+
+
+void pqxx::connection_base::set_variable(const std::string &Var,
+ const std::string &Value)
+{
+ if (m_trans.get())
+ {
+ // We're in a transaction. The variable should go in there.
+ m_trans.get()->set_variable(Var, Value);
+ }
+ else
+ {
+ // We're not in a transaction. Set a session variable.
+ if (is_open()) raw_set_var(Var, Value);
+ m_vars[Var] = Value;
+ }
+}
+
+
+std::string pqxx::connection_base::get_variable(const std::string &Var)
+{
+ return m_trans.get() ? m_trans.get()->get_variable(Var) : raw_get_var(Var);
+}
+
+
+std::string pqxx::connection_base::raw_get_var(const std::string &Var)
+{
+ // Is this variable in our local map of set variables?
+ const auto i = m_vars.find(Var);
+ if (i != m_vars.end()) return i->second;
+
+ return exec(("SHOW " + Var).c_str(), 0).at(0).at(0).as(std::string{});
+}
+
+
+void pqxx::connection_base::clearcaps() noexcept
+{
+ m_caps.reset();
+}
+
+
+/** Set up various parts of logical connection state that may need to be
+ * recovered because the physical connection to the database was lost and is
+ * being reset, or that may not have been initialized yet.
+ */
+void pqxx::connection_base::set_up_state()
+{
+ if (m_conn == nullptr)
+ throw internal_error{"set_up_state() on no connection"};
+
+ if (status() != CONNECTION_OK)
+ {
+ const auto msg = err_msg();
+ m_conn = m_policy.do_disconnect(m_conn);
+ throw failure{msg};
+ }
+
+ read_capabilities();
+
+ for (auto &p: m_prepared) p.second.registered = false;
+
+ // The default notice processor in libpq writes to stderr. Ours does
+ // nothing.
+ // If the caller registers an error handler, this gets replaced with an
+ // error handler that walks down the connection's chain of handlers. We
+ // don't do that by default because there's a danger: libpq may call the
+ // notice processor via a result object, even after the connection has been
+ // destroyed and the handlers list no longer exists.
+ clear_notice_processor();
+
+ internal_set_trace();
+
+ if (not m_receivers.empty() or not m_vars.empty())
+ {
+ std::stringstream restore_query;
+
+ // Pipeline all queries needed to restore receivers and variables, so we can
+ // send them over in one go.
+
+ // Reinstate all active receivers
+ if (not m_receivers.empty())
+ {
+ std::string Last;
+ for (auto &i: m_receivers)
+ {
+ // m_receivers can handle multiple receivers waiting on the same event;
+ // issue just one LISTEN for each event.
+ if (i.first != Last)
+ {
+ restore_query << "LISTEN " << quote_name(i.first) << "; ";
+ Last = i.first;
+ }
+ }
+ }
+
+ for (auto &i: m_vars)
+ restore_query << "SET " << i.first << "=" << i.second << "; ";
+
+ // Now do the whole batch at once
+ PQsendQuery(m_conn, restore_query.str().c_str());
+ result r;
+ do
+ r = make_result(PQgetResult(m_conn), "[RECONNECT]");
+ while (gate::result_connection(r));
+ }
+
+ m_completed = true;
+ if (not is_open()) throw broken_connection{};
+}
+
+
+void pqxx::connection_base::check_result(const result &R)
+{
+ if (not is_open()) throw broken_connection{};
+
+ // A shame we can't quite detect out-of-memory to turn this into a bad_alloc!
+ if (not gate::result_connection{R}) throw failure(err_msg());
+
+ gate::result_creation{R}.check_status();
+}
+
+
+void pqxx::connection_base::disconnect() noexcept
+{
+ // When we activate again, the server may be different!
+ clearcaps();
+
+ m_conn = m_policy.do_disconnect(m_conn);
+}
+
+
+bool pqxx::connection_base::is_open() const noexcept
+{
+ return m_conn and m_completed and (status() == CONNECTION_OK);
+}
+
+
+void pqxx::connection_base::process_notice_raw(const char msg[]) noexcept
+{
+ if ((msg == nullptr) or (*msg == '\0')) return;
+ const auto
+ rbegin = m_errorhandlers.crbegin(),
+ rend = m_errorhandlers.crend();
+ for (auto i = rbegin; (i != rend) and (**i)(msg); ++i) ;
+}
+
+
+void pqxx::connection_base::process_notice(const char msg[]) noexcept
+{
+ if (msg == nullptr) return;
+ const auto len = strlen(msg);
+ if (len == 0) return;
+ if (msg[len-1] == '\n')
+ {
+ process_notice_raw(msg);
+ }
+ else try
+ {
+ // Newline is missing. Try the C++ string version of this function.
+ process_notice(std::string{msg});
+ }
+ catch (const std::exception &)
+ {
+ // If we can't even do that, use plain old buffer copying instead
+ // (unavoidably, this will break up overly long messages!)
+ const char separator[] = "[...]\n";
+ char buf[1007];
+ size_t bytes = sizeof(buf)-sizeof(separator)-1;
+ size_t written;
+ strcpy(&buf[bytes], separator);
+ // Write all chunks but last. Each will fill the buffer exactly.
+ for (written = 0; (written+bytes) < len; written += bytes)
+ {
+ memcpy(buf, &msg[written], bytes);
+ process_notice_raw(buf);
+ }
+ // Write any remaining bytes (which won't fill an entire buffer)
+ bytes = len-written;
+ memcpy(buf, &msg[written], bytes);
+ // Add trailing nul byte, plus newline unless there already is one
+ strcpy(&buf[bytes], &"\n"[buf[bytes-1]=='\n']);
+ process_notice_raw(buf);
+ }
+}
+
+
+void pqxx::connection_base::process_notice(const std::string &msg) noexcept
+{
+ // Ensure that message passed to errorhandler ends in newline
+ if (msg[msg.size()-1] == '\n')
+ {
+ process_notice_raw(msg.c_str());
+ }
+ else try
+ {
+ const std::string nl = msg + "\n";
+ process_notice_raw(nl.c_str());
+ }
+ catch (const std::exception &)
+ {
+ // If nothing else works, try writing the message without the newline
+ process_notice_raw(msg.c_str());
+ // This is ugly.
+ process_notice_raw("\n");
+ }
+}
+
+
+void pqxx::connection_base::trace(FILE *Out) noexcept
+{
+ m_trace = Out;
+ if (m_conn) internal_set_trace();
+}
+
+
+void pqxx::connection_base::add_receiver(pqxx::notification_receiver *T)
+{
+ if (T == nullptr) throw argument_error{"Null receiver registered"};
+
+ // Add to receiver list and attempt to start listening.
+ const auto p = m_receivers.find(T->channel());
+ const receiver_list::value_type NewVal(T->channel(), T);
+
+ if (p == m_receivers.end())
+ {
+ // Not listening on this event yet, start doing so.
+ const std::string LQ("LISTEN " + quote_name(T->channel()));
+
+ if (is_open()) try
+ {
+ check_result(make_result(PQexec(m_conn, LQ.c_str()), LQ));
+ }
+ catch (const broken_connection &)
+ {
+ }
+ m_receivers.insert(NewVal);
+ }
+ else
+ {
+ m_receivers.insert(p, NewVal);
+ }
+}
+
+
+void pqxx::connection_base::remove_receiver(pqxx::notification_receiver *T)
+ noexcept
+{
+ if (T == nullptr) return;
+
+ try
+ {
+ const std::pair<const std::string, notification_receiver *> needle{
+ T->channel(), T};
+ auto R = m_receivers.equal_range(needle.first);
+ const auto i = find(R.first, R.second, needle);
+
+ if (i == R.second)
+ {
+ process_notice(
+ "Attempt to remove unknown receiver '" + needle.first + "'");
+ }
+ else
+ {
+ // Erase first; otherwise a notification for the same receiver may yet
+ // come in and wreak havoc. Thanks Dragan Milenkovic.
+ const bool gone = (m_conn and (R.second == ++R.first));
+ m_receivers.erase(i);
+ if (gone) exec(("UNLISTEN " + quote_name(needle.first)).c_str(), 0);
+ }
+ }
+ catch (const std::exception &e)
+ {
+ process_notice(e.what());
+ }
+}
+
+
+bool pqxx::connection_base::consume_input() noexcept
+{
+ return PQconsumeInput(m_conn) != 0;
+}
+
+
+bool pqxx::connection_base::is_busy() const noexcept
+{
+ return PQisBusy(m_conn) != 0;
+}
+
+
+namespace
+{
+/// Stateful libpq "cancel" operation.
+class cancel_wrapper
+{
+ PGcancel *m_cancel;
+ char m_errbuf[500];
+
+public:
+ explicit cancel_wrapper(PGconn *conn) :
+ m_cancel{nullptr},
+ m_errbuf{}
+ {
+ if (conn)
+ {
+ m_cancel = PQgetCancel(conn);
+ if (m_cancel == nullptr) throw std::bad_alloc{};
+ }
+ }
+ ~cancel_wrapper() { if (m_cancel) PQfreeCancel(m_cancel); }
+
+ void operator()()
+ {
+ if (not m_cancel) return;
+ if (PQcancel(m_cancel, m_errbuf, int{sizeof(m_errbuf)}) == 0)
+ throw sql_error{std::string{m_errbuf}};
+ }
+};
+}
+
+
+void pqxx::connection_base::cancel_query()
+{
+ cancel_wrapper cancel{m_conn};
+ cancel();
+}
+
+
+void pqxx::connection_base::set_verbosity(error_verbosity verbosity) noexcept
+{
+ PQsetErrorVerbosity(m_conn, static_cast<PGVerbosity>(verbosity));
+ m_verbosity = verbosity;
+}
+
+
+namespace
+{
+/// Unique pointer to PGnotify.
+using notify_ptr = std::unique_ptr<PGnotify, void (*)(PGnotify *)>;
+
+
+/// Get one notification from a connection, or null.
+notify_ptr get_notif(pqxx::internal::pq::PGconn *conn)
+{
+ return notify_ptr(PQnotifies(conn), freepqmem_templated<PGnotify>);
+}
+}
+
+
+int pqxx::connection_base::get_notifs()
+{
+ if (not is_open()) return 0;
+
+ if (not consume_input()) throw broken_connection{};
+
+ // Even if somehow we receive notifications during our transaction, don't
+ // deliver them.
+ if (m_trans.get()) return 0;
+
+ int notifs = 0;
+ for (auto N = get_notif(m_conn); N.get(); N = get_notif(m_conn))
+ {
+ notifs++;
+
+ const auto Hit = m_receivers.equal_range(std::string{N->relname});
+ for (auto i = Hit.first; i != Hit.second; ++i) try
+ {
+ (*i->second)(N->extra, N->be_pid);
+ }
+ catch (const std::exception &e)
+ {
+ try
+ {
+ process_notice(
+ "Exception in notification receiver '" +
+ i->first +
+ "': " +
+ e.what() +
+ "\n");
+ }
+ catch (const std::bad_alloc &)
+ {
+ // Out of memory. Try to get the message out in a more robust way.
+ process_notice(
+ "Exception in notification receiver, "
+ "and also ran out of memory\n");
+ }
+ catch (const std::exception &)
+ {
+ process_notice(
+ "Exception in notification receiver "
+ "(compounded by other error)\n");
+ }
+ }
+
+ N.reset();
+ }
+ return notifs;
+}
+
+
+const char *pqxx::connection_base::dbname()
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ if (m_conn == nullptr) activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ return PQdb(m_conn);
+}
+
+
+const char *pqxx::connection_base::username()
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ if (m_conn == nullptr) activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ return PQuser(m_conn);
+}
+
+
+const char *pqxx::connection_base::hostname()
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ if (m_conn == nullptr) activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ return PQhost(m_conn);
+}
+
+
+const char *pqxx::connection_base::port()
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ if (m_conn == nullptr) activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ return PQport(m_conn);
+}
+
+
+const char *pqxx::connection_base::err_msg() const noexcept
+{
+ return m_conn ? PQerrorMessage(m_conn) : "No connection to database";
+}
+
+
+void pqxx::connection_base::clear_notice_processor()
+{
+ PQsetNoticeProcessor(m_conn, inert_notice_processor, nullptr);
+}
+
+
+void pqxx::connection_base::set_notice_processor()
+{
+ PQsetNoticeProcessor(m_conn, pqxx_notice_processor, this);
+}
+
+
+void pqxx::connection_base::register_errorhandler(errorhandler *handler)
+{
+ // Set notice processor on demand, i.e. only when the caller actually
+ // registers an error handler.
+ // We do this just to make it less likely that users fall into the trap
+ // where a result object may hold a notice processor derived from its parent
+ // connection which has already been destroyed. Our notice processor goes
+ // through the connection's list of error handlers. If the connection object
+ // has already been destroyed though, that list no longer exists.
+ // By setting the notice processor on demand, we absolve users who never
+ // register an error handler from ahving to care about this nasty subtlety.
+ if (m_errorhandlers.empty()) set_notice_processor();
+ m_errorhandlers.push_back(handler);
+}
+
+
+void pqxx::connection_base::unregister_errorhandler(errorhandler *handler)
+ noexcept
+{
+ // The errorhandler itself will take care of nulling its pointer to this
+ // connection.
+ m_errorhandlers.remove(handler);
+ if (m_errorhandlers.empty()) clear_notice_processor();
+}
+
+
+std::vector<errorhandler *> pqxx::connection_base::get_errorhandlers() const
+{
+ return std::vector<errorhandler *>{
+ std::begin(m_errorhandlers), std::end(m_errorhandlers)};
+}
+
+
+pqxx::result pqxx::connection_base::exec(const char Query[], int Retries)
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+
+ auto R = make_result(PQexec(m_conn, Query), Query);
+
+ while ((Retries > 0) and not gate::result_connection{R} and not is_open())
+ {
+ Retries--;
+ reset();
+ if (is_open()) R = make_result(PQexec(m_conn, Query), Query);
+ }
+
+ check_result(R);
+
+ get_notifs();
+ return R;
+}
+
+
+void pqxx::connection_base::prepare(
+ const std::string &name,
+ const std::string &definition)
+{
+ auto i = m_prepared.find(name);
+ if (i != m_prepared.end())
+ {
+ if (definition != i->second.definition)
+ {
+ if (not name.empty())
+ throw argument_error{
+ "Inconsistent redefinition of prepared statement " + name};
+
+ i->second.registered = false;
+ i->second.definition = definition;
+ }
+ }
+ else
+ {
+ m_prepared.insert(make_pair(
+ name,
+ prepare::internal::prepared_def{definition}));
+ }
+}
+
+
+void pqxx::connection_base::prepare(const std::string &definition)
+{
+ this->prepare(std::string{}, definition);
+}
+
+
+void pqxx::connection_base::unprepare(const std::string &name)
+{
+ auto i = m_prepared.find(name);
+
+ // Quietly ignore duplicated or spurious unprepare()s
+ if (i == m_prepared.end()) return;
+
+ if (i->second.registered)
+ exec(("DEALLOCATE " + quote_name(name)).c_str(), 0);
+
+ m_prepared.erase(i);
+}
+
+
+pqxx::prepare::internal::prepared_def &
+pqxx::connection_base::find_prepared(const std::string &statement)
+{
+ auto s = m_prepared.find(statement);
+ if (s == m_prepared.end())
+ throw argument_error{"Unknown prepared statement '" + statement + "'"};
+ return s->second;
+}
+
+
+pqxx::prepare::internal::prepared_def &
+pqxx::connection_base::register_prepared(const std::string &name)
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ auto &s = find_prepared(name);
+
+ // "Register" (i.e., define) prepared statement with backend on demand
+ if (not s.registered)
+ {
+ auto r = make_result(
+ PQprepare(m_conn, name.c_str(), s.definition.c_str(), 0, nullptr),
+ "[PREPARE " + name + "]");
+ check_result(r);
+ s.registered = not name.empty();
+ return s;
+ }
+
+ return s;
+}
+
+
+void pqxx::connection_base::prepare_now(const std::string &name)
+{
+ register_prepared(name);
+}
+
+
+pqxx::result pqxx::connection_base::prepared_exec(
+ const std::string &statement,
+ const char *const params[],
+ const int paramlengths[],
+ const int binary[],
+ int nparams,
+ result_format format)
+{
+ register_prepared(statement);
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ auto r = make_result(
+ PQexecPrepared(
+ m_conn,
+ statement.c_str(),
+ nparams,
+ params,
+ paramlengths,
+ binary,
+ format == result_format::binary? 1 : 0),
+ statement);
+ check_result(r);
+ get_notifs();
+ return r;
+}
+
+
+pqxx::result pqxx::connection_base::exec_prepared(
+ const std::string &statement,
+ const internal::params &args,
+ result_format format)
+{
+ register_prepared(statement);
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ const auto pointers = args.get_pointers();
+ const auto pq_result = PQexecPrepared(
+ m_conn,
+ statement.c_str(),
+ int(args.nonnulls.size()),
+ pointers.data(),
+ args.lengths.data(),
+ args.binaries.data(),
+ format == result_format::binary? 1 : 0);
+ const auto r = make_result(pq_result, statement);
+ check_result(r);
+ get_notifs();
+ return r;
+}
+
+
+bool pqxx::connection_base::prepared_exists(const std::string &statement) const
+{
+ auto s = m_prepared.find(statement);
+ return s != PSMap::const_iterator(m_prepared.end());
+}
+
+
+void pqxx::connection_base::reset()
+{
+ if (m_inhibit_reactivation)
+ throw broken_connection{
+ "Could not reset connection: reactivation is inhibited"};
+ if (m_reactivation_avoidance.get()) return;
+
+ // TODO: Probably need to go through a full disconnect/reconnect!
+ // Forget about any previously ongoing connection attempts
+ m_conn = m_policy.do_dropconnect(m_conn);
+ m_completed = false;
+
+ if (m_conn)
+ {
+ // Reset existing connection
+ PQreset(m_conn);
+ set_up_state();
+ }
+ else
+ {
+ // No existing connection--start a new one
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ }
+}
+
+
+void pqxx::connection_base::close() noexcept
+{
+ m_completed = false;
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ inhibit_reactivation(false);
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ m_reactivation_avoidance.clear();
+ try
+ {
+ if (m_trans.get())
+ process_notice(
+ "Closing connection while " + m_trans.get()->description() +
+ " still open");
+
+ if (not m_receivers.empty())
+ {
+ process_notice("Closing connection with outstanding receivers.");
+ m_receivers.clear();
+ }
+
+ std::list<errorhandler *> old_handlers;
+ m_errorhandlers.swap(old_handlers);
+ const auto
+ rbegin = old_handlers.crbegin(),
+ rend = old_handlers.crend();
+ for (auto i = rbegin; i!=rend; ++i)
+ gate::errorhandler_connection_base{**i}.unregister();
+
+ m_conn = m_policy.do_disconnect(m_conn);
+ }
+ catch (...)
+ {
+ }
+}
+
+
+void pqxx::connection_base::raw_set_var(
+ const std::string &Var,
+ const std::string &Value)
+{
+ exec(("SET " + Var + "=" + Value).c_str(), 0);
+}
+
+
+void pqxx::connection_base::add_variables(
+ const std::map<std::string,std::string> &Vars)
+{
+ for (auto &i: Vars) m_vars[i.first] = i.second;
+}
+
+
+void pqxx::connection_base::internal_set_trace() noexcept
+{
+ if (m_conn)
+ {
+ if (m_trace) PQtrace(m_conn, m_trace);
+ else PQuntrace(m_conn);
+ }
+}
+
+
+int pqxx::connection_base::status() const noexcept
+{
+ return PQstatus(m_conn);
+}
+
+
+void pqxx::connection_base::register_transaction(transaction_base *T)
+{
+ m_trans.register_guest(T);
+}
+
+
+void pqxx::connection_base::unregister_transaction(transaction_base *T)
+ noexcept
+{
+ try
+ {
+ m_trans.unregister_guest(T);
+ }
+ catch (const std::exception &e)
+ {
+ process_notice(e.what());
+ }
+}
+
+
+bool pqxx::connection_base::read_copy_line(std::string &Line)
+{
+ if (not is_open())
+ throw internal_error{"read_copy_line() without connection"};
+
+ Line.erase();
+ bool Result;
+
+ char *Buf = nullptr;
+ const std::string query = "[END COPY]";
+ const auto line_len = PQgetCopyData(m_conn, &Buf, false);
+ switch (line_len)
+ {
+ case -2:
+ throw failure{"Reading of table data failed: " + std::string{err_msg()}};
+
+ case -1:
+ for (
+ auto R = make_result(PQgetResult(m_conn), query);
+ gate::result_connection(R);
+ R=make_result(PQgetResult(m_conn), query)
+ )
+ check_result(R);
+ Result = false;
+ break;
+
+ case 0:
+ throw internal_error{"table read inexplicably went asynchronous"};
+
+ default:
+ if (Buf)
+ {
+ std::unique_ptr<char, void (*)(char *)> PQA(
+ Buf, freepqmem_templated<char>);
+ Line.assign(Buf, unsigned(line_len));
+ }
+ Result = true;
+ }
+
+ return Result;
+}
+
+
+void pqxx::connection_base::write_copy_line(const std::string &Line)
+{
+ if (not is_open())
+ throw internal_error{"write_copy_line() without connection"};
+
+ const std::string L = Line + '\n';
+ const char *const LC = L.c_str();
+ const auto Len = L.size();
+
+ if (PQputCopyData(m_conn, LC, int(Len)) <= 0)
+ {
+ const std::string msg = (
+ std::string{"Error writing to table: "} + err_msg());
+// TODO: PQendcopy() is documented as obsolete!
+ PQendcopy(m_conn);
+ throw failure{msg};
+ }
+}
+
+
+void pqxx::connection_base::end_copy_write()
+{
+ int Res = PQputCopyEnd(m_conn, nullptr);
+ switch (Res)
+ {
+ case -1:
+ throw failure{"Write to table failed: " + std::string{err_msg()}};
+ case 0:
+ throw internal_error{"table write is inexplicably asynchronous"};
+ case 1:
+ // Normal termination. Retrieve result object.
+ break;
+
+ default:
+ throw internal_error{
+ "unexpected result " + to_string(Res) + " from PQputCopyEnd()"};
+ }
+
+ check_result(make_result(PQgetResult(m_conn), "[END COPY]"));
+}
+
+
+void pqxx::connection_base::start_exec(const std::string &Q)
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ if (PQsendQuery(m_conn, Q.c_str()) == 0) throw failure{err_msg()};
+}
+
+
+pqxx::internal::pq::PGresult *pqxx::connection_base::get_result()
+{
+ if (m_conn == nullptr) throw broken_connection{};
+ return PQgetResult(m_conn);
+}
+
+
+void pqxx::connection_base::add_reactivation_avoidance_count(int n)
+{
+ m_reactivation_avoidance.add(n);
+}
+
+
+std::string pqxx::connection_base::esc(const char str[], size_t maxlen)
+{
+ // We need a connection object... This is the one reason why this function is
+ // not const!
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ if (m_conn == nullptr) activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+
+ std::vector<char> buf(2 * maxlen + 1);
+ int err = 0;
+ // TODO: Can we make a callback-based string_view alternative to this?
+ // TODO: If we can, then quote() can wrap PQescapeLiteral()!
+ PQescapeStringConn(m_conn, buf.data(), str, maxlen, &err);
+ if (err) throw argument_error{err_msg()};
+ return std::string{buf.data()};
+}
+
+
+std::string pqxx::connection_base::esc(const char str[])
+{
+ return this->esc(str, strlen(str));
+}
+
+
+std::string pqxx::connection_base::esc(const std::string &str)
+{
+ return this->esc(str.c_str(), str.size());
+}
+
+
+std::string pqxx::connection_base::esc_raw(
+ const unsigned char str[],
+ size_t len)
+{
+ size_t bytes = 0;
+ // We need a connection object... This is the one reason why this function is
+ // not const!
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+
+ std::unique_ptr<unsigned char, void (*)(unsigned char *)> buf{
+ PQescapeByteaConn(m_conn, str, len, &bytes),
+ freepqmem_templated<unsigned char>};
+ if (buf.get() == nullptr) throw std::bad_alloc{};
+ return std::string{reinterpret_cast<char *>(buf.get())};
+}
+
+
+std::string pqxx::connection_base::unesc_raw(const char *text)
+{
+ size_t len;
+ unsigned char *bytes = const_cast<unsigned char *>(
+ reinterpret_cast<const unsigned char *>(text));
+ const std::unique_ptr<unsigned char, decltype(internal::freepqmem)*> ptr{
+ PQunescapeBytea(bytes, &len),
+ internal::freepqmem};
+ return std::string{ptr.get(), ptr.get() + len};
+}
+
+
+std::string pqxx::connection_base::quote_raw(
+ const unsigned char str[],
+ size_t len)
+{
+ return "'" + esc_raw(str, len) + "'::bytea";
+}
+
+
+std::string pqxx::connection_base::quote(const binarystring &b)
+{
+ return quote_raw(b.data(), b.size());
+}
+
+
+std::string pqxx::connection_base::quote_name(const std::string &identifier)
+{
+ // We need a connection object... This is the one reason why this function is
+ // not const!
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ std::unique_ptr<char, void (*)(char *)> buf{
+ PQescapeIdentifier(m_conn, identifier.c_str(), identifier.size()),
+ freepqmem_templated<char>};
+ if (buf.get() == nullptr) throw failure{err_msg()};
+ return std::string{buf.get()};
+}
+
+
+std::string pqxx::connection_base::esc_like(
+ const std::string &str,
+ char escape_char) const
+{
+ std::string out;
+ out.reserve(str.size());
+ internal::for_glyphs(
+ internal::enc_group(encoding_id()),
+ [&out, escape_char](const char *gbegin, const char *gend)
+ {
+ if ((gend - gbegin == 1) and (*gbegin == '_' or *gbegin == '%'))
+ out.push_back(escape_char);
+
+ for (; gbegin != gend; ++gbegin) out.push_back(*gbegin);
+ },
+ str.c_str(),
+ str.size());
+ return out;
+}
+
+
+pqxx::internal::reactivation_avoidance_exemption::
+ reactivation_avoidance_exemption(
+ connection_base &C) :
+ m_home{C},
+ m_count{gate::connection_reactivation_avoidance_exemption(C).get_counter()},
+ m_open{C.is_open()}
+{
+ gate::connection_reactivation_avoidance_exemption gate{C};
+ gate.clear_counter();
+}
+
+
+pqxx::internal::reactivation_avoidance_exemption::
+ ~reactivation_avoidance_exemption()
+{
+ // Don't leave the connection open if reactivation avoidance is in effect and
+ // the connection needed to be reactivated temporarily.
+ if (m_count and not m_open)
+ {
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ m_home.deactivate();
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+ }
+ gate::connection_reactivation_avoidance_exemption gate{m_home};
+ gate.add_counter(m_count);
+}
+
+
+namespace
+{
+#if defined(_WIN32) || defined(HAVE_POLL)
+// Convert a timeval to milliseconds, or -1 if no timeval is given.
+inline int tv_milliseconds(timeval *tv = nullptr)
+{
+ return tv ? int(tv->tv_sec * 1000 + tv->tv_usec/1000) : -1;
+}
+#endif
+
+
+/// Wait for an fd to become free for reading/writing. Optional timeout.
+void wait_fd(int fd, bool forwrite=false, timeval *tv=nullptr)
+{
+ if (fd < 0) throw pqxx::broken_connection{};
+
+// WSAPoll is available in winsock2.h only for versions of Windows >= 0x0600
+#if defined(_WIN32) && (_WIN32_WINNT >= 0x0600)
+ const short events = (forwrite ? POLLWRNORM : POLLRDNORM);
+ WSAPOLLFD fdarray{SOCKET(fd), events, 0};
+ WSAPoll(&fdarray, 1, tv_milliseconds(tv));
+#elif defined(HAVE_POLL)
+ const short events = short(
+ POLLERR|POLLHUP|POLLNVAL | (forwrite?POLLOUT:POLLIN));
+ pollfd pfd{fd, events, 0};
+ poll(&pfd, 1, tv_milliseconds(tv));
+#else
+ // No poll()? Our last option is select().
+ fd_set read_fds;
+ FD_ZERO(&read_fds);
+ if (not forwrite) FD_SET(fd, &read_fds);
+
+ fd_set write_fds;
+ FD_ZERO(&write_fds);
+ if (forwrite) FD_SET(fd, &write_fds);
+
+ fd_set except_fds;
+ FD_ZERO(&except_fds);
+ FD_SET(fd, &except_fds);
+
+ select(fd+1, &read_fds, &write_fds, &except_fds, tv);
+#endif
+
+ // No need to report errors. The caller will try to use the file
+ // descriptor right after we return, so if the file descriptor is broken,
+ // the caller will notice soon enough.
+}
+} // namespace
+
+void pqxx::internal::wait_read(const internal::pq::PGconn *c)
+{
+ wait_fd(socket_of(c));
+}
+
+
+void pqxx::internal::wait_read(
+ const internal::pq::PGconn *c,
+ long seconds,
+ long microseconds)
+{
+ // These are really supposed to be time_t and suseconds_t. But not all
+ // platforms have that type; some use "long" instead, and some 64-bit
+ // systems use 32-bit integers here. So "int" seems to be the only really
+ // safe type to use.
+ timeval tv = { time_t(seconds), int(microseconds) };
+ wait_fd(socket_of(c), false, &tv);
+}
+
+
+void pqxx::internal::wait_write(const internal::pq::PGconn *c)
+{
+ wait_fd(socket_of(c), true);
+}
+
+
+void pqxx::connection_base::wait_read() const
+{
+ internal::wait_read(m_conn);
+}
+
+
+void pqxx::connection_base::wait_read(long seconds, long microseconds) const
+{
+ internal::wait_read(m_conn, seconds, microseconds);
+}
+
+
+void pqxx::connection_base::wait_write() const
+{
+ internal::wait_write(m_conn);
+}
+
+
+int pqxx::connection_base::await_notification()
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ int notifs = get_notifs();
+ if (notifs == 0)
+ {
+ wait_read();
+ notifs = get_notifs();
+ }
+ return notifs;
+}
+
+
+int pqxx::connection_base::await_notification(long seconds, long microseconds)
+{
+#include <pqxx/internal/ignore-deprecated-pre.hxx>
+ activate();
+#include <pqxx/internal/ignore-deprecated-post.hxx>
+ int notifs = get_notifs();
+ if (notifs == 0)
+ {
+ wait_read(seconds, microseconds);
+ notifs = get_notifs();
+ }
+ return notifs;
+}
+
+
+void pqxx::connection_base::read_capabilities()
+{
+ m_serverversion = PQserverVersion(m_conn);
+ if (m_serverversion <= 90000)
+ throw feature_not_supported{
+ "Unsupported server version; 9.0 is the minimum."};
+
+ switch (protocol_version()) {
+ case 0:
+ throw broken_connection{};
+ case 1:
+ case 2:
+ throw feature_not_supported{
+ "Unsupported frontend/backend protocol version; 3.0 is the minimum."};
+ default:
+ break;
+ }
+
+ // TODO: Check for capabilities here. Currently don't need any checks.
+}
+
+
+std::string pqxx::connection_base::adorn_name(const std::string &n)
+{
+ const std::string id = to_string(++m_unique_id);
+ return n.empty() ? ("x"+id) : (n+"_"+id);
+}
+
+
+std::string pqxx::connection_base::get_client_encoding() const
+{
+ return internal::name_encoding(encoding_id());
+}
+
+
+void pqxx::connection_base::set_client_encoding(const char encoding[])
+{
+ const auto retval = PQsetClientEncoding(m_conn, encoding);
+ switch (retval)
+ {
+ case 0:
+ // OK.
+ break;
+ case -1:
+ // TODO: Any helpful information we could give here?
+ throw failure{"Setting client encoding failed."};
+ default:
+ throw internal_error{
+ "Unexpected result from PQsetClientEncoding: " + to_string(retval)};
+ }
+}
+
+
+void pqxx::connection_base::set_client_encoding(const std::string &encoding)
+{
+ set_client_encoding(encoding.c_str());
+}
+
+
+int pqxx::connection_base::encoding_id() const
+{
+ const int enc = PQclientEncoding(m_conn);
+ if (enc == -1)
+ {
+ if (not is_open())
+ throw broken_connection{
+ "Could not obtain client encoding: not connected."};
+ throw failure{"Could not obtain client encoding."};
+ }
+ return enc;
+}
+
+
+pqxx::result pqxx::connection_base::parameterized_exec(
+ const std::string &query,
+ const char *const params[],
+ const int paramlengths[],
+ const int binaries[],
+ int nparams)
+{
+ auto r = make_result(
+ PQexecParams(
+ m_conn,
+ query.c_str(),
+ nparams,
+ nullptr,
+ params,
+ paramlengths,
+ binaries,
+ 0),
+ query);
+ check_result(r);
+ get_notifs();
+ return r;
+}
+
+
+pqxx::result pqxx::connection_base::exec_params(
+ const std::string &query,
+ const internal::params &args)
+{
+ const auto pointers = args.get_pointers();
+ const auto pq_result = PQexecParams(
+ m_conn,
+ query.c_str(),
+ int(args.nonnulls.size()),
+ nullptr,
+ pointers.data(),
+ args.lengths.data(),
+ args.binaries.data(),
+ 0);
+ const auto r = make_result(pq_result, query);
+ check_result(r);
+ get_notifs();
+ return r;
+}
diff --git a/contrib/libs/libpqxx/src/cursor.cxx b/contrib/libs/libpqxx/src/cursor.cxx
new file mode 100644
index 0000000000..8d2c7dfb25
--- /dev/null
+++ b/contrib/libs/libpqxx/src/cursor.cxx
@@ -0,0 +1,321 @@
+/** Implementation of libpqxx STL-style cursor classes.
+ *
+ * These classes wrap SQL cursors in STL-like interfaces.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <iterator>
+
+#include "pqxx/cursor"
+#include "pqxx/result"
+#include "pqxx/strconv"
+#include "pqxx/transaction"
+
+#include "pqxx/internal/gates/icursor_iterator-icursorstream.hxx"
+#include "pqxx/internal/gates/icursorstream-icursor_iterator.hxx"
+
+using namespace pqxx;
+using namespace pqxx::internal;
+
+
+pqxx::cursor_base::difference_type pqxx::cursor_base::all() noexcept
+{
+ // Implemented out-of-line so we don't fall afoul of Visual Studio defining
+ // min() and max() macros, which turn this expression into malformed code:
+ return std::numeric_limits<int>::max() - 1;
+}
+
+
+pqxx::cursor_base::difference_type cursor_base::backward_all() noexcept
+{
+ // Implemented out-of-line so we don't fall afoul of Visual Studio defining
+ // min() and max() macros, which turn this expression into malformed code:
+ return std::numeric_limits<int>::min() + 1;
+}
+
+
+pqxx::cursor_base::cursor_base(
+ connection_base &context,
+ const std::string &Name,
+ bool embellish_name) :
+ m_name{embellish_name ? context.adorn_name(Name) : Name}
+{
+}
+
+
+result::size_type pqxx::internal::obtain_stateless_cursor_size(sql_cursor &cur)
+{
+ if (cur.endpos() == -1) cur.move(cursor_base::all());
+ return result::size_type(cur.endpos() - 1);
+}
+
+
+result pqxx::internal::stateless_cursor_retrieve(
+ sql_cursor &cur,
+ result::difference_type size,
+ result::difference_type begin_pos,
+ result::difference_type end_pos)
+{
+ if (begin_pos < 0 or begin_pos > size)
+ throw range_error{"Starting position out of range"};
+
+ if (end_pos < -1) end_pos = -1;
+ else if (end_pos > size) end_pos = size;
+
+ if (begin_pos == end_pos) return cur.empty_result();
+
+ const int direction = ((begin_pos < end_pos) ? 1 : -1);
+ cur.move((begin_pos-direction) - (cur.pos()-1));
+ return cur.fetch(end_pos - begin_pos);
+}
+
+
+pqxx::icursorstream::icursorstream(
+ transaction_base &context,
+ const std::string &query,
+ const std::string &basename,
+ difference_type sstride) :
+ m_cur{context,
+ query,
+ basename,
+ cursor_base::forward_only,
+ cursor_base::read_only,
+ cursor_base::owned,
+ false},
+ m_stride{sstride},
+ m_realpos{0},
+ m_reqpos{0},
+ m_iterators{nullptr},
+ m_done{false}
+{
+ set_stride(sstride);
+}
+
+
+pqxx::icursorstream::icursorstream(
+ transaction_base &context,
+ const field &cname,
+ difference_type sstride,
+ cursor_base::ownershippolicy op) :
+ m_cur{context, cname.c_str(), op},
+ m_stride{sstride},
+ m_realpos{0},
+ m_reqpos{0},
+ m_iterators{nullptr},
+ m_done{false}
+{
+ set_stride(sstride);
+}
+
+
+void pqxx::icursorstream::set_stride(difference_type n)
+{
+ if (n < 1)
+ throw argument_error{"Attempt to set cursor stride to " + to_string(n)};
+ m_stride = n;
+}
+
+result pqxx::icursorstream::fetchblock()
+{
+ const result r{m_cur.fetch(m_stride)};
+ m_realpos += r.size();
+ if (r.empty()) m_done = true;
+ return r;
+}
+
+
+icursorstream &pqxx::icursorstream::ignore(std::streamsize n)
+{
+ auto offset = m_cur.move(difference_type(n));
+ m_realpos += offset;
+ if (offset < n) m_done = true;
+ return *this;
+}
+
+
+icursorstream::size_type pqxx::icursorstream::forward(size_type n)
+{
+ m_reqpos += difference_type(n) * m_stride;
+ return icursorstream::size_type(m_reqpos);
+}
+
+
+void pqxx::icursorstream::insert_iterator(icursor_iterator *i) noexcept
+{
+ gate::icursor_iterator_icursorstream{*i}.set_next(m_iterators);
+ if (m_iterators)
+ gate::icursor_iterator_icursorstream{*m_iterators}.set_prev(i);
+ m_iterators = i;
+}
+
+
+void pqxx::icursorstream::remove_iterator(icursor_iterator *i) const noexcept
+{
+ gate::icursor_iterator_icursorstream igate{*i};
+ if (i == m_iterators)
+ {
+ m_iterators = igate.get_next();
+ if (m_iterators)
+ gate::icursor_iterator_icursorstream{*m_iterators}.set_prev(nullptr);
+ }
+ else
+ {
+ auto prev = igate.get_prev(), next = igate.get_next();
+ gate::icursor_iterator_icursorstream{*prev}.set_next(next);
+ if (next) gate::icursor_iterator_icursorstream{*next}.set_prev(prev);
+ }
+ igate.set_prev(nullptr);
+ igate.set_next(nullptr);
+}
+
+
+void pqxx::icursorstream::service_iterators(difference_type topos)
+{
+ if (topos < m_realpos) return;
+
+ using todolist = std::multimap<difference_type,icursor_iterator*>;
+ todolist todo;
+ for (icursor_iterator *i = m_iterators, *next; i; i = next)
+ {
+ gate::icursor_iterator_icursorstream gate{*i};
+ const auto ipos = gate.pos();
+ if (ipos >= m_realpos and ipos <= topos)
+ todo.insert(todolist::value_type(ipos, i));
+ next = gate.get_next();
+ }
+ const auto todo_end = std::end(todo);
+ for (auto i = std::begin(todo); i != todo_end; )
+ {
+ const auto readpos = i->first;
+ if (readpos > m_realpos) ignore(readpos - m_realpos);
+ const result r = fetchblock();
+ for ( ; i != todo_end and i->first == readpos; ++i)
+ gate::icursor_iterator_icursorstream{*i->second}.fill(r);
+ }
+}
+
+
+pqxx::icursor_iterator::icursor_iterator() noexcept :
+ m_pos{0}
+{
+}
+
+
+pqxx::icursor_iterator::icursor_iterator(istream_type &s) noexcept :
+ m_stream{&s},
+ m_pos{difference_type(gate::icursorstream_icursor_iterator(s).forward(0))}
+{
+ gate::icursorstream_icursor_iterator{*m_stream}.insert_iterator(this);
+}
+
+
+pqxx::icursor_iterator::icursor_iterator(const icursor_iterator &rhs)
+ noexcept :
+ m_stream{rhs.m_stream},
+ m_here{rhs.m_here},
+ m_pos{rhs.m_pos}
+{
+ if (m_stream)
+ gate::icursorstream_icursor_iterator{*m_stream}.insert_iterator(this);
+}
+
+
+pqxx::icursor_iterator::~icursor_iterator() noexcept
+{
+ if (m_stream)
+ gate::icursorstream_icursor_iterator{*m_stream}.remove_iterator(this);
+}
+
+
+icursor_iterator pqxx::icursor_iterator::operator++(int)
+{
+ icursor_iterator old{*this};
+ m_pos = difference_type(
+ gate::icursorstream_icursor_iterator{*m_stream}.forward());
+ m_here.clear();
+ return old;
+}
+
+
+icursor_iterator &pqxx::icursor_iterator::operator++()
+{
+ m_pos = difference_type(
+ gate::icursorstream_icursor_iterator{*m_stream}.forward());
+ m_here.clear();
+ return *this;
+}
+
+
+icursor_iterator &pqxx::icursor_iterator::operator+=(difference_type n)
+{
+ if (n <= 0)
+ {
+ if (n == 0) return *this;
+ throw argument_error{"Advancing icursor_iterator by negative offset."};
+ }
+ m_pos = difference_type(
+ gate::icursorstream_icursor_iterator{*m_stream}.forward(
+ icursorstream::size_type(n)));
+ m_here.clear();
+ return *this;
+}
+
+
+icursor_iterator &
+pqxx::icursor_iterator::operator=(const icursor_iterator &rhs) noexcept
+{
+ if (rhs.m_stream == m_stream)
+ {
+ m_here = rhs.m_here;
+ m_pos = rhs.m_pos;
+ }
+ else
+ {
+ if (m_stream)
+ gate::icursorstream_icursor_iterator{*m_stream}.remove_iterator(this);
+ m_here = rhs.m_here;
+ m_pos = rhs.m_pos;
+ m_stream = rhs.m_stream;
+ if (m_stream)
+ gate::icursorstream_icursor_iterator{*m_stream}.insert_iterator(this);
+ }
+ return *this;
+}
+
+
+bool pqxx::icursor_iterator::operator==(const icursor_iterator &rhs) const
+{
+ if (m_stream == rhs.m_stream) return pos() == rhs.pos();
+ if (m_stream and rhs.m_stream) return false;
+ refresh();
+ rhs.refresh();
+ return m_here.empty() and rhs.m_here.empty();
+}
+
+
+bool pqxx::icursor_iterator::operator<(const icursor_iterator &rhs) const
+{
+ if (m_stream == rhs.m_stream) return pos() < rhs.pos();
+ refresh();
+ rhs.refresh();
+ return not m_here.empty();
+}
+
+
+void pqxx::icursor_iterator::refresh() const
+{
+ if (m_stream)
+ gate::icursorstream_icursor_iterator{*m_stream}.service_iterators(pos());
+}
+
+
+void pqxx::icursor_iterator::fill(const result &r)
+{
+ m_here = r;
+}
diff --git a/contrib/libs/libpqxx/src/dbtransaction.cxx b/contrib/libs/libpqxx/src/dbtransaction.cxx
new file mode 100644
index 0000000000..9d0938a181
--- /dev/null
+++ b/contrib/libs/libpqxx/src/dbtransaction.cxx
@@ -0,0 +1,99 @@
+/** Implementation of the pqxx::dbtransaction class.
+ *
+ * pqxx::dbtransaction represents a real backend transaction.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/dbtransaction"
+
+#include "pqxx/internal/gates/connection-dbtransaction.hxx"
+
+using namespace pqxx::internal;
+
+
+namespace
+{
+std::string generate_set_transaction(
+ pqxx::readwrite_policy rw,
+ const std::string &IsolationString=std::string{})
+{
+ std::string args;
+
+ if (not IsolationString.empty())
+ if (IsolationString != pqxx::isolation_traits<pqxx::read_committed>::name())
+ args += " ISOLATION LEVEL " + IsolationString;
+
+ if (rw != pqxx::read_write) args += " READ ONLY";
+
+ return args.empty() ? "BEGIN" : ("BEGIN; SET TRANSACTION" + args);
+}
+} // namespace
+
+
+pqxx::dbtransaction::dbtransaction(
+ connection_base &C,
+ const std::string &IsolationString,
+ readwrite_policy rw) :
+ namedclass{"dbtransaction"},
+ transaction_base{C},
+ m_start_cmd{generate_set_transaction(rw, IsolationString)}
+{
+}
+
+
+pqxx::dbtransaction::dbtransaction(
+ connection_base &C,
+ bool direct,
+ readwrite_policy rw) :
+ namedclass{"dbtransaction"},
+ transaction_base(C, direct),
+ m_start_cmd{generate_set_transaction(rw)}
+{
+}
+
+
+pqxx::dbtransaction::~dbtransaction()
+{
+}
+
+
+void pqxx::dbtransaction::do_begin()
+{
+ const gate::connection_dbtransaction gate(conn());
+ const int avoidance_counter = gate.get_reactivation_avoidance_count();
+ direct_exec(m_start_cmd.c_str(), avoidance_counter ? 0 : 2);
+}
+
+
+pqxx::result pqxx::dbtransaction::do_exec(const char Query[])
+{
+ try
+ {
+ return direct_exec(Query);
+ }
+ catch (const std::exception &)
+ {
+ try { abort(); } catch (const std::exception &) {}
+ throw;
+ }
+}
+
+
+void pqxx::dbtransaction::do_abort()
+{
+ reactivation_avoidance_clear();
+ direct_exec("ROLLBACK");
+}
+
+
+std::string pqxx::dbtransaction::fullname(const std::string &ttype,
+ const std::string &isolation)
+{
+ return ttype + "<" + isolation + ">";
+}
diff --git a/contrib/libs/libpqxx/src/encodings.cxx b/contrib/libs/libpqxx/src/encodings.cxx
new file mode 100644
index 0000000000..7102c891c4
--- /dev/null
+++ b/contrib/libs/libpqxx/src/encodings.cxx
@@ -0,0 +1,826 @@
+/** Implementation of string encodings support
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/except.hxx"
+#include "pqxx/internal/encodings.hxx"
+
+#include <cstring>
+#include <iomanip>
+#include <map>
+#include <sstream>
+
+using namespace pqxx::internal;
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+
+// Internal helper functions
+namespace
+{
+/// Extract byte from buffer, return as unsigned char.
+unsigned char get_byte(const char buffer[], std::string::size_type offset)
+{
+ return static_cast<unsigned char>(buffer[offset]);
+}
+
+
+[[noreturn]] void throw_for_encoding_error(
+ const char* encoding_name,
+ const char buffer[],
+ std::string::size_type start,
+ std::string::size_type count
+)
+{
+ std::stringstream s;
+ s
+ << "Invalid byte sequence for encoding "
+ << encoding_name
+ << " at byte "
+ << start
+ << ": "
+ << std::hex
+ << std::setw(2)
+ << std::setfill('0')
+ ;
+ for (std::string::size_type i{0}; i < count; ++i)
+ {
+ s << "0x" << static_cast<unsigned int>(get_byte(buffer, start + i));
+ if (i + 1 < count) s << " ";
+ }
+ throw pqxx::argument_error{s.str()};
+}
+
+
+/// Does value lie between bottom and top, inclusive?
+constexpr bool between_inc(unsigned char value, unsigned bottom, unsigned top)
+{
+ return value >= bottom and value <= top;
+}
+
+
+/*
+EUC-JP and EUC-JIS-2004 represent slightly different code points but iterate
+the same:
+ * https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-JP
+ * http://x0213.org/codetable/index.en.html
+*/
+std::string::size_type next_seq_for_euc_jplike(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start,
+ const char encoding_name[])
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error(encoding_name, buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (byte1 == 0x8e)
+ {
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error(encoding_name, buffer, start, 2);
+
+ return start + 2;
+ }
+
+ if (between_inc(byte1, 0xa1, 0xfe))
+ {
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error(encoding_name, buffer, start, 2);
+
+ return start + 2;
+ }
+
+ if (byte1 == 0x8f and start + 3 <= buffer_len)
+ {
+ const auto byte3 = get_byte(buffer, start + 2);
+ if (
+ not between_inc(byte2, 0xa1, 0xfe) or
+ not between_inc(byte3, 0xa1, 0xfe)
+ )
+ throw_for_encoding_error(encoding_name, buffer, start, 3);
+
+ return start + 3;
+ }
+
+ throw_for_encoding_error(encoding_name, buffer, start, 1);
+}
+
+/*
+As far as I can tell, for the purposes of iterating the only difference between
+SJIS and SJIS-2004 is increased range in the first byte of two-byte sequences
+(0xEF increased to 0xFC). Officially, that is; apparently the version of SJIS
+used by Postgres has the same range as SJIS-2004. They both have increased
+range over the documented versions, not having the even/odd restriction for the
+first byte in 2-byte sequences.
+*/
+// https://en.wikipedia.org/wiki/Shift_JIS#Shift_JIS_byte_map
+// http://x0213.org/codetable/index.en.html
+std::string::size_type next_seq_for_sjislike(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start,
+ const char* encoding_name
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80 or between_inc(byte1, 0xa1, 0xdf)) return start + 1;
+
+ if (
+ not between_inc(byte1, 0x81, 0x9f) and
+ not between_inc(byte1, 0xe0, 0xfc)
+ )
+ throw_for_encoding_error(encoding_name, buffer, start, 1);
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error(
+ encoding_name,
+ buffer,
+ start,
+ buffer_len - start);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (byte2 == 0x7f) throw_for_encoding_error(encoding_name, buffer, start, 2);
+
+ if (between_inc(byte2, 0x40, 0x9e) or between_inc(byte2, 0x9f, 0xfc))
+ return start + 2;
+
+ throw_for_encoding_error(encoding_name, buffer, start, 2);
+}
+} // namespace
+
+
+// Implement template specializations first
+namespace pqxx
+{
+namespace internal
+{
+template<encoding_group> struct glyph_scanner
+{
+ static std::string::size_type call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start);
+};
+
+template<>
+std::string::size_type glyph_scanner<encoding_group::MONOBYTE>::call(
+ const char /* buffer */[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+ else return start + 1;
+}
+
+// https://en.wikipedia.org/wiki/Big5#Organization
+template<> std::string::size_type glyph_scanner<encoding_group::BIG5>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (not between_inc(byte1, 0x81, 0xfe) or (start + 2 > buffer_len))
+ throw_for_encoding_error("BIG5", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (
+ not between_inc(byte2, 0x40, 0x7e) and
+ not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error("BIG5", buffer, start, 2);
+
+ return start + 2;
+}
+
+/*
+The PostgreSQL documentation claims that the EUC_* encodings are 1-3 bytes each,
+but other documents explain that the EUC sets can contain 1-(2,3,4) bytes
+depending on the specific extension:
+ EUC_CN : 1-2
+ EUC_JP : 1-3
+ EUC_JIS_2004: 1-2
+ EUC_KR : 1-2
+ EUC_TW : 1-4
+*/
+
+// https://en.wikipedia.org/wiki/GB_2312#EUC-CN
+template<> std::string::size_type glyph_scanner<encoding_group::EUC_CN>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (not between_inc(byte1, 0xa1, 0xf7) or start + 2 > buffer_len)
+ throw_for_encoding_error("EUC_CN", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error("EUC_CN", buffer, start, 2);
+
+ return start + 2;
+}
+
+template<> std::string::size_type glyph_scanner<encoding_group::EUC_JP>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ return next_seq_for_euc_jplike(buffer, buffer_len, start, "EUC_JP");
+}
+
+template<>
+std::string::size_type glyph_scanner<encoding_group::EUC_JIS_2004>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ return next_seq_for_euc_jplike(buffer, buffer_len, start, "EUC_JIS_2004");
+}
+
+// https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-KR
+template<> std::string::size_type glyph_scanner<encoding_group::EUC_KR>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (not between_inc(byte1, 0xa1, 0xfe) or start + 2 > buffer_len)
+ throw_for_encoding_error("EUC_KR", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error("EUC_KR", buffer, start, 1);
+
+ return start + 2;
+}
+
+// https://en.wikipedia.org/wiki/Extended_Unix_Code#EUC-TW
+template<> std::string::size_type glyph_scanner<encoding_group::EUC_TW>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("EUC_KR", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (between_inc(byte1, 0xa1, 0xfe))
+ {
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error("EUC_KR", buffer, start, 2);
+
+ return start + 2;
+ }
+
+ if (byte1 != 0x8e or start + 4 > buffer_len)
+ throw_for_encoding_error("EUC_KR", buffer, start, 1);
+
+ if (
+ between_inc(byte2, 0xa1, 0xb0) and
+ between_inc(get_byte(buffer, start + 2), 0xa1, 0xfe) and
+ between_inc(get_byte(buffer, start + 3), 0xa1, 0xfe)
+ )
+ return start + 4;
+
+ throw_for_encoding_error("EUC_KR", buffer, start, 4);
+}
+
+// https://en.wikipedia.org/wiki/GB_18030#Mapping
+template<> std::string::size_type glyph_scanner<encoding_group::GB18030>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (between_inc(byte1, 0x80, 0xff)) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("GB18030", buffer, start, buffer_len - start);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (between_inc(byte2, 0x40, 0xfe))
+ {
+ if (byte2 == 0x7f)
+ throw_for_encoding_error("GB18030", buffer, start, 2);
+
+ return start + 2;
+ }
+
+ if (start + 4 > buffer_len)
+ throw_for_encoding_error("GB18030", buffer, start, buffer_len - start);
+
+ if (
+ between_inc(byte2, 0x30, 0x39) and
+ between_inc(get_byte(buffer, start + 2), 0x81, 0xfe) and
+ between_inc(get_byte(buffer, start + 3), 0x30, 0x39)
+ )
+ return start + 4;
+
+ throw_for_encoding_error("GB18030", buffer, start, 4);
+}
+
+// https://en.wikipedia.org/wiki/GBK_(character_encoding)#Encoding
+template<> std::string::size_type glyph_scanner<encoding_group::GBK>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("GBK", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (
+ (between_inc(byte1, 0xa1, 0xa9) and between_inc(byte2, 0xa1, 0xfe))
+ or
+ (between_inc(byte1, 0xb0, 0xf7) and between_inc(byte2, 0xa1, 0xfe))
+ or
+ (
+ between_inc(byte1, 0x81, 0xa0) and
+ between_inc(byte2, 0x40, 0xfe) and
+ byte2 != 0x7f
+ )
+ or
+ (
+ between_inc(byte1, 0xaa, 0xfe) and
+ between_inc(byte2, 0x40, 0xa0) and
+ byte2 != 0x7f
+ )
+ or
+ (
+ between_inc(byte1, 0xa8, 0xa9) and
+ between_inc(byte2, 0x40, 0xa0) and
+ byte2 != 0x7f
+ )
+ or
+ (between_inc(byte1, 0xaa, 0xaf) and between_inc(byte2, 0xa1, 0xfe))
+ or
+ (between_inc(byte1, 0xf8, 0xfe) and between_inc(byte2, 0xa1, 0xfe))
+ or
+ (
+ between_inc(byte1, 0xa1, 0xa7) and
+ between_inc(byte2, 0x40, 0xa0) and
+ byte2 != 0x7f
+ )
+ )
+ return start + 2;
+
+ throw_for_encoding_error("GBK", buffer, start, 2);
+}
+
+/*
+The PostgreSQL documentation claims that the JOHAB encoding is 1-3 bytes, but
+"CJKV Information Processing" describes it (actually just the Hangul portion)
+as "three five-bit segments" that reside inside 16 bits (2 bytes).
+
+CJKV Information Processing by Ken Lunde, pg. 269:
+
+ https://bit.ly/2BEOu5V
+*/
+template<> std::string::size_type glyph_scanner<encoding_group::JOHAB>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("JOHAB", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start);
+ if (
+ (
+ between_inc(byte1, 0x84, 0xd3) and
+ (between_inc(byte2, 0x41, 0x7e) or between_inc(byte2, 0x81, 0xfe))
+ )
+ or
+ (
+ (between_inc(byte1, 0xd8, 0xde) or between_inc(byte1, 0xe0, 0xf9)) and
+ (between_inc(byte2, 0x31, 0x7e) or between_inc(byte2, 0x91, 0xfe))
+ )
+ )
+ return start + 2;
+
+ throw_for_encoding_error("JOHAB", buffer, start, 2);
+}
+
+/*
+PostgreSQL's MULE_INTERNAL is the emacs rather than Xemacs implementation;
+see the server/mb/pg_wchar.h PostgreSQL header file.
+This is implemented according to the description in said header file, but I was
+unable to get it to successfully iterate a MULE-encoded test CSV generated using
+PostgreSQL 9.2.23. Use this at your own risk.
+*/
+template<>
+std::string::size_type glyph_scanner<encoding_group::MULE_INTERNAL>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("MULE_INTERNAL", buffer, start, 1);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (between_inc(byte1, 0x81, 0x8d) and byte2 >= 0xA0)
+ return start + 2;
+
+ if (start + 3 > buffer_len)
+ throw_for_encoding_error("MULE_INTERNAL", buffer, start, 2);
+
+ if (
+ (
+ (byte1 == 0x9A and between_inc(byte2, 0xa0, 0xdf)) or
+ (byte1 == 0x9B and between_inc(byte2, 0xe0, 0xef)) or
+ (between_inc(byte1, 0x90, 0x99) and byte2 >= 0xa0)
+ )
+ and
+ (
+ byte2 >= 0xA0
+ )
+ )
+ return start + 3;
+
+ if (start + 4 > buffer_len)
+ throw_for_encoding_error("MULE_INTERNAL", buffer, start, 3);
+
+ if (
+ (
+ (byte1 == 0x9C and between_inc(byte2, 0xf0, 0xf4)) or
+ (byte1 == 0x9D and between_inc(byte2, 0xf5, 0xfe))
+ )
+ and
+ get_byte(buffer, start + 2) >= 0xa0 and
+ get_byte(buffer, start + 4) >= 0xa0
+ )
+ return start + 4;
+
+ throw_for_encoding_error("MULE_INTERNAL", buffer, start, 4);
+}
+
+template<> std::string::size_type glyph_scanner<encoding_group::SJIS>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ return next_seq_for_sjislike(buffer, buffer_len, start, "SJIS");
+}
+
+template<>
+std::string::size_type glyph_scanner<encoding_group::SHIFT_JIS_2004>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ return next_seq_for_sjislike(buffer, buffer_len, start, "SHIFT_JIS_2004");
+}
+
+// https://en.wikipedia.org/wiki/Unified_Hangul_Code
+template<> std::string::size_type glyph_scanner<encoding_group::UHC>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("UHC", buffer, start, buffer_len - start);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (between_inc(byte1, 0x80, 0xc6))
+ {
+ if (
+ between_inc(byte2, 0x41, 0x5a) or
+ between_inc(byte2, 0x61, 0x7a) or
+ between_inc(byte2, 0x80, 0xfe)
+ )
+ return start + 2;
+
+ throw_for_encoding_error("UHC", buffer, start, 2);
+ }
+
+ if (between_inc(byte1, 0xa1, 0xfe))
+ {
+ if (not between_inc(byte2, 0xa1, 0xfe))
+ throw_for_encoding_error("UHC", buffer, start, 2);
+
+ return start + 2;
+ }
+
+ throw_for_encoding_error("UHC", buffer, start, 1);
+}
+
+// https://en.wikipedia.org/wiki/UTF-8#Description
+template<> std::string::size_type glyph_scanner<encoding_group::UTF8>::call(
+ const char buffer[],
+ std::string::size_type buffer_len,
+ std::string::size_type start
+)
+{
+ if (start >= buffer_len) return std::string::npos;
+
+ const auto byte1 = get_byte(buffer, start);
+ if (byte1 < 0x80) return start + 1;
+
+ if (start + 2 > buffer_len)
+ throw_for_encoding_error("UTF8", buffer, start, buffer_len - start);
+
+ const auto byte2 = get_byte(buffer, start + 1);
+ if (between_inc(byte1, 0xc0, 0xdf))
+ {
+ if (not between_inc(byte2, 0x80, 0xbf))
+ throw_for_encoding_error("UTF8", buffer, start, 2);
+
+ return start + 2;
+ }
+
+ if (start + 3 > buffer_len)
+ throw_for_encoding_error("UTF8", buffer, start, buffer_len - start);
+
+ const auto byte3 = get_byte(buffer, start + 2);
+ if (between_inc(byte1, 0xe0, 0xef))
+ {
+ if (between_inc(byte2, 0x80, 0xbf) and between_inc(byte3, 0x80, 0xbf))
+ return start + 3;
+
+ throw_for_encoding_error("UTF8", buffer, start, 3);
+ }
+
+ if (start + 4 > buffer_len)
+ throw_for_encoding_error("UTF8", buffer, start, buffer_len - start);
+
+ if (between_inc(byte1, 0xf0, 0xf7))
+ {
+ if (
+ between_inc(byte2, 0x80, 0xbf) and
+ between_inc(byte3, 0x80, 0xbf) and
+ between_inc(get_byte(buffer, start + 3), 0x80, 0xbf)
+ )
+ return start + 4;
+
+ throw_for_encoding_error("UTF8", buffer, start, 4);
+ }
+
+ throw_for_encoding_error("UTF8", buffer, start, 1);
+}
+
+
+const char *name_encoding(int encoding_id)
+{
+ return pg_encoding_to_char(encoding_id);
+}
+
+
+encoding_group enc_group(int libpq_enc_id)
+{
+ return enc_group(name_encoding(libpq_enc_id));
+}
+
+
+encoding_group enc_group(const std::string& encoding_name)
+{
+ static const std::map<std::string, encoding_group> encoding_map{
+ {"BIG5", encoding_group::BIG5},
+ {"EUC_CN", encoding_group::EUC_CN},
+ {"EUC_JP", encoding_group::EUC_JP},
+ {"EUC_JIS_2004", encoding_group::EUC_JIS_2004},
+ {"EUC_KR", encoding_group::EUC_KR},
+ {"EUC_TW", encoding_group::EUC_TW},
+ {"GB18030", encoding_group::GB18030},
+ {"GBK", encoding_group::GBK},
+ {"ISO_8859_5", encoding_group::MONOBYTE},
+ {"ISO_8859_6", encoding_group::MONOBYTE},
+ {"ISO_8859_7", encoding_group::MONOBYTE},
+ {"ISO_8859_8", encoding_group::MONOBYTE},
+ {"JOHAB", encoding_group::JOHAB},
+ {"KOI8R", encoding_group::MONOBYTE},
+ {"KOI8U", encoding_group::MONOBYTE},
+ {"LATIN1", encoding_group::MONOBYTE},
+ {"LATIN2", encoding_group::MONOBYTE},
+ {"LATIN3", encoding_group::MONOBYTE},
+ {"LATIN4", encoding_group::MONOBYTE},
+ {"LATIN5", encoding_group::MONOBYTE},
+ {"LATIN6", encoding_group::MONOBYTE},
+ {"LATIN7", encoding_group::MONOBYTE},
+ {"LATIN8", encoding_group::MONOBYTE},
+ {"LATIN9", encoding_group::MONOBYTE},
+ {"LATIN10", encoding_group::MONOBYTE},
+ {"MULE_INTERNAL", encoding_group::MULE_INTERNAL},
+ {"SJIS", encoding_group::SJIS},
+ {"SHIFT_JIS_2004", encoding_group::SHIFT_JIS_2004},
+ {"SQL_ASCII", encoding_group::MONOBYTE},
+ {"UHC", encoding_group::UHC},
+ {"UTF8", encoding_group::UTF8},
+ {"WIN866", encoding_group::MONOBYTE},
+ {"WIN874", encoding_group::MONOBYTE},
+ {"WIN1250", encoding_group::MONOBYTE},
+ {"WIN1251", encoding_group::MONOBYTE},
+ {"WIN1252", encoding_group::MONOBYTE},
+ {"WIN1253", encoding_group::MONOBYTE},
+ {"WIN1254", encoding_group::MONOBYTE},
+ {"WIN1255", encoding_group::MONOBYTE},
+ {"WIN1256", encoding_group::MONOBYTE},
+ {"WIN1257", encoding_group::MONOBYTE},
+ {"WIN1258", encoding_group::MONOBYTE},
+ };
+
+ const auto found_encoding_group = encoding_map.find(encoding_name);
+ if (found_encoding_group == encoding_map.end())
+ throw std::invalid_argument{
+ "unrecognized encoding '" + encoding_name + "'"
+ };
+ return found_encoding_group->second;
+}
+
+
+/// Look up instantiation @c T<enc>::call at runtime.
+/** Here, "T" is a struct template with a static member function "call", whose
+ * type is "F".
+ *
+ * The return value is a pointer to the "call" member function for the
+ * instantiation of T for encoding group enc.
+ */
+template<template<encoding_group> class T, typename F>
+inline F *for_encoding(encoding_group enc)
+{
+
+#define CASE_GROUP(ENC) \
+ case encoding_group::ENC: return T<encoding_group::ENC>::call
+
+ switch (enc)
+ {
+ CASE_GROUP(MONOBYTE);
+ CASE_GROUP(BIG5);
+ CASE_GROUP(EUC_CN);
+ CASE_GROUP(EUC_JP);
+ CASE_GROUP(EUC_JIS_2004);
+ CASE_GROUP(EUC_KR);
+ CASE_GROUP(EUC_TW);
+ CASE_GROUP(GB18030);
+ CASE_GROUP(GBK);
+ CASE_GROUP(JOHAB);
+ CASE_GROUP(MULE_INTERNAL);
+ CASE_GROUP(SJIS);
+ CASE_GROUP(SHIFT_JIS_2004);
+ CASE_GROUP(UHC);
+ CASE_GROUP(UTF8);
+ }
+ throw pqxx::usage_error{
+ "Unsupported encoding group code " + to_string(int(enc)) + "."};
+
+#undef CASE_GROUP
+}
+
+
+glyph_scanner_func *get_glyph_scanner(encoding_group enc)
+{
+ return for_encoding<glyph_scanner, glyph_scanner_func>(enc);
+}
+
+
+template<encoding_group E> struct char_finder
+{
+ static std::string::size_type call(
+ const std::string &haystack,
+ char needle,
+ std::string::size_type start)
+ {
+ const auto buffer = haystack.c_str();
+ const auto size = haystack.size();
+ for (
+ auto here = start;
+ here + 1 <= size;
+ here = glyph_scanner<E>::call(buffer, size, here)
+ )
+ {
+ if (haystack[here] == needle) return here;
+ }
+ return std::string::npos;
+ }
+};
+
+
+template<encoding_group E> struct string_finder
+{
+ static std::string::size_type call(
+ const std::string &haystack,
+ const std::string &needle,
+ std::string::size_type start)
+ {
+ const auto buffer = haystack.c_str();
+ const auto size = haystack.size();
+ const auto needle_size = needle.size();
+ for (
+ auto here = start;
+ here + needle_size <= size;
+ here = glyph_scanner<E>::call(buffer, size, here)
+ )
+ {
+ if (std::memcmp(buffer + here, needle.c_str(), needle_size) == 0)
+ return here;
+ }
+ return std::string::npos;
+ }
+};
+
+
+std::string::size_type find_with_encoding(
+ encoding_group enc,
+ const std::string& haystack,
+ char needle,
+ std::string::size_type start
+)
+{
+ using finder_func =
+ std::string::size_type(
+ const std::string &haystack,
+ char needle,
+ std::string::size_type start);
+ const auto finder = for_encoding<char_finder, finder_func>(enc);
+ return finder(haystack, needle, start);
+}
+
+
+std::string::size_type find_with_encoding(
+ encoding_group enc,
+ const std::string& haystack,
+ const std::string& needle,
+ std::string::size_type start
+)
+{
+ using finder_func =
+ std::string::size_type(
+ const std::string &haystack,
+ const std::string &needle,
+ std::string::size_type start);
+ const auto finder = for_encoding<string_finder, finder_func>(enc);
+ return finder(haystack, needle, start);
+}
+
+#undef DISPATCH_ENCODING_OPERATION
+
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/src/errorhandler.cxx b/contrib/libs/libpqxx/src/errorhandler.cxx
new file mode 100644
index 0000000000..f561746f9e
--- /dev/null
+++ b/contrib/libs/libpqxx/src/errorhandler.cxx
@@ -0,0 +1,44 @@
+/** Implementation of pqxx::errorhandler and helpers.
+ *
+ * pqxx::errorhandler allows programs to receive errors and warnings.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/connection_base"
+#include "pqxx/errorhandler"
+
+#include "pqxx/internal/gates/connection-errorhandler.hxx"
+
+
+using namespace pqxx;
+using namespace pqxx::internal;
+
+
+pqxx::errorhandler::errorhandler(connection_base &conn) :
+ m_home{&conn}
+{
+ gate::connection_errorhandler{*m_home}.register_errorhandler(this);
+}
+
+
+pqxx::errorhandler::~errorhandler()
+{
+ unregister();
+}
+
+
+void pqxx::errorhandler::unregister() noexcept
+{
+ if (m_home != nullptr)
+ {
+ gate::connection_errorhandler connection_gate{*m_home};
+ m_home = nullptr;
+ connection_gate.unregister_errorhandler(this);
+ }
+}
diff --git a/contrib/libs/libpqxx/src/except.cxx b/contrib/libs/libpqxx/src/except.cxx
new file mode 100644
index 0000000000..9dcc8a8201
--- /dev/null
+++ b/contrib/libs/libpqxx/src/except.cxx
@@ -0,0 +1,124 @@
+/** Implementation of libpqxx exception classes.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/except"
+
+
+pqxx::pqxx_exception::~pqxx_exception() noexcept
+{
+}
+
+
+pqxx::failure::failure(const std::string &whatarg) :
+ std::runtime_error{whatarg}
+{
+}
+
+
+pqxx::broken_connection::broken_connection() :
+ failure{"Connection to database failed"}
+{
+}
+
+
+pqxx::broken_connection::broken_connection(const std::string &whatarg) :
+ failure{whatarg}
+{
+}
+
+
+pqxx::sql_error::sql_error(
+ const std::string &whatarg,
+ const std::string &Q,
+ const char sqlstate[]) :
+ failure{whatarg},
+ m_query{Q},
+ m_sqlstate{sqlstate ? sqlstate : ""}
+{
+}
+
+
+pqxx::sql_error::~sql_error() noexcept
+{
+}
+
+
+PQXX_PURE const std::string &pqxx::sql_error::query() const noexcept
+{
+ return m_query;
+}
+
+
+PQXX_PURE const std::string &pqxx::sql_error::sqlstate() const noexcept
+{
+ return m_sqlstate;
+}
+
+
+pqxx::in_doubt_error::in_doubt_error(const std::string &whatarg) :
+ failure{whatarg}
+{
+}
+
+
+pqxx::transaction_rollback::transaction_rollback(const std::string &whatarg) :
+ failure{whatarg}
+{
+}
+
+
+pqxx::serialization_failure::serialization_failure(
+ const std::string &whatarg) :
+ transaction_rollback{whatarg}
+{
+}
+
+
+pqxx::statement_completion_unknown::statement_completion_unknown(
+ const std::string &whatarg) :
+ transaction_rollback{whatarg}
+{
+}
+
+
+pqxx::deadlock_detected::deadlock_detected(const std::string &whatarg) :
+ transaction_rollback{whatarg}
+{
+}
+
+
+pqxx::internal_error::internal_error(const std::string &whatarg) :
+ logic_error{"libpqxx internal error: " + whatarg}
+{
+}
+
+
+pqxx::usage_error::usage_error(const std::string &whatarg) :
+ logic_error{whatarg}
+{
+}
+
+
+pqxx::argument_error::argument_error(const std::string &whatarg) :
+ invalid_argument{whatarg}
+{
+}
+
+
+pqxx::conversion_error::conversion_error(const std::string &whatarg) :
+ domain_error{whatarg}
+{
+}
+
+
+pqxx::range_error::range_error(const std::string &whatarg) :
+ out_of_range{whatarg}
+{
+}
diff --git a/contrib/libs/libpqxx/src/field.cxx b/contrib/libs/libpqxx/src/field.cxx
new file mode 100644
index 0000000000..10f0f69e2b
--- /dev/null
+++ b/contrib/libs/libpqxx/src/field.cxx
@@ -0,0 +1,77 @@
+/** Implementation of the pqxx::field class.
+ *
+ * pqxx::field refers to a field in a query result.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cstring>
+
+#include "pqxx/internal/libpq-forward.hxx"
+
+#include "pqxx/result"
+
+
+pqxx::field::field(const pqxx::row &R, pqxx::row::size_type C) noexcept :
+ m_col{static_cast<decltype(m_col)>(C)},
+ m_home{R.m_result},
+ m_row{pqxx::result_size_type(R.m_index)}
+{
+}
+
+
+bool pqxx::field::operator==(const field &rhs) const
+{
+ if (is_null() != rhs.is_null()) return false;
+ // TODO: Verify null handling decision
+ const size_type s = size();
+ if (s != rhs.size()) return false;
+ return std::memcmp(c_str(), rhs.c_str(), s) == 0;
+}
+
+
+const char *pqxx::field::name() const
+{
+ return home().column_name(col());
+}
+
+
+pqxx::oid pqxx::field::type() const
+{
+ return home().column_type(col());
+}
+
+
+pqxx::oid pqxx::field::table() const
+{
+ return home().column_table(col());
+}
+
+
+pqxx::row::size_type pqxx::field::table_column() const
+{
+ return home().table_column(col());
+}
+
+
+const char *pqxx::field::c_str() const
+{
+ return home().GetValue(idx(), col());
+}
+
+
+bool pqxx::field::is_null() const noexcept
+{
+ return home().get_is_null(idx(), col());
+}
+
+
+pqxx::field::size_type pqxx::field::size() const noexcept
+{
+ return home().get_length(idx(), col());
+}
diff --git a/contrib/libs/libpqxx/src/largeobject.cxx b/contrib/libs/libpqxx/src/largeobject.cxx
new file mode 100644
index 0000000000..8020a2fc04
--- /dev/null
+++ b/contrib/libs/libpqxx/src/largeobject.cxx
@@ -0,0 +1,313 @@
+/** Implementation of the Large Objects interface.
+ *
+ * Allows direct access to large objects, as well as though I/O streams.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <algorithm>
+#include <cerrno>
+#include <stdexcept>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/largeobject"
+
+#include "pqxx/internal/gates/connection-largeobject.hxx"
+
+
+using namespace pqxx::internal;
+
+namespace
+{
+inline int StdModeToPQMode(std::ios::openmode mode)
+{
+ /// Mode bits, copied from libpq-fs.h so that we no longer need that header.
+ constexpr int
+ INV_WRITE = 0x00020000,
+ INV_READ = 0x00040000;
+
+ return
+ ((mode & std::ios::in) ? INV_READ : 0) |
+ ((mode & std::ios::out) ? INV_WRITE : 0);
+}
+
+
+inline int StdDirToPQDir(std::ios::seekdir dir) noexcept
+{
+ // TODO: Figure out whether seekdir values match C counterparts!
+#ifdef PQXX_SEEKDIRS_MATCH_C
+ return dir;
+#else
+ int pqdir;
+ switch (dir)
+ {
+ case std::ios::beg: pqdir=SEEK_SET; break;
+ case std::ios::cur: pqdir=SEEK_CUR; break;
+ case std::ios::end: pqdir=SEEK_END; break;
+
+ /* Added mostly to silence compiler warning, but also to help compiler detect
+ * cases where this function can be optimized away completely. This latter
+ * reason should go away as soon as PQXX_SEEKDIRS_MATCH_C works.
+ */
+ default: pqdir = dir; break;
+ }
+ return pqdir;
+#endif
+}
+
+
+} // namespace
+
+
+pqxx::largeobject::largeobject(dbtransaction &T) :
+ m_id{}
+{
+ // (Mode is ignored as of postgres 8.1.)
+ m_id = lo_creat(raw_connection(T), 0);
+ if (m_id == oid_none)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{"Could not create large object: " + reason(T.conn(), err)};
+ }
+}
+
+
+pqxx::largeobject::largeobject(dbtransaction &T, const std::string &File) :
+ m_id{}
+{
+ m_id = lo_import(raw_connection(T), File.c_str());
+ if (m_id == oid_none)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{
+ "Could not import file '" + File + "' to large object: " +
+ reason(T.conn(), err)};
+ }
+}
+
+
+pqxx::largeobject::largeobject(const largeobjectaccess &O) noexcept :
+ m_id{O.id()}
+{
+}
+
+
+void pqxx::largeobject::to_file(
+ dbtransaction &T,
+ const std::string &File) const
+{
+ if (lo_export(raw_connection(T), id(), File.c_str()) == -1)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{
+ "Could not export large object " + to_string(m_id) + " "
+ "to file '" + File + "': " + reason(T.conn(), err)};
+ }
+}
+
+
+void pqxx::largeobject::remove(dbtransaction &T) const
+{
+ if (lo_unlink(raw_connection(T), id()) == -1)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{
+ "Could not delete large object " + to_string(m_id) + ": " +
+ reason(T.conn(), err)};
+ }
+}
+
+
+pqxx::internal::pq::PGconn *pqxx::largeobject::raw_connection(
+ const dbtransaction &T)
+{
+ return gate::connection_largeobject{T.conn()}.raw_connection();
+}
+
+
+std::string pqxx::largeobject::reason(const connection_base &c, int err) const
+{
+ if (err == ENOMEM) return "Out of memory";
+ if (id() == oid_none) return "No object selected";
+ return gate::const_connection_largeobject{c}.error_message();
+}
+
+
+pqxx::largeobjectaccess::largeobjectaccess(dbtransaction &T, openmode mode) :
+ largeobject{T},
+ m_trans{T}
+{
+ open(mode);
+}
+
+
+pqxx::largeobjectaccess::largeobjectaccess(
+ dbtransaction &T,
+ oid O,
+ openmode mode) :
+ largeobject{O},
+ m_trans{T}
+{
+ open(mode);
+}
+
+
+pqxx::largeobjectaccess::largeobjectaccess(
+ dbtransaction &T,
+ largeobject O,
+ openmode mode) :
+ largeobject{O},
+ m_trans{T}
+{
+ open(mode);
+}
+
+
+pqxx::largeobjectaccess::largeobjectaccess(
+ dbtransaction &T,
+ const std::string &File,
+ openmode mode) :
+ largeobject{T, File},
+ m_trans{T}
+{
+ open(mode);
+}
+
+
+pqxx::largeobjectaccess::size_type
+pqxx::largeobjectaccess::seek(size_type dest, seekdir dir)
+{
+ const auto Result = cseek(dest, dir);
+ if (Result == -1)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{"Error seeking in large object: " + reason(err)};
+ }
+
+ return Result;
+}
+
+
+pqxx::largeobjectaccess::pos_type
+pqxx::largeobjectaccess::cseek(off_type dest, seekdir dir) noexcept
+{
+ return lo_lseek(raw_connection(), m_fd, int(dest), StdDirToPQDir(dir));
+}
+
+
+pqxx::largeobjectaccess::pos_type
+pqxx::largeobjectaccess::cwrite(const char Buf[], size_type Len) noexcept
+{
+ return
+ std::max(
+ lo_write(raw_connection(), m_fd,const_cast<char *>(Buf), size_t(Len)),
+ -1);
+}
+
+
+pqxx::largeobjectaccess::pos_type
+pqxx::largeobjectaccess::cread(char Buf[], size_type Bytes) noexcept
+{
+ return std::max(lo_read(raw_connection(), m_fd, Buf, size_t(Bytes)), -1);
+}
+
+
+pqxx::largeobjectaccess::pos_type
+pqxx::largeobjectaccess::ctell() const noexcept
+{
+ return lo_tell(raw_connection(), m_fd);
+}
+
+
+void pqxx::largeobjectaccess::write(const char Buf[], size_type Len)
+{
+ const auto Bytes = cwrite(Buf, Len);
+ if (Bytes < Len)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ if (Bytes < 0)
+ throw failure{
+ "Error writing to large object #" + to_string(id()) + ": " +
+ reason(err)};
+ if (Bytes == 0)
+ throw failure{
+ "Could not write to large object #" + to_string(id()) + ": " +
+ reason(err)};
+
+ throw failure{
+ "Wanted to write " + to_string(Len) + " bytes to large object #" +
+ to_string(id()) + "; " "could only write " + to_string(Bytes)};
+ }
+}
+
+
+pqxx::largeobjectaccess::size_type
+pqxx::largeobjectaccess::read(char Buf[], size_type Len)
+{
+ const auto Bytes = cread(Buf, Len);
+ if (Bytes < 0)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{
+ "Error reading from large object #" + to_string(id()) + ": " +
+ reason(err)};
+ }
+ return Bytes;
+}
+
+
+void pqxx::largeobjectaccess::open(openmode mode)
+{
+ m_fd = lo_open(raw_connection(), id(), StdModeToPQMode(mode));
+ if (m_fd < 0)
+ {
+ const int err = errno;
+ if (err == ENOMEM) throw std::bad_alloc{};
+ throw failure{
+ "Could not open large object " + to_string(id()) + ": " +
+ reason(err)};
+ }
+}
+
+
+void pqxx::largeobjectaccess::close() noexcept
+{
+ if (m_fd >= 0) lo_close(raw_connection(), m_fd);
+}
+
+
+pqxx::largeobjectaccess::size_type pqxx::largeobjectaccess::tell() const
+{
+ const size_type res = ctell();
+ if (res == -1) throw failure{reason(errno)};
+ return res;
+}
+
+
+std::string pqxx::largeobjectaccess::reason(int err) const
+{
+ if (m_fd == -1) return "No object opened.";
+ return largeobject::reason(m_trans.conn(), err);
+}
+
+
+void pqxx::largeobjectaccess::process_notice(const std::string &s) noexcept
+{
+ m_trans.process_notice(s);
+}
diff --git a/contrib/libs/libpqxx/src/nontransaction.cxx b/contrib/libs/libpqxx/src/nontransaction.cxx
new file mode 100644
index 0000000000..09e13a94d0
--- /dev/null
+++ b/contrib/libs/libpqxx/src/nontransaction.cxx
@@ -0,0 +1,25 @@
+/** Implementation of the pqxx::nontransaction class.
+ *
+ * pqxx::nontransaction provides nontransactional database access.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/nontransaction"
+
+
+pqxx::nontransaction::~nontransaction()
+{
+ End();
+}
+
+
+pqxx::result pqxx::nontransaction::do_exec(const char Query[])
+{
+ return direct_exec(Query, 0);
+}
diff --git a/contrib/libs/libpqxx/src/notification.cxx b/contrib/libs/libpqxx/src/notification.cxx
new file mode 100644
index 0000000000..391a71c1a4
--- /dev/null
+++ b/contrib/libs/libpqxx/src/notification.cxx
@@ -0,0 +1,36 @@
+/** Implementation of the pqxx::notification_receiever class.
+ *
+ * pqxx::notification_receiver processes notifications.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <string>
+
+#include "pqxx/internal/gates/connection-notification_receiver.hxx"
+
+#include "pqxx/notification"
+
+
+using namespace pqxx::internal;
+
+
+pqxx::notification_receiver::notification_receiver(
+ connection_base &c,
+ const std::string &channel_name) :
+ m_conn{c},
+ m_channel{channel_name}
+{
+ gate::connection_notification_receiver{c}.add_receiver(this);
+}
+
+
+pqxx::notification_receiver::~notification_receiver()
+{
+ gate::connection_notification_receiver{this->conn()}.remove_receiver(this);
+}
diff --git a/contrib/libs/libpqxx/src/pipeline.cxx b/contrib/libs/libpqxx/src/pipeline.cxx
new file mode 100644
index 0000000000..15b646ea3b
--- /dev/null
+++ b/contrib/libs/libpqxx/src/pipeline.cxx
@@ -0,0 +1,413 @@
+/** Implementation of the pqxx::pipeline class.
+ *
+ * Throughput-optimized query interface.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <iterator>
+
+#include "pqxx/dbtransaction"
+#include "pqxx/pipeline"
+
+#include "pqxx/internal/gates/connection-pipeline.hxx"
+#include "pqxx/internal/gates/result-creation.hxx"
+
+
+using namespace pqxx;
+using namespace pqxx::internal;
+
+
+namespace
+{
+const std::string theSeparator{"; "};
+const std::string theDummyValue{"1"};
+const std::string theDummyQuery{"SELECT " + theDummyValue + theSeparator};
+}
+
+
+pqxx::pipeline::pipeline(transaction_base &t, const std::string &Name) :
+ namedclass{"pipeline", Name},
+ transactionfocus{t}
+{
+ m_issuedrange = make_pair(m_queries.end(), m_queries.end());
+ attach();
+}
+
+
+pqxx::pipeline::~pipeline() noexcept
+{
+ try { cancel(); } catch (const std::exception &) {}
+ detach();
+}
+
+
+void pqxx::pipeline::attach()
+{
+ if (not registered()) register_me();
+}
+
+
+void pqxx::pipeline::detach()
+{
+ if (registered()) unregister_me();
+}
+
+
+pipeline::query_id pqxx::pipeline::insert(const std::string &q)
+{
+ attach();
+ const query_id qid = generate_id();
+ const auto i = m_queries.insert(std::make_pair(qid,Query(q))).first;
+
+ if (m_issuedrange.second == m_queries.end())
+ {
+ m_issuedrange.second = i;
+ if (m_issuedrange.first == m_queries.end()) m_issuedrange.first = i;
+ }
+ m_num_waiting++;
+
+ if (m_num_waiting > m_retain)
+ {
+ if (have_pending()) receive_if_available();
+ if (not have_pending()) issue();
+ }
+
+ return qid;
+}
+
+
+void pqxx::pipeline::complete()
+{
+ if (have_pending()) receive(m_issuedrange.second);
+ if (m_num_waiting and (m_error == qid_limit()))
+ {
+ issue();
+ receive(m_queries.end());
+ }
+ detach();
+}
+
+
+void pqxx::pipeline::flush()
+{
+ if (not m_queries.empty())
+ {
+ if (have_pending()) receive(m_issuedrange.second);
+ m_issuedrange.first = m_issuedrange.second = m_queries.end();
+ m_num_waiting = 0;
+ m_dummy_pending = false;
+ m_queries.clear();
+ }
+ detach();
+}
+
+
+void pqxx::pipeline::cancel()
+{
+ while (have_pending())
+ {
+ gate::connection_pipeline(m_trans.conn()).cancel_query();
+ auto canceled_query = m_issuedrange.first;
+ ++m_issuedrange.first;
+ m_queries.erase(canceled_query);
+ }
+}
+
+
+bool pqxx::pipeline::is_finished(pipeline::query_id q) const
+{
+ if (m_queries.find(q) == m_queries.end())
+ throw std::logic_error{
+ "Requested status for unknown query '" + to_string(q) + "'."};
+ return
+ (QueryMap::const_iterator(m_issuedrange.first)==m_queries.end()) or
+ (q < m_issuedrange.first->first and q < m_error);
+}
+
+
+std::pair<pipeline::query_id, result> pqxx::pipeline::retrieve()
+{
+ if (m_queries.empty())
+ throw std::logic_error{"Attempt to retrieve result from empty pipeline."};
+ return retrieve(std::begin(m_queries));
+}
+
+
+int pqxx::pipeline::retain(int retain_max)
+{
+ if (retain_max < 0)
+ throw range_error{
+ "Attempt to make pipeline retain " +
+ to_string(retain_max) + " queries"};
+
+ const int oldvalue = m_retain;
+ m_retain = retain_max;
+
+ if (m_num_waiting >= m_retain) resume();
+
+ return oldvalue;
+}
+
+
+void pqxx::pipeline::resume()
+{
+ if (have_pending()) receive_if_available();
+ if (not have_pending() and m_num_waiting)
+ {
+ issue();
+ receive_if_available();
+ }
+}
+
+
+pipeline::query_id pqxx::pipeline::generate_id()
+{
+ if (m_q_id == qid_limit())
+ throw std::overflow_error{"Too many queries went through pipeline."};
+ ++m_q_id;
+ return m_q_id;
+}
+
+
+
+void pqxx::pipeline::issue()
+{
+ // TODO: Wrap in nested transaction if available, for extra "replayability"
+
+ // Retrieve that null result for the last query, if needed
+ obtain_result();
+
+ // Don't issue anything if we've encountered an error
+ if (m_error < qid_limit()) return;
+
+ // Start with oldest query (lowest id) not in previous issue range
+ auto oldest = m_issuedrange.second;
+
+ // Construct cumulative query string for entire batch
+ std::string cum = separated_list(
+ theSeparator, oldest, m_queries.end(),
+ [](QueryMap::const_iterator i){return i->second.get_query();});
+ const auto num_issued = QueryMap::size_type(std::distance(
+ oldest, m_queries.end()));
+ const bool prepend_dummy = (num_issued > 1);
+ if (prepend_dummy) cum = theDummyQuery + cum;
+
+ gate::connection_pipeline{m_trans.conn()}.start_exec(cum);
+
+ // Since we managed to send out these queries, update state to reflect this
+ m_dummy_pending = prepend_dummy;
+ m_issuedrange.first = oldest;
+ m_issuedrange.second = m_queries.end();
+ m_num_waiting -= int(num_issued);
+}
+
+
+void pqxx::pipeline::internal_error(const std::string &err)
+{
+ set_error_at(0);
+ throw pqxx::internal_error{err};
+}
+
+
+bool pqxx::pipeline::obtain_result(bool expect_none)
+{
+ gate::connection_pipeline gate{m_trans.conn()};
+ const auto r = gate.get_result();
+ if (r == nullptr)
+ {
+ if (have_pending() and not expect_none)
+ {
+ set_error_at(m_issuedrange.first->first);
+ m_issuedrange.second = m_issuedrange.first;
+ }
+ return false;
+ }
+
+ const result res = gate::result_creation::create(
+ r, std::begin(m_queries)->second.get_query(),
+ internal::enc_group(m_trans.conn().encoding_id()));
+
+ if (not have_pending())
+ {
+ set_error_at(std::begin(m_queries)->first);
+ throw std::logic_error{
+ "Got more results from pipeline than there were queries."};
+ }
+
+ // Must be the result for the oldest pending query
+ if (not m_issuedrange.first->second.get_result().empty())
+ internal_error("Multiple results for one query.");
+
+ m_issuedrange.first->second.set_result(res);
+ ++m_issuedrange.first;
+
+ return true;
+}
+
+
+void pqxx::pipeline::obtain_dummy()
+{
+ gate::connection_pipeline gate{m_trans.conn()};
+ const auto r = gate.get_result();
+ m_dummy_pending = false;
+
+ if (r == nullptr)
+ internal_error("Pipeline got no result from backend when it expected one.");
+
+ result R = gate::result_creation::create(
+ r,
+ "[DUMMY PIPELINE QUERY]",
+ internal::enc_group(m_trans.conn().encoding_id()));
+
+ bool OK = false;
+ try
+ {
+ gate::result_creation{R}.check_status();
+ OK = true;
+ }
+ catch (const sql_error &)
+ {
+ }
+ if (OK)
+ {
+ if (R.size() > 1)
+ internal_error("Unexpected result for dummy query in pipeline.");
+
+ if (std::string{R.at(0).at(0).c_str()} != theDummyValue)
+ internal_error("Dummy query in pipeline returned unexpected value.");
+ return;
+ }
+
+ /* Since none of the queries in the batch were actually executed, we can
+ * afford to replay them one by one until we find the exact query that
+ * caused the error. This gives us not only a more specific error message
+ * to report, but also tells us which query to report it for.
+ */
+ // First, give the whole batch the same syntax error message, in case all else
+ // is going to fail.
+ for (auto i = m_issuedrange.first; i != m_issuedrange.second; ++i)
+ i->second.set_result(R);
+
+ // Remember where the end of this batch was
+ const auto stop = m_issuedrange.second;
+
+ // Retrieve that null result for the last query, if needed
+ obtain_result(true);
+
+
+ // Reset internal state to forget botched batch attempt
+ m_num_waiting += int(std::distance(m_issuedrange.first, stop));
+ m_issuedrange.second = m_issuedrange.first;
+
+ // Issue queries in failed batch one at a time.
+ unregister_me();
+ try
+ {
+ do
+ {
+ m_num_waiting--;
+ const std::string &query = m_issuedrange.first->second.get_query();
+ const result res{m_trans.exec(query)};
+ m_issuedrange.first->second.set_result(res);
+ gate::result_creation{res}.check_status();
+ ++m_issuedrange.first;
+ }
+ while (m_issuedrange.first != stop);
+ }
+ catch (const std::exception &)
+ {
+ const query_id thud = m_issuedrange.first->first;
+ ++m_issuedrange.first;
+ m_issuedrange.second = m_issuedrange.first;
+ auto q = m_issuedrange.first;
+ set_error_at( (q == m_queries.end()) ? thud + 1 : q->first);
+ }
+}
+
+
+std::pair<pipeline::query_id, result>
+pqxx::pipeline::retrieve(pipeline::QueryMap::iterator q)
+{
+ if (q == m_queries.end())
+ throw std::logic_error{"Attempt to retrieve result for unknown query."};
+
+ if (q->first >= m_error)
+ throw std::runtime_error{
+ "Could not complete query in pipeline due to error in earlier query."};
+
+ // If query hasn't issued yet, do it now
+ if (m_issuedrange.second != m_queries.end() and
+ (q->first >= m_issuedrange.second->first))
+ {
+ if (have_pending()) receive(m_issuedrange.second);
+ if (m_error == qid_limit()) issue();
+ }
+
+ // If result not in yet, get it; else get at least whatever's convenient
+ if (have_pending())
+ {
+ if (q->first >= m_issuedrange.first->first)
+ {
+ auto suc = q;
+ ++suc;
+ receive(suc);
+ }
+ else
+ {
+ receive_if_available();
+ }
+ }
+
+ if (q->first >= m_error)
+ throw std::runtime_error{
+ "Could not complete query in pipeline due to error in earlier query."};
+
+ // Don't leave the backend idle if there are queries waiting to be issued
+ if (m_num_waiting and not have_pending() and (m_error==qid_limit())) issue();
+
+ const result R = q->second.get_result();
+ const auto P = std::make_pair(q->first, R);
+
+ m_queries.erase(q);
+
+ gate::result_creation{R}.check_status();
+ return P;
+}
+
+
+void pqxx::pipeline::get_further_available_results()
+{
+ gate::connection_pipeline gate{m_trans.conn()};
+ while (not gate.is_busy() and obtain_result())
+ if (not gate.consume_input()) throw broken_connection{};
+}
+
+
+void pqxx::pipeline::receive_if_available()
+{
+ gate::connection_pipeline gate{m_trans.conn()};
+ if (not gate.consume_input()) throw broken_connection{};
+ if (gate.is_busy()) return;
+
+ if (m_dummy_pending) obtain_dummy();
+ if (have_pending()) get_further_available_results();
+}
+
+
+void pqxx::pipeline::receive(pipeline::QueryMap::const_iterator stop)
+{
+ if (m_dummy_pending) obtain_dummy();
+
+ while (obtain_result() and
+ QueryMap::const_iterator{m_issuedrange.first} != stop) ;
+
+ // Also haul in any remaining "targets of opportunity"
+ if (QueryMap::const_iterator{m_issuedrange.first} == stop)
+ get_further_available_results();
+}
diff --git a/contrib/libs/libpqxx/src/prepared_statement.cxx b/contrib/libs/libpqxx/src/prepared_statement.cxx
new file mode 100644
index 0000000000..c2d7fe23f9
--- /dev/null
+++ b/contrib/libs/libpqxx/src/prepared_statement.cxx
@@ -0,0 +1,69 @@
+/** Helper classes for defining and executing prepared statements>
+ *
+ * See the connection_base hierarchy for more about prepared statements.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/connection_base"
+#include "pqxx/prepared_statement"
+#include "pqxx/result"
+#include "pqxx/transaction_base"
+
+#include "pqxx/internal/gates/connection-prepare-invocation.hxx"
+
+
+using namespace pqxx;
+using namespace pqxx::internal;
+
+
+pqxx::prepare::invocation::invocation(
+ transaction_base &home,
+ const std::string &statement) :
+ m_home{home},
+ m_statement{statement}
+{
+}
+
+pqxx::result pqxx::prepare::invocation::exec() const
+{
+ return internal_exec(result_format::text);
+}
+
+pqxx::result pqxx::prepare::invocation::exec_binary() const
+{
+ return internal_exec(result_format::binary);
+}
+
+pqxx::result pqxx::prepare::invocation::internal_exec(result_format format) const
+{
+ std::vector<const char *> ptrs;
+ std::vector<int> lens;
+ std::vector<int> binaries;
+ const int elts = marshall(ptrs, lens, binaries);
+
+ return gate::connection_prepare_invocation{m_home.conn()}.prepared_exec(
+ m_statement,
+ ptrs.data(),
+ lens.data(),
+ binaries.data(),
+ elts,
+ format);
+}
+
+bool pqxx::prepare::invocation::exists() const
+{
+ return gate::connection_prepare_invocation{m_home.conn()}.prepared_exists(
+ m_statement);
+}
+
+
+pqxx::prepare::internal::prepared_def::prepared_def(const std::string &def) :
+ definition{def}
+{
+}
diff --git a/contrib/libs/libpqxx/src/result.cxx b/contrib/libs/libpqxx/src/result.cxx
new file mode 100644
index 0000000000..fcb602d779
--- /dev/null
+++ b/contrib/libs/libpqxx/src/result.cxx
@@ -0,0 +1,454 @@
+/** Implementation of the pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cstdlib>
+#include <cstring>
+#include <stdexcept>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/except"
+#include "pqxx/result"
+
+
+const std::string pqxx::result::s_empty_string;
+
+
+/// C++ wrapper for libpq's PQclear.
+void pqxx::internal::clear_result(const pq::PGresult *data)
+{
+ PQclear(const_cast<pq::PGresult *>(data));
+}
+
+
+pqxx::result::result(
+ pqxx::internal::pq::PGresult *rhs,
+ const std::string &Query,
+ internal::encoding_group enc) :
+ m_data{make_data_pointer(rhs)},
+ m_query{std::make_shared<std::string>(Query)},
+ m_encoding(enc)
+{
+}
+
+
+bool pqxx::result::operator==(const result &rhs) const noexcept
+{
+ if (&rhs == this) return true;
+ const auto s = size();
+ if (rhs.size() != s) return false;
+ for (size_type i=0; i<s; ++i)
+ if ((*this)[i] != rhs[i]) return false;
+ return true;
+}
+
+
+pqxx::result::const_reverse_iterator pqxx::result::rbegin() const
+{
+ return const_reverse_iterator{end()};
+}
+
+
+pqxx::result::const_reverse_iterator pqxx::result::crbegin() const
+{
+ return rbegin();
+}
+
+
+pqxx::result::const_reverse_iterator pqxx::result::rend() const
+{
+ return const_reverse_iterator{begin()};
+}
+
+
+pqxx::result::const_reverse_iterator pqxx::result::crend() const
+{
+ return rend();
+}
+
+
+pqxx::result::const_iterator pqxx::result::begin() const noexcept
+{
+ return const_iterator{this, 0};
+}
+
+
+pqxx::result::const_iterator pqxx::result::cbegin() const noexcept
+{
+ return begin();
+}
+
+
+pqxx::result::size_type pqxx::result::size() const noexcept
+{
+ return m_data.get() ? size_type(PQntuples(m_data.get())) : 0;
+}
+
+
+bool pqxx::result::empty() const noexcept
+{
+ return (m_data.get() == nullptr) or (PQntuples(m_data.get()) == 0);
+}
+
+
+pqxx::result::reference pqxx::result::front() const noexcept
+{
+ return row{*this, 0};
+}
+
+
+pqxx::result::reference pqxx::result::back() const noexcept
+{
+ return row{*this, size() - 1};
+}
+
+
+void pqxx::result::swap(result &rhs) noexcept
+{
+ m_data.swap(rhs.m_data);
+ m_query.swap(rhs.m_query);
+}
+
+
+const pqxx::row pqxx::result::operator[](result_size_type i) const noexcept
+{
+ return row{*this, i};
+}
+
+
+const pqxx::row pqxx::result::at(pqxx::result::size_type i) const
+{
+ if (i >= size()) throw range_error{"Row number out of range."};
+ return operator[](i);
+}
+
+
+namespace
+{
+/// C string comparison.
+inline bool equal(const char lhs[], const char rhs[])
+{
+ return strcmp(lhs, rhs) == 0;
+}
+} // namespace
+
+void pqxx::result::ThrowSQLError(
+ const std::string &Err,
+ const std::string &Query) const
+{
+ // Try to establish more precise error type, and throw corresponding
+ // type of exception.
+ const char *const code = PQresultErrorField(m_data.get(), PG_DIAG_SQLSTATE);
+ if (code) switch (code[0])
+ {
+ case '0':
+ switch (code[1])
+ {
+ case '8':
+ throw broken_connection{Err};
+ case 'A':
+ throw feature_not_supported{Err, Query, code};
+ }
+ break;
+ case '2':
+ switch (code[1])
+ {
+ case '2':
+ throw data_exception{Err, Query, code};
+ case '3':
+ if (equal(code,"23001")) throw restrict_violation{Err, Query, code};
+ if (equal(code,"23502")) throw not_null_violation{Err, Query, code};
+ if (equal(code,"23503"))
+ throw foreign_key_violation{Err, Query, code};
+ if (equal(code,"23505")) throw unique_violation{Err, Query, code};
+ if (equal(code,"23514")) throw check_violation{Err, Query, code};
+ throw integrity_constraint_violation{Err, Query, code};
+ case '4':
+ throw invalid_cursor_state{Err, Query, code};
+ case '6':
+ throw invalid_sql_statement_name{Err, Query, code};
+ }
+ break;
+ case '3':
+ switch (code[1])
+ {
+ case '4':
+ throw invalid_cursor_name{Err, Query, code};
+ }
+ break;
+ case '4':
+ switch (code[1])
+ {
+ case '0':
+ if (equal(code, "40000")) throw transaction_rollback{Err};
+ if (equal(code, "40001")) throw serialization_failure{Err};
+ if (equal(code, "40003")) throw statement_completion_unknown{Err};
+ if (equal(code, "40P01")) throw deadlock_detected{Err};
+ break;
+ case '2':
+ if (equal(code,"42501")) throw insufficient_privilege{Err, Query};
+ if (equal(code,"42601"))
+ throw syntax_error{Err, Query, code, errorposition()};
+ if (equal(code,"42703")) throw undefined_column{Err, Query, code};
+ if (equal(code,"42883")) throw undefined_function{Err, Query, code};
+ if (equal(code,"42P01")) throw undefined_table{Err, Query, code};
+ }
+ break;
+ case '5':
+ switch (code[1])
+ {
+ case '3':
+ if (equal(code,"53100")) throw disk_full{Err, Query, code};
+ if (equal(code,"53200")) throw out_of_memory{Err, Query, code};
+ if (equal(code,"53300")) throw too_many_connections{Err};
+ throw insufficient_resources{Err, Query, code};
+ }
+ break;
+
+ case 'P':
+ if (equal(code, "P0001")) throw plpgsql_raise{Err, Query, code};
+ if (equal(code, "P0002"))
+ throw plpgsql_no_data_found{Err, Query, code};
+ if (equal(code, "P0003"))
+ throw plpgsql_too_many_rows{Err, Query, code};
+ throw plpgsql_error{Err, Query, code};
+ }
+ // Fallback: No error code.
+ throw sql_error{Err, Query, code};
+}
+
+void pqxx::result::check_status() const
+{
+ const std::string Err = StatusError();
+ if (not Err.empty()) ThrowSQLError(Err, query());
+}
+
+
+std::string pqxx::result::StatusError() const
+{
+ if (m_data.get() == nullptr) throw failure{"No result set given."};
+
+ std::string Err;
+
+ switch (PQresultStatus(m_data.get()))
+ {
+ case PGRES_EMPTY_QUERY: // The string sent to the backend was empty.
+ case PGRES_COMMAND_OK: // Successful completion of a command returning no data
+ case PGRES_TUPLES_OK: // The query successfully executed
+ break;
+
+ case PGRES_COPY_OUT: // Copy Out (from server) data transfer started
+ case PGRES_COPY_IN: // Copy In (to server) data transfer started
+ break;
+
+ case PGRES_BAD_RESPONSE: // The server's response was not understood
+ case PGRES_NONFATAL_ERROR:
+ case PGRES_FATAL_ERROR:
+ Err = PQresultErrorMessage(m_data.get());
+ break;
+
+ default:
+ throw internal_error{
+ "pqxx::result: Unrecognized response code " +
+ to_string(int(PQresultStatus(m_data.get())))};
+ }
+ return Err;
+}
+
+
+const char *pqxx::result::cmd_status() const noexcept
+{
+ return PQcmdStatus(const_cast<internal::pq::PGresult *>(m_data.get()));
+}
+
+
+const std::string &pqxx::result::query() const noexcept
+{
+ return m_query ? *m_query : s_empty_string;
+}
+
+
+pqxx::oid pqxx::result::inserted_oid() const
+{
+ if (m_data.get() == nullptr)
+ throw usage_error{
+ "Attempt to read oid of inserted row without an INSERT result"};
+ return PQoidValue(const_cast<internal::pq::PGresult *>(m_data.get()));
+}
+
+
+pqxx::result::size_type pqxx::result::affected_rows() const
+{
+ const char *const RowsStr = PQcmdTuples(
+ const_cast<internal::pq::PGresult *>(m_data.get()));
+ return RowsStr[0] ? size_type(atoi(RowsStr)) : 0;
+}
+
+
+const char *pqxx::result::GetValue(
+ pqxx::result::size_type Row,
+ pqxx::row::size_type Col) const
+{
+ return PQgetvalue(m_data.get(), int(Row), int(Col));
+}
+
+
+bool pqxx::result::get_is_null(
+ pqxx::result::size_type Row,
+ pqxx::row::size_type Col) const
+{
+ return PQgetisnull(m_data.get(), int(Row), int(Col)) != 0;
+}
+
+pqxx::field::size_type pqxx::result::get_length(
+ pqxx::result::size_type Row,
+ pqxx::row::size_type Col) const noexcept
+{
+ return field::size_type(PQgetlength(m_data.get(), int(Row), int(Col)));
+}
+
+
+pqxx::oid pqxx::result::column_type(row::size_type ColNum) const
+{
+ const oid T = PQftype(m_data.get(), int(ColNum));
+ if (T == oid_none)
+ throw argument_error{
+ "Attempt to retrieve type of nonexistent column " +
+ to_string(ColNum) + " of query result."};
+ return T;
+}
+
+
+pqxx::oid pqxx::result::column_table(row::size_type ColNum) const
+{
+ const oid T = PQftable(m_data.get(), int(ColNum));
+
+ /* If we get oid_none, it may be because the column is computed, or because we
+ * got an invalid row number.
+ */
+ if (T == oid_none and ColNum >= columns())
+ throw argument_error{
+ "Attempt to retrieve table ID for column " + to_string(ColNum) +
+ " out of " + to_string(columns())};
+
+ return T;
+}
+
+
+pqxx::row::size_type pqxx::result::table_column(row::size_type ColNum) const
+{
+ const auto n = row::size_type(PQftablecol(m_data.get(), int(ColNum)));
+ if (n != 0) return n-1;
+
+ // Failed. Now find out why, so we can throw a sensible exception.
+ const std::string col_num = to_string(ColNum);
+ if (ColNum > columns())
+ throw range_error{"Invalid column index in table_column(): " + col_num};
+
+ if (m_data.get() == nullptr)
+ throw usage_error{
+ "Can't query origin of column " + col_num + ": "
+ "result is not initialized."};
+
+ throw usage_error{
+ "Can't query origin of column " + col_num + ": "
+ "not derived from table column."};
+}
+
+int pqxx::result::errorposition() const
+{
+ int pos = -1;
+ if (m_data.get())
+ {
+ const char *p = PQresultErrorField(
+ const_cast<internal::pq::PGresult *>(m_data.get()),
+ PG_DIAG_STATEMENT_POSITION);
+ if (p) from_string(p, pos);
+ }
+ return pos;
+}
+
+
+const char *pqxx::result::column_name(pqxx::row::size_type Number) const
+{
+ const char *const N = PQfname(m_data.get(), int(Number));
+ if (N == nullptr)
+ {
+ if (m_data.get() == nullptr)
+ throw usage_error{"Queried column name on null result."};
+ throw range_error{
+ "Invalid column number: " + to_string(Number) +
+ " (maximum is " + to_string(columns() - 1) + ")."};
+ }
+ return N;
+}
+
+
+pqxx::row::size_type pqxx::result::columns() const noexcept
+{
+ auto ptr = const_cast<internal::pq::PGresult *>(m_data.get());
+ return ptr ? row::size_type(PQnfields(ptr)) : 0;
+}
+
+
+// const_result_iterator
+
+pqxx::const_result_iterator pqxx::const_result_iterator::operator++(int)
+{
+ const_result_iterator old{*this};
+ m_index++;
+ return old;
+}
+
+
+pqxx::const_result_iterator pqxx::const_result_iterator::operator--(int)
+{
+ const_result_iterator old{*this};
+ m_index--;
+ return old;
+}
+
+
+pqxx::result::const_iterator
+pqxx::result::const_reverse_iterator::base() const noexcept
+{
+ iterator_type tmp{*this};
+ return ++tmp;
+}
+
+
+pqxx::const_reverse_result_iterator
+pqxx::const_reverse_result_iterator::operator++(int)
+{
+ const_reverse_result_iterator tmp{*this};
+ iterator_type::operator--();
+ return tmp;
+}
+
+
+pqxx::const_reverse_result_iterator
+pqxx::const_reverse_result_iterator::operator--(int)
+{
+ const_reverse_result_iterator tmp{*this};
+ iterator_type::operator++();
+ return tmp;
+}
+
+
+template<>
+std::string pqxx::to_string(const field &Obj)
+{
+ return std::string{Obj.c_str(), Obj.size()};
+}
diff --git a/contrib/libs/libpqxx/src/robusttransaction.cxx b/contrib/libs/libpqxx/src/robusttransaction.cxx
new file mode 100644
index 0000000000..fbada337df
--- /dev/null
+++ b/contrib/libs/libpqxx/src/robusttransaction.cxx
@@ -0,0 +1,317 @@
+/** Implementation of the pqxx::robusttransaction class.
+ *
+ * pqxx::robusttransaction is a slower but safer transaction class.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <stdexcept>
+
+#include "pqxx/connection_base"
+#include "pqxx/result"
+#include "pqxx/robusttransaction"
+
+
+using namespace pqxx::internal;
+
+
+// TODO: Log username in more places.
+
+pqxx::internal::basic_robusttransaction::basic_robusttransaction(
+ connection_base &C,
+ const std::string &IsolationLevel,
+ const std::string &table_name) :
+ namedclass{"robusttransaction"},
+ dbtransaction(C, IsolationLevel),
+ m_log_table{table_name}
+{
+ if (table_name.empty()) m_log_table = "pqxx_robusttransaction_log";
+ m_sequence = m_log_table + "_seq";
+}
+
+
+pqxx::internal::basic_robusttransaction::~basic_robusttransaction()
+{
+}
+
+
+void pqxx::internal::basic_robusttransaction::do_begin()
+{
+ try
+ {
+ CreateTransactionRecord();
+ }
+ catch (const std::exception &)
+ {
+ // The problem here *may* be that the log table doesn't exist yet. Create
+ // one, start a new transaction, and try again.
+ try { dbtransaction::do_abort(); } catch (const std::exception &) {}
+ CreateLogTable();
+ dbtransaction::do_begin();
+ m_backendpid = conn().backendpid();
+ CreateTransactionRecord();
+ }
+
+ dbtransaction::do_begin();
+
+ // If this transaction commits, the transaction record should also be gone.
+ direct_exec(sql_delete().c_str());
+
+ if (conn().server_version() >= 80300)
+ direct_exec("SELECT txid_current()")[0][0].to(m_xid);
+}
+
+
+
+void pqxx::internal::basic_robusttransaction::do_commit()
+{
+ if (m_record_id == 0)
+ throw internal_error{"transaction '" + name() + "' has no ID."};
+
+ // Check constraints before sending the COMMIT to the database to reduce the
+ // work being done inside our in-doubt window.
+ try
+ {
+ direct_exec("SET CONSTRAINTS ALL IMMEDIATE");
+ }
+ catch (...)
+ {
+ do_abort();
+ throw;
+ }
+
+ // Here comes the critical part. If we lose our connection here, we'll be
+ // left clueless as to whether the backend got the message and is trying to
+ // commit the transaction (let alone whether it will succeed if so). That
+ // case requires some special handling that makes robusttransaction what it
+ // is.
+ try
+ {
+ direct_exec("COMMIT");
+
+ // If we make it here, great. Normal, successful commit.
+ m_record_id = 0;
+ return;
+ }
+ catch (const broken_connection &)
+ {
+ // Oops, lost connection at the crucial moment. Fall through to in-doubt
+ // handling below.
+ }
+ catch (...)
+ {
+ if (conn().is_open())
+ {
+ // Commit failed--probably due to a constraint violation or something
+ // similar. But we're still connected, so no worries from a consistency
+ // point of view.
+ do_abort();
+ throw;
+ }
+ // Otherwise, fall through to in-doubt handling.
+ }
+
+ // If we get here, we're in doubt. Talk to the backend, figure out what
+ // happened. If the transaction record still exists, the transaction failed.
+ // If not, it succeeded.
+
+ bool exists;
+ try
+ {
+ exists = CheckTransactionRecord();
+ }
+ catch (const std::exception &f)
+ {
+ // Couldn't check for transaction record. We're still in doubt as to
+ // whether the transaction was performed.
+ const std::string Msg =
+ "WARNING: Connection lost while committing transaction "
+ "'" + name() + "' (id " + to_string(m_record_id) + ", "
+ "transaction_id " + m_xid + "). "
+ "Please check for this record in the "
+ "'" + m_log_table + "' table. "
+ "If the record exists, the transaction was executed. "
+ "If not, then it wasn't.\n";
+
+ process_notice(Msg);
+ process_notice(
+ "Could not verify existence of transaction record because of the "
+ "following error:\n");
+ process_notice(std::string{f.what()} + "\n");
+
+ throw in_doubt_error{Msg};
+ }
+
+ // Transaction record is still there, so the transaction failed and all we
+ // have is a "normal" transaction failure.
+ if (exists)
+ {
+ do_abort();
+ throw broken_connection{"Connection lost while committing."};
+ }
+
+ // Otherwise, the transaction succeeded. Forget there was ever an error.
+}
+
+
+void pqxx::internal::basic_robusttransaction::do_abort()
+{
+ dbtransaction::do_abort();
+ DeleteTransactionRecord();
+}
+
+
+// Create transaction log table if it didn't already exist
+void pqxx::internal::basic_robusttransaction::CreateLogTable()
+{
+ // Create log table in case it doesn't already exist. This code must only be
+ // executed before the backend transaction has properly started.
+ std::string CrTab =
+ "CREATE TABLE " + quote_name(m_log_table) + " ("
+ "id INTEGER NOT NULL, "
+ "username VARCHAR(256), "
+ "transaction_id xid, "
+ "name VARCHAR(256), "
+ "date TIMESTAMP NOT NULL"
+ ")";
+
+ try
+ {
+ direct_exec(CrTab.c_str(), 1);
+ }
+ catch (const std::exception &e)
+ {
+ conn().process_notice(
+ "Could not create transaction log table: " + std::string{e.what()});
+ }
+
+ try
+ {
+ direct_exec(("CREATE SEQUENCE " + m_sequence).c_str());
+ }
+ catch (const std::exception &e)
+ {
+ conn().process_notice(
+ "Could not create transaction log sequence: " + std::string{e.what()});
+ }
+}
+
+
+void pqxx::internal::basic_robusttransaction::CreateTransactionRecord()
+{
+ // Clean up old transaction records.
+ direct_exec((
+ "DELETE FROM " + m_log_table + " "
+ "WHERE date < CURRENT_TIMESTAMP - '30 days'::interval").c_str());
+
+ // Allocate id.
+ const std::string sql_get_id{"SELECT nextval(" + quote(m_sequence) + ")"};
+ direct_exec(sql_get_id.c_str())[0][0].to(m_record_id);
+
+ direct_exec((
+ "INSERT INTO " + quote_name(m_log_table) +
+ " (id, username, name, date) "
+ "VALUES "
+ "(" +
+ to_string(m_record_id) + ", " +
+ quote(conn().username()) + ", " +
+ (name().empty() ? "NULL" : quote(name())) + ", "
+ "CURRENT_TIMESTAMP"
+ ")").c_str());
+}
+
+
+std::string pqxx::internal::basic_robusttransaction::sql_delete() const
+{
+ return
+ "DELETE FROM " + quote_name(m_log_table) + " "
+ "WHERE id = " + to_string(m_record_id);
+}
+
+
+void pqxx::internal::basic_robusttransaction::DeleteTransactionRecord()
+ noexcept
+{
+ if (m_record_id == 0) return;
+
+ try
+ {
+ const std::string Del = sql_delete();
+
+ reactivation_avoidance_exemption E(conn());
+ direct_exec(Del.c_str(), 20);
+
+ // Now that we've arrived here, we're about as sure as we can be that that
+ // record is quite dead.
+ m_record_id = 0;
+ }
+ catch (const std::exception &)
+ {
+ }
+
+ if (m_record_id != 0) try
+ {
+ process_notice(
+ "WARNING: "
+ "Failed to delete obsolete transaction record with id " +
+ to_string(m_record_id) + " ('" + name() + "'). "
+ "Please delete it manually. Thank you.\n");
+ }
+ catch (const std::exception &)
+ {
+ }
+}
+
+
+// Attempt to establish whether transaction record with given ID still exists
+bool pqxx::internal::basic_robusttransaction::CheckTransactionRecord()
+{
+ bool hold = true;
+ for (int c=20; hold and c; internal::sleep_seconds(5), --c)
+ {
+ if (conn().server_version() > 80300)
+ {
+ const std::string query{
+ "SELECT " + m_xid + " >= txid_snapshot_xmin(txid_current_snapshot())"};
+ direct_exec(query.c_str())[0][0].to(hold);
+ }
+ else
+ {
+ /* Wait for the old backend (with the lost connection) to die.
+ *
+ * Actually this is only possible if stats_command_string (or maybe
+ * stats_start_collector?) has been set in postgresql.conf and we're
+ * running as the postgres superuser.
+ *
+ * Starting with 7.4, we could also use pg_locks. The entry for a zombied
+ * transaction will have a "relation" field of null, a "transaction" field
+ * with the transaction ID, and "pid" set to our backend pid. If the
+ * relation exists but no such record is found, then the transaction is no
+ * longer running.
+ */
+ const result R{direct_exec((
+ "SELECT current_query "
+ "FROM pq_stat_activity "
+ "WHERE procpid = " + to_string(m_backendpid)).c_str())};
+ hold = not R.empty();
+ }
+ }
+
+ if (hold)
+ throw in_doubt_error{
+ "Old backend process stays alive too long to wait for."};
+
+ // Now look for our transaction record
+ const std::string Find =
+ "SELECT id FROM " + quote_name(m_log_table) + " "
+ "WHERE "
+ "id = " + to_string(m_record_id) + " AND "
+ "user = " + conn().username();
+
+ return not direct_exec(Find.c_str(), 20).empty();
+}
diff --git a/contrib/libs/libpqxx/src/row.cxx b/contrib/libs/libpqxx/src/row.cxx
new file mode 100644
index 0000000000..3ae9a19a81
--- /dev/null
+++ b/contrib/libs/libpqxx/src/row.cxx
@@ -0,0 +1,276 @@
+/** Implementation of the pqxx::result class and support classes.
+ *
+ * pqxx::result represents the set of result rows from a database query.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cstdlib>
+#include <cstring>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/except"
+#include "pqxx/result"
+
+#include "pqxx/internal/gates/result-row.hxx"
+
+
+pqxx::row::row(result r, size_t i) noexcept :
+ m_result{r},
+ m_index{long(i)},
+ m_end{internal::gate::result_row(r) ? r.columns() : 0}
+{
+}
+
+
+pqxx::row::const_iterator pqxx::row::begin() const noexcept
+{
+ return const_iterator{*this, m_begin};
+}
+
+
+pqxx::row::const_iterator pqxx::row::cbegin() const noexcept
+{
+ return begin();
+}
+
+
+pqxx::row::const_iterator pqxx::row::end() const noexcept
+{
+ return const_iterator{*this, m_end};
+}
+
+
+pqxx::row::const_iterator pqxx::row::cend() const noexcept
+{
+ return end();
+}
+
+
+pqxx::row::reference pqxx::row::front() const noexcept
+{
+ return field{*this, m_begin};
+}
+
+
+pqxx::row::reference pqxx::row::back() const noexcept
+{
+ return field{*this, m_end - 1};
+}
+
+
+pqxx::row::const_reverse_iterator pqxx::row::rbegin() const
+{
+ return const_reverse_row_iterator{end()};
+}
+
+
+pqxx::row::const_reverse_iterator pqxx::row::crbegin() const
+{
+ return rbegin();
+}
+
+
+pqxx::row::const_reverse_iterator pqxx::row::rend() const
+{
+ return const_reverse_row_iterator{begin()};
+}
+
+
+pqxx::row::const_reverse_iterator pqxx::row::crend() const
+{
+ return rend();
+}
+
+
+bool pqxx::row::operator==(const row &rhs) const noexcept
+{
+ if (&rhs == this) return true;
+ const auto s = size();
+ if (rhs.size() != s) return false;
+ // TODO: Depends on how null is handled!
+ for (size_type i=0; i<s; ++i) if ((*this)[i] != rhs[i]) return false;
+ return true;
+}
+
+
+pqxx::row::reference pqxx::row::operator[](size_type i) const noexcept
+{
+ return field{*this, m_begin + i};
+}
+
+
+pqxx::row::reference pqxx::row::operator[](int i) const noexcept
+{
+ return operator[](size_type(i));
+}
+
+
+pqxx::row::reference pqxx::row::operator[](const char f[]) const
+{
+ return at(f);
+}
+
+
+pqxx::row::reference pqxx::row::operator[](const std::string &s) const
+{
+ return operator[](s.c_str());
+}
+
+
+pqxx::row::reference pqxx::row::at(int i) const
+{
+ return at(size_type(i));
+}
+
+
+pqxx::row::reference pqxx::row::at(const std::string &s) const
+{
+ return at(s.c_str());
+}
+
+
+void pqxx::row::swap(row &rhs) noexcept
+{
+ const auto i = m_index;
+ const auto b= m_begin;
+ const auto e = m_end;
+ m_result.swap(rhs.m_result);
+ m_index = rhs.m_index;
+ m_begin = rhs.m_begin;
+ m_end = rhs.m_end;
+ rhs.m_index = i;
+ rhs.m_begin = b;
+ rhs.m_end = e;
+}
+
+
+pqxx::field pqxx::row::at(const char f[]) const
+{
+ return field{*this, m_begin + column_number(f)};
+}
+
+
+pqxx::field pqxx::row::at(pqxx::row::size_type i) const
+{
+ if (i >= size())
+ throw range_error{"Invalid field number."};
+
+ return operator[](i);
+}
+
+
+pqxx::oid pqxx::row::column_type(size_type ColNum) const
+{
+ return m_result.column_type(m_begin + ColNum);
+}
+
+
+pqxx::oid pqxx::row::column_table(size_type ColNum) const
+{
+ return m_result.column_table(m_begin + ColNum);
+}
+
+
+pqxx::row::size_type pqxx::row::table_column(size_type ColNum) const
+{
+ return m_result.table_column(m_begin + ColNum);
+}
+
+
+pqxx::row::size_type pqxx::row::column_number(const char ColName[]) const
+{
+ const auto n = m_result.column_number(ColName);
+ if (n >= m_end)
+ return result{}.column_number(ColName);
+ if (n >= m_begin)
+ return n - m_begin;
+
+ const char *const AdaptedColName = m_result.column_name(n);
+ for (auto i = m_begin; i < m_end; ++i)
+ if (strcmp(AdaptedColName, m_result.column_name(i)) == 0)
+ return i - m_begin;
+
+ return result{}.column_number(ColName);
+}
+
+
+pqxx::row::size_type pqxx::result::column_number(const char ColName[]) const
+{
+ const int N = PQfnumber(
+ const_cast<internal::pq::PGresult *>(m_data.get()), ColName);
+ if (N == -1)
+ throw argument_error{
+ "Unknown column name: '" + std::string{ColName} + "'."};
+
+ return row::size_type(N);
+}
+
+
+pqxx::row pqxx::row::slice(size_type Begin, size_type End) const
+{
+ if (Begin > End or End > size())
+ throw range_error{"Invalid field range."};
+
+ row result{*this};
+ result.m_begin = m_begin + Begin;
+ result.m_end = m_begin + End;
+ return result;
+}
+
+
+bool pqxx::row::empty() const noexcept
+{
+ return m_begin == m_end;
+}
+
+
+pqxx::const_row_iterator pqxx::const_row_iterator::operator++(int)
+{
+ const_row_iterator old{*this};
+ m_col++;
+ return old;
+}
+
+
+pqxx::const_row_iterator pqxx::const_row_iterator::operator--(int)
+{
+ const_row_iterator old{*this};
+ m_col--;
+ return old;
+}
+
+
+pqxx::const_row_iterator
+pqxx::const_reverse_row_iterator::base() const noexcept
+{
+ iterator_type tmp{*this};
+ return ++tmp;
+}
+
+
+pqxx::const_reverse_row_iterator
+pqxx::const_reverse_row_iterator::operator++(int)
+{
+ const_reverse_row_iterator tmp{*this};
+ operator++();
+ return tmp;
+}
+
+
+pqxx::const_reverse_row_iterator
+pqxx::const_reverse_row_iterator::operator--(int)
+{
+ const_reverse_row_iterator tmp{*this};
+ operator--();
+ return tmp;
+}
diff --git a/contrib/libs/libpqxx/src/sql_cursor.cxx b/contrib/libs/libpqxx/src/sql_cursor.cxx
new file mode 100644
index 0000000000..2ebdb1304d
--- /dev/null
+++ b/contrib/libs/libpqxx/src/sql_cursor.cxx
@@ -0,0 +1,309 @@
+/** Implementation of libpqxx STL-style cursor classes.
+ *
+ * These classes wrap SQL cursors in STL-like interfaces.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <iterator>
+
+#include "pqxx/cursor"
+
+#include "pqxx/internal/encodings.hxx"
+#include "pqxx/internal/gates/connection-sql_cursor.hxx"
+#include "pqxx/internal/gates/transaction-sql_cursor.hxx"
+
+using namespace pqxx;
+using namespace pqxx::internal;
+
+
+namespace
+{
+/// Is this character a "useless trailing character" in a query?
+/** A character is "useless" at the end of a query if it is either whitespace or
+ * a semicolon.
+ */
+inline bool useless_trail(char c)
+{
+ return isspace(c) or c==';';
+}
+
+
+/// Find end of nonempty query, stripping off any trailing semicolon.
+/** When executing a normal query, a trailing semicolon is meaningless but
+ * won't hurt. That's why we can't rule out that some code may include one.
+ *
+ * But for cursor queries, a trailing semicolon is a problem. The query gets
+ * embedded in a larger statement, which a semicolon would break into two.
+ * We'll have to remove it if present.
+ *
+ * A trailing semicolon may not actually be at the end. It could be masked by
+ * subsequent whitespace. If there's also a comment though, that's the
+ * caller's own lookout. We can't guard against every possible mistake, and
+ * text processing is actually remarkably sensitive to mistakes in a
+ * multi-encoding world.
+ *
+ * If there is a trailing semicolon, this function returns its offset. If
+ * there are more than one, it returns the offset of the first one. If there
+ * is no trailing semicolon, it returns the length of the query string.
+ *
+ * The query must be nonempty.
+ */
+std::string::size_type find_query_end(
+ const std::string &query,
+ encoding_group enc)
+{
+ const auto text = query.c_str();
+ const auto size = query.size();
+ std::string::size_type end;
+ if (enc == encoding_group::MONOBYTE)
+ {
+ // This is an encoding where we can scan backwards from the end.
+ for (end = query.size(); end > 0 and useless_trail(text[end-1]); --end);
+ }
+ else
+ {
+ // Complex encoding. We only know how to iterate forwards, so start from
+ // the beginning.
+ end = 0;
+
+ pqxx::internal::for_glyphs(
+ enc,
+ [text, &end](const char *gbegin, const char *gend)
+ {
+ if (gend - gbegin > 1 or not useless_trail(*gbegin))
+ end = std::string::size_type(gend - text);
+ },
+ text, size);
+ }
+
+ return end;
+}
+} // namespace
+
+
+pqxx::internal::sql_cursor::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) :
+ cursor_base{t.conn(), cname},
+ m_home{t.conn()},
+ m_adopted{false},
+ m_at_end{-1},
+ m_pos{0}
+{
+ if (&t.conn() != &m_home) throw internal_error{"Cursor in wrong connection"};
+
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ m_home.activate();
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+
+ if (query.empty()) throw usage_error{"Cursor has empty query."};
+ const auto enc = enc_group(t.conn().encoding_id());
+ const auto qend = find_query_end(query, enc);
+ if (qend == 0) throw usage_error{"Cursor has effectively empty query."};
+
+ std::stringstream cq, qn;
+
+ cq << "DECLARE " << t.quote_name(name()) << " ";
+
+ if (format == result_format::binary) {
+ cq << "BINARY ";
+ }
+
+ if (ap == cursor_base::forward_only) cq << "NO ";
+ cq << "SCROLL ";
+
+ cq << "CURSOR ";
+
+ if (hold) cq << "WITH HOLD ";
+
+ cq << "FOR ";
+ cq.write(query.c_str(), std::streamsize(qend));
+ cq << ' ';
+
+ if (up != cursor_base::update) cq << "FOR READ ONLY ";
+ else cq << "FOR UPDATE ";
+
+ qn << "[DECLARE " << name() << ']';
+ t.exec(cq, qn.str());
+
+ // Now that we're here in the starting position, keep a copy of an empty
+ // result. That may come in handy later, because we may not be able to
+ // construct an empty result with all the right metadata due to the weird
+ // meaning of "FETCH 0."
+ init_empty_result(t);
+
+ // If we're creating a WITH HOLD cursor, noone is going to destroy it until
+ // after this transaction. That means the connection cannot be deactivated
+ // without losing the cursor.
+ if (hold)
+ gate::connection_sql_cursor{t.conn()}.add_reactivation_avoidance_count(1);
+
+ m_ownership = op;
+}
+
+
+pqxx::internal::sql_cursor::sql_cursor(
+ transaction_base &t,
+ const std::string &cname,
+ cursor_base::ownershippolicy op) :
+ cursor_base{t.conn(), cname, false},
+ m_home{t.conn()},
+ m_empty_result{},
+ m_adopted{true},
+ m_at_end{0},
+ m_pos{-1}
+{
+ // If we take responsibility for destroying the cursor, that's one less
+ // reason not to allow the connection to be deactivated and reactivated.
+ // TODO: Go over lifetime/reactivation rules again to be sure they work.
+ if (op==cursor_base::owned)
+ gate::connection_sql_cursor{t.conn()}.add_reactivation_avoidance_count(-1);
+ m_adopted = true;
+ m_ownership = op;
+}
+
+
+void pqxx::internal::sql_cursor::close() noexcept
+{
+ if (m_ownership==cursor_base::owned)
+ {
+ try
+ {
+ gate::connection_sql_cursor{m_home}.exec(
+ ("CLOSE " + m_home.quote_name(name())).c_str(),
+ 0);
+ }
+ catch (const std::exception &)
+ {
+ }
+
+ if (m_adopted)
+ gate::connection_sql_cursor{m_home}.add_reactivation_avoidance_count(-1);
+
+ m_ownership = cursor_base::loose;
+ }
+}
+
+
+void pqxx::internal::sql_cursor::init_empty_result(transaction_base &t)
+{
+ if (pos() != 0) throw internal_error{"init_empty_result() from bad pos()."};
+ m_empty_result = t.exec("FETCH 0 IN " + m_home.quote_name(name()));
+}
+
+
+/// Compute actual displacement based on requested and reported displacements.
+internal::sql_cursor::difference_type
+pqxx::internal::sql_cursor::adjust(difference_type hoped,
+ difference_type actual)
+{
+ if (actual < 0) throw internal_error{"Negative rows in cursor movement."};
+ if (hoped == 0) return 0;
+ const int direction = ((hoped < 0) ? -1 : 1);
+ bool hit_end = false;
+ if (actual != labs(hoped))
+ {
+ if (actual > labs(hoped))
+ throw internal_error{"Cursor displacement larger than requested."};
+
+ // If we see fewer rows than requested, then we've hit an end (on either
+ // side) of the result set. Wether we make an extra step to a one-past-end
+ // position or whether we're already there depends on where we were
+ // previously: if our last move was in the same direction and also fell
+ // short, we're already at a one-past-end row.
+ if (m_at_end != direction) ++actual;
+
+ // If we hit the beginning, make sure our position calculation ends up
+ // at zero (even if we didn't previously know where we were!), and if we
+ // hit the other end, register the fact that we now know where the end
+ // of the result set is.
+ if (direction > 0) hit_end = true;
+ else if (m_pos == -1) m_pos = actual;
+ else if (m_pos != actual)
+ throw internal_error{
+ "Moved back to beginning, but wrong position: "
+ "hoped=" + to_string(hoped) + ", "
+ "actual=" + to_string(actual) + ", "
+ "m_pos=" + to_string(m_pos) + ", "
+ "direction=" + to_string(direction) + "."};
+
+ m_at_end = direction;
+ }
+ else
+ {
+ m_at_end = 0;
+ }
+
+ if (m_pos >= 0) m_pos += direction*actual;
+ if (hit_end)
+ {
+ if (m_endpos >= 0 and m_pos != m_endpos)
+ throw internal_error{"Inconsistent cursor end positions."};
+ m_endpos = m_pos;
+ }
+ return direction*actual;
+}
+
+
+result pqxx::internal::sql_cursor::fetch(
+ difference_type rows,
+ difference_type &displacement)
+{
+ if (rows == 0)
+ {
+ displacement = 0;
+ return m_empty_result;
+ }
+ const std::string query =
+ "FETCH " + stridestring(rows) + " IN " + m_home.quote_name(name());
+ const result r{gate::connection_sql_cursor{m_home}.exec(query.c_str(), 0)};
+ displacement = adjust(rows, difference_type(r.size()));
+ return r;
+}
+
+
+cursor_base::difference_type pqxx::internal::sql_cursor::move(
+ difference_type rows,
+ difference_type &displacement)
+{
+ if (rows == 0)
+ {
+ displacement = 0;
+ return 0;
+ }
+
+ const std::string query =
+ "MOVE " + stridestring(rows) + " IN " + m_home.quote_name(name());
+ const result r(gate::connection_sql_cursor{m_home}.exec(query.c_str(), 0));
+ difference_type d = difference_type(r.affected_rows());
+ displacement = adjust(rows, d);
+ return d;
+}
+
+
+std::string pqxx::internal::sql_cursor::stridestring(difference_type n)
+{
+ /* Some special-casing for ALL and BACKWARD ALL here. We used to use numeric
+ * "infinities" for difference_type for this (the highest and lowest possible
+ * values for "long"), but for PostgreSQL 8.0 at least, the backend appears to
+ * expect a 32-bit number and fails to parse large 64-bit numbers.
+ * We could change the alias to match this behaviour, but that would break
+ * if/when Postgres is changed to accept 64-bit displacements.
+ */
+ static const std::string All{"ALL"}, BackAll{"BACKWARD ALL"};
+ if (n >= cursor_base::all()) return All;
+ else if (n <= cursor_base::backward_all()) return BackAll;
+ return to_string(n);
+}
diff --git a/contrib/libs/libpqxx/src/statement_parameters.cxx b/contrib/libs/libpqxx/src/statement_parameters.cxx
new file mode 100644
index 0000000000..3500cb04a9
--- /dev/null
+++ b/contrib/libs/libpqxx/src/statement_parameters.cxx
@@ -0,0 +1,58 @@
+/** Common implementation for statement parameter lists.
+ *
+ * See the connection_base hierarchy for more about prepared statements
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/util"
+
+#include "pqxx/internal/statement_parameters.hxx"
+
+
+void pqxx::internal::statement_parameters::add_checked_param(
+ const std::string &value,
+ bool nonnull,
+ bool binary)
+{
+ m_nonnull.push_back(nonnull);
+ if (nonnull) m_values.push_back(value);
+ m_binary.push_back(binary);
+}
+
+
+int pqxx::internal::statement_parameters::marshall(
+ std::vector<const char *> &values,
+ std::vector<int> &lengths,
+ std::vector<int> &binaries) const
+{
+ const auto elements = m_nonnull.size();
+ const auto array_size = elements + 1;
+ values.clear();
+ values.resize(array_size, nullptr);
+ lengths.clear();
+ lengths.resize(array_size, 0);
+ // "Unpack" from m_values, which skips arguments that are null, to the
+ // outputs which represent all parameters including nulls.
+ size_t arg = 0;
+ for (size_t param = 0; param < elements; ++param)
+ if (m_nonnull[param])
+ {
+ values[param] = m_values[arg].c_str();
+ lengths[param] = int(m_values[arg].size());
+ ++arg;
+ }
+
+ // The binaries array is simpler: it maps 1-on-1.
+ binaries.resize(array_size);
+ for (size_t param = 0; param < elements; ++param)
+ binaries[param] = int(m_binary[param]);
+ binaries.back() = 0;
+
+ return int(elements);
+}
diff --git a/contrib/libs/libpqxx/src/strconv.cxx b/contrib/libs/libpqxx/src/strconv.cxx
new file mode 100644
index 0000000000..9e67d55bb3
--- /dev/null
+++ b/contrib/libs/libpqxx/src/strconv.cxx
@@ -0,0 +1,724 @@
+/** Implementation of string conversions.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <limits>
+#include <locale>
+#include <system_error>
+
+#if __cplusplus < 201703
+// This is not C++17 or better. Don't use to_chars/from_chars; the code which
+// uses those also relies on other C++17 features.
+#if defined(PQXX_HAVE_CHARCONV_INT)
+#undef PQXX_HAVE_CHARCONV_INT
+#endif
+#if defined(PQXX_HAVE_CHARCONV_FLOAT)
+#undef PQXX_HAVE_CHARCONV_FLOAT
+#endif
+#endif
+
+#if defined(PQXX_HAVE_CHARCONV_INT) || defined(PQXX_HAVE_CHARCONV_FLOAT)
+#include <charconv>
+#endif
+
+#if __cplusplus >= 201703
+#include <string_view>
+#endif
+
+#include "pqxx/except"
+#include "pqxx/strconv"
+
+
+using namespace pqxx::internal;
+
+
+namespace
+{
+/// C string comparison.
+inline bool equal(const char lhs[], const char rhs[])
+{
+ return strcmp(lhs, rhs) == 0;
+}
+} // namespace
+
+
+namespace pqxx
+{
+namespace internal
+{
+void throw_null_conversion(const std::string &type)
+{
+ throw conversion_error{"Attempt to convert null to " + type + "."};
+}
+} // namespace pqxx::internal
+} // namespace pqxx
+
+
+#if defined(PQXX_HAVE_CHARCONV_INT) || defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace
+{
+template<typename T> void wrap_from_chars(std::string_view in, T &out)
+{
+ using traits = pqxx::string_traits<T>;
+ const char *end = in.data() + in.size();
+ const auto res = std::from_chars(in.data(), end, out);
+ if (res.ec == std::errc() and res.ptr == end) return;
+
+ std::string msg;
+ if (res.ec == std::errc())
+ {
+ msg = "Could not parse full string.";
+ }
+ else switch (res.ec)
+ {
+ case std::errc::result_out_of_range:
+ msg = "Value out of range.";
+ break;
+ case std::errc::invalid_argument:
+ msg = "Invalid argument.";
+ break;
+ default:
+ break;
+ }
+
+ const std::string base =
+ "Could not convert '" + std::string(in) + "' "
+ "to " + traits::name();
+ if (msg.empty()) throw pqxx::conversion_error{base + "."};
+ else throw pqxx::conversion_error{base + ": " + msg};
+}
+
+
+/// How big of a buffer do we want for representing a T?
+template<typename T> constexpr int size_buffer()
+{
+ using lim = std::numeric_limits<T>;
+ // Allocate room for how many digits? There's "max_digits10" for
+ // floating-point numbers, but only "digits10" for integer types.
+ constexpr auto digits = std::max({lim::digits10, lim::max_digits10});
+ // Leave a little bit of extra room for signs, decimal points, and the like.
+ return digits + 4;
+}
+
+
+/// Call @c std::to_chars. It differs for integer vs. floating-point types.
+template<typename TYPE, bool INTEGRAL> struct to_chars_caller;
+
+#if defined(PQXX_HAVE_CHARCONV_INT)
+/// For integer types, we pass "base 10" to @c std::to_chars.
+template<typename TYPE> struct to_chars_caller<TYPE, true>
+{
+ static std::to_chars_result call(char *begin, char *end, TYPE in)
+ { return std::to_chars(begin, end, in, 10); }
+};
+#endif
+
+#if defined(PQXX_HAVE_CHARCONV_FLOAT)
+/// For floating-point types, we pass "general format" to @c std::to_chars.
+template<typename TYPE>
+template<typename TYPE> struct to_chars_caller<TYPE, true>
+{
+ static std::to_chars_result call(char *begin, char *end, TYPE in)
+ { return std::to_chars(begin, end, in, std::chars_format::general); }
+};
+#endif
+} // namespace
+
+
+namespace pqxx
+{
+namespace internal
+{
+template<typename T> std::string builtin_traits<T>::to_string(T in)
+{
+ using traits = pqxx::string_traits<T>;
+ char buf[size_buffer<T>()];
+
+ // Annoying: we need to make slightly different calls to std::to_chars
+ // depending on whether this is an integral type or a floating-point type.
+ // Use to_chars_caller to hide the difference.
+ constexpr bool is_integer = std::numeric_limits<T>::is_integer;
+ const auto res = to_chars_caller<T, is_integer>::call(
+ buf, buf + sizeof(buf), in);
+ if (res.ec == std::errc()) return std::string(buf, res.ptr);
+
+ std::string msg;
+ switch (res.ec)
+ {
+ case std::errc::value_too_large:
+ msg = "Value too large.";
+ break;
+ default:
+ break;
+ }
+
+ const std::string base =
+ std::string{"Could not convert "} + traits::name() + " to string";
+ if (msg.empty()) throw pqxx::conversion_error{base + "."};
+ else throw pqxx::conversion_error{base + ": " + msg};
+}
+
+
+/// Translate @c from_string calls to @c wrap_from_chars calls.
+/** The only difference is the type of the string.
+ */
+template<typename TYPE>
+void builtin_traits<TYPE>::from_string(const char Str[], TYPE &Obj)
+ { wrap_from_chars(std::string_view{Str}, Obj); }
+} // namespace pqxx::internal
+} // namespace pqxx
+#endif // PQXX_HAVE_CHARCONV_INT || PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace
+{
+template<typename T> inline void set_to_Inf(T &t, int sign=1)
+{
+ T value = std::numeric_limits<T>::infinity();
+ if (sign < 0) value = -value;
+ t = value;
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_INT)
+namespace
+{
+[[noreturn]] void report_overflow()
+{
+ throw pqxx::conversion_error{
+ "Could not convert string to integer: value out of range."};
+}
+
+
+/** Helper to check for underflow before multiplying a number by 10.
+ *
+ * Needed just so the compiler doesn't get to complain about an "if (n < 0)"
+ * clause that's pointless for unsigned numbers.
+ */
+template<typename T, bool is_signed> struct underflow_check;
+
+/* Specialization for signed types: check.
+ */
+template<typename T> struct underflow_check<T, true>
+{
+ static void check_before_adding_digit(T n)
+ {
+ constexpr T ten{10};
+ if (n < 0 and (std::numeric_limits<T>::min() / ten) > n) report_overflow();
+ }
+};
+
+/* Specialization for unsigned types: no check needed becaue negative
+ * numbers don't exist.
+ */
+template<typename T> struct underflow_check<T, false>
+{
+ static void check_before_adding_digit(T) {}
+};
+
+
+/// Return 10*n, or throw exception if it overflows.
+template<typename T> T safe_multiply_by_ten(T n)
+{
+ using limits = std::numeric_limits<T>;
+ constexpr T ten{10};
+ if (n > 0 and (limits::max() / n) < ten) report_overflow();
+ underflow_check<T, limits::is_signed>::check_before_adding_digit(n);
+ return T(n * ten);
+}
+
+
+/// Add a digit d to n, or throw exception if it overflows.
+template<typename T> T safe_add_digit(T n, T d)
+{
+ assert((n >= 0 and d >= 0) or (n <=0 and d <= 0));
+ if ((n > 0) and (n > (std::numeric_limits<T>::max() - d))) report_overflow();
+ if ((n < 0) and (n < (std::numeric_limits<T>::min() - d))) report_overflow();
+ return n + d;
+}
+
+
+/// For use in string parsing: add new numeric digit to intermediate value
+template<typename L, typename R>
+ inline L absorb_digit(L value, R digit)
+{
+ return L(safe_multiply_by_ten(value) + L(digit));
+}
+
+
+template<typename T> void from_string_signed(const char Str[], T &Obj)
+{
+ int i = 0;
+ T result = 0;
+
+ if (not isdigit(Str[i]))
+ {
+ if (Str[i] != '-')
+ throw pqxx::conversion_error{
+ "Could not convert string to integer: '" + std::string{Str} + "'."};
+
+ for (++i; isdigit(Str[i]); ++i)
+ result = absorb_digit(result, -digit_to_number(Str[i]));
+ }
+ else
+ {
+ for (; isdigit(Str[i]); ++i)
+ result = absorb_digit(result, digit_to_number(Str[i]));
+ }
+
+ if (Str[i])
+ throw pqxx::conversion_error{
+ "Unexpected text after integer: '" + std::string{Str} + "'."};
+
+ Obj = result;
+}
+
+template<typename T> void from_string_unsigned(const char Str[], T &Obj)
+{
+ int i = 0;
+ T result = 0;
+
+ if (not isdigit(Str[i]))
+ throw pqxx::conversion_error{
+ "Could not convert string to unsigned integer: '" +
+ std::string{Str} + "'."};
+
+ for (; isdigit(Str[i]); ++i)
+ result = absorb_digit(result, digit_to_number(Str[i]));
+
+ if (Str[i])
+ throw pqxx::conversion_error{
+ "Unexpected text after integer: '" + std::string{Str} + "'."};
+
+ Obj = result;
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_INT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace
+{
+bool valid_infinity_string(const char str[]) noexcept
+{
+ return
+ equal("infinity", str) or
+ equal("Infinity", str) or
+ equal("INFINITY", str) or
+ equal("inf", str);
+}
+
+
+/// Wrapper for std::stringstream with C locale.
+/** Some of our string conversions use the standard library. But, they must
+ * _not_ obey the system's locale settings, or a value like 1000.0 might end
+ * up looking like "1.000,0".
+ *
+ * Initialising the stream (including locale and tweaked precision) seems to
+ * be expensive though. So, create thread-local instances which we re-use.
+ * It's a lockless way of keeping global variables thread-safe, basically.
+ *
+ * The stream initialisation happens once per thread, in the constructor.
+ * And that's why we need to wrap this in a class. We can't just do it at the
+ * call site, or we'd still be doing it for every call.
+ */
+template<typename T> class dumb_stringstream : public std::stringstream
+{
+public:
+ // Do not initialise the base-class object using "stringstream{}" (with curly
+ // braces): that breaks on Visual C++. The classic "stringstream()" syntax
+ // (with parentheses) does work.
+ dumb_stringstream()
+ {
+ this->imbue(std::locale::classic());
+ this->precision(std::numeric_limits<T>::max_digits10);
+ }
+};
+
+
+/* These are hard. Sacrifice performance of specialized, nonflexible,
+ * non-localized code and lean on standard library. Some special-case code
+ * handles NaNs.
+ */
+template<typename T> inline void from_string_float(const char Str[], T &Obj)
+{
+ bool ok = false;
+ T result;
+
+ switch (Str[0])
+ {
+ case 'N':
+ case 'n':
+ // Accept "NaN," "nan," etc.
+ ok = (
+ (Str[1]=='A' or Str[1]=='a') and
+ (Str[2]=='N' or Str[2]=='n') and
+ (Str[3] == '\0'));
+ result = std::numeric_limits<T>::quiet_NaN();
+ break;
+
+ case 'I':
+ case 'i':
+ ok = valid_infinity_string(Str);
+ set_to_Inf(result);
+ break;
+
+ default:
+ if (Str[0] == '-' and valid_infinity_string(&Str[1]))
+ {
+ ok = true;
+ set_to_Inf(result, -1);
+ }
+ else
+ {
+ thread_local dumb_stringstream<T> S;
+ // Visual Studio 2017 seems to fail on repeated conversions if the
+ // clear() is done before the seekg(). Still don't know why! See #124
+ // and #125.
+ S.seekg(0);
+ S.clear();
+ S.str(Str);
+ ok = static_cast<bool>(S >> result);
+ }
+ break;
+ }
+
+ if (not ok)
+ throw pqxx::conversion_error{
+ "Could not convert string to numeric value: '" +
+ std::string{Str} + "'."};
+
+ Obj = result;
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_INT)
+namespace
+{
+template<typename T> inline std::string to_string_unsigned(T Obj)
+{
+ if (not Obj) return "0";
+
+ // Every byte of width on T adds somewhere between 3 and 4 digits to the
+ // maximum length of our decimal string.
+ char buf[4*sizeof(T)+1];
+
+ char *p = &buf[sizeof(buf)];
+ *--p = '\0';
+ while (Obj > 0)
+ {
+ *--p = number_to_digit(int(Obj%10));
+ Obj = T(Obj / 10);
+ }
+ return p;
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_INT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_INT) || !defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace
+{
+template<typename T> inline std::string to_string_fallback(T Obj)
+{
+ thread_local dumb_stringstream<T> S;
+ S.str("");
+ S << Obj;
+ return S.str();
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_INT || !PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace
+{
+template<typename T> inline std::string to_string_float(T Obj)
+{
+ if (std::isnan(Obj)) return "nan";
+ if (std::isinf(Obj)) return Obj > 0 ? "infinity" : "-infinity";
+ return to_string_fallback(Obj);
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_INT)
+namespace
+{
+template<typename T> inline std::string to_string_signed(T Obj)
+{
+ if (Obj < 0)
+ {
+ // Remember--the smallest negative number for a given two's-complement type
+ // cannot be negated.
+ const bool negatable = (Obj != std::numeric_limits<T>::min());
+ if (negatable)
+ return '-' + to_string_unsigned(-Obj);
+ else
+ return to_string_fallback(Obj);
+ }
+
+ return to_string_unsigned(Obj);
+}
+} // namespace
+#endif // !PQXX_HAVE_CHARCONV_INT
+
+
+#if defined(PQXX_HAVE_CHARCONV_INT)
+namespace pqxx
+{
+template void
+builtin_traits<short>::from_string(const char[], short &);
+template void
+builtin_traits<unsigned short>::from_string(const char[], unsigned short &);
+template void
+builtin_traits<int>::from_string(const char[], int &);
+template void
+builtin_traits<unsigned int>::from_string(const char[], unsigned int &);
+template void
+builtin_traits<long>::from_string(const char[], long &);
+template void
+builtin_traits<unsigned long>::from_string(const char[], unsigned long &);
+template void
+builtin_traits<long long>::from_string(const char[], long long &);
+template void
+builtin_traits<unsigned long long>::from_string(
+ const char[], unsigned long long &);
+} // namespace pqxx
+#endif // PQXX_HAVE_CHARCONV_INT
+
+
+#if defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace pqxx
+{
+template
+void string_traits<float>::from_string(const char Str[], float &Obj);
+template
+void string_traits<double>::from_string(const char Str[], double &Obj);
+template
+void string_traits<long double>::from_string(
+ const char Str[],
+ long double &Obj);
+} // namespace pqxx
+#endif // PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if defined(PQXX_HAVE_CHARCONV_INT)
+namespace pqxx
+{
+namespace internal
+{
+template
+std::string builtin_traits<short>::to_string(short Obj);
+template
+std::string builtin_traits<unsigned short>::to_string(unsigned short Obj);
+template
+std::string builtin_traits<int>::to_string(int Obj);
+template
+std::string builtin_traits<unsigned int>::to_string(unsigned int Obj);
+template
+std::string builtin_traits<long>::to_string(long Obj);
+template
+std::string builtin_traits<unsigned long>::to_string(unsigned long Obj);
+template
+std::string builtin_traits<long long>::to_string(long long Obj);
+template
+std::string builtin_traits<unsigned long long>::to_string(
+ unsigned long long Obj);
+} // namespace pqxx::internal
+} // namespace pqxx
+#endif // PQXX_HAVE_CHARCONV_INT
+
+
+#if defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace pqxx
+{
+namespace internal
+{
+template
+std::string builtin_traits<float>::to_string(float Obj);
+template
+std::string builtin_traits<double>::to_string(double Obj);
+template
+std::string builtin_traits<long double>::to_string(long double Obj);
+} // namespace pqxx::internal
+} // namespace pqxx
+#endif // PQXX_HAVE_CHARCONV_FLOAT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_INT)
+namespace pqxx
+{
+namespace internal
+{
+template<>
+void builtin_traits<short>::from_string(const char Str[], short &Obj)
+ { from_string_signed(Str, Obj); }
+template<>
+std::string builtin_traits<short>::to_string(short Obj)
+ { return to_string_signed(Obj); }
+template<>
+void builtin_traits<unsigned short>::from_string(
+ const char Str[],
+ unsigned short &Obj)
+ { from_string_unsigned(Str, Obj); }
+template<>
+std::string builtin_traits<unsigned short>::to_string(unsigned short Obj)
+ { return to_string_unsigned(Obj); }
+template<>
+void builtin_traits<int>::from_string(const char Str[], int &Obj)
+ { from_string_signed(Str, Obj); }
+template<>
+std::string builtin_traits<int>::to_string(int Obj)
+ { return to_string_signed(Obj); }
+template<>
+void builtin_traits<unsigned int>::from_string(
+ const char Str[],
+ unsigned int &Obj)
+ { from_string_unsigned(Str, Obj); }
+template<>
+std::string builtin_traits<unsigned int>::to_string(unsigned int Obj)
+ { return to_string_unsigned(Obj); }
+template<>
+void builtin_traits<long>::from_string(const char Str[], long &Obj)
+ { from_string_signed(Str, Obj); }
+template<>
+std::string builtin_traits<long>::to_string(long Obj)
+ { return to_string_signed(Obj); }
+template<>
+void builtin_traits<unsigned long>::from_string(
+ const char Str[],
+ unsigned long &Obj)
+ { from_string_unsigned(Str, Obj); }
+template<>
+std::string builtin_traits<unsigned long>::to_string(unsigned long Obj)
+ { return to_string_unsigned(Obj); }
+template<>
+void builtin_traits<long long>::from_string(const char Str[], long long &Obj)
+ { from_string_signed(Str, Obj); }
+template<>
+std::string builtin_traits<long long>::to_string(long long Obj)
+ { return to_string_signed(Obj); }
+template<>
+void builtin_traits<unsigned long long>::from_string(
+ const char Str[],
+ unsigned long long &Obj)
+ { from_string_unsigned(Str, Obj); }
+template<>
+std::string builtin_traits<unsigned long long>::to_string(
+ unsigned long long Obj)
+ { return to_string_unsigned(Obj); }
+} // namespace pqxx::internal
+} // namespace pqxx
+#endif // !PQXX_HAVE_CHARCONV_INT
+
+
+#if !defined(PQXX_HAVE_CHARCONV_FLOAT)
+namespace pqxx
+{
+namespace internal
+{
+template<>
+void builtin_traits<float>::from_string(const char Str[], float &Obj)
+ { from_string_float(Str, Obj); }
+template<>
+std::string builtin_traits<float>::to_string(float Obj)
+ { return to_string_float(Obj); }
+template<>
+void builtin_traits<double>::from_string(const char Str[], double &Obj)
+ { from_string_float(Str, Obj); }
+template<>
+std::string builtin_traits<double>::to_string(double Obj)
+ { return to_string_float(Obj); }
+template<>
+void builtin_traits<long double>::from_string(
+ const char Str[], long double &Obj)
+ { from_string_float(Str, Obj); }
+template<>
+std::string builtin_traits<long double>::to_string(long double Obj)
+ { return to_string_float(Obj); }
+} // namespace pqxx::internal
+} // namespace pqxx
+#endif // !PQXX_HAVE_CHARCONV_FLOAT
+
+
+namespace pqxx
+{
+namespace internal
+{
+template<> void builtin_traits<bool>::from_string(const char Str[], bool &Obj)
+{
+ bool OK, result=false;
+
+ switch (Str[0])
+ {
+ case 0:
+ result = false;
+ OK = true;
+ break;
+
+ case 'f':
+ case 'F':
+ result = false;
+ OK = not (
+ (Str[1] != '\0') and
+ (not equal(Str+1, "alse")) and
+ (not equal(Str+1, "ALSE")));
+ break;
+
+ case '0':
+ {
+ int I;
+ string_traits<int>::from_string(Str, I);
+ result = (I != 0);
+ OK = ((I == 0) or (I == 1));
+ }
+ break;
+
+ case '1':
+ result = true;
+ OK = (Str[1] == '\0');
+ break;
+
+ case 't':
+ case 'T':
+ result = true;
+ OK = not (
+ (Str[1] != '\0') and
+ (not equal(Str+1, "rue")) and
+ (not equal(Str+1, "RUE")));
+ break;
+
+ default:
+ OK = false;
+ }
+
+ if (not OK)
+ throw conversion_error{
+ "Failed conversion to bool: '" + std::string{Str} + "'."};
+
+ Obj = result;
+}
+
+
+template<> std::string builtin_traits<bool>::to_string(bool Obj)
+{
+ return Obj ? "true" : "false";
+}
+} // namespace pqxx::internal
+} // namespace pqxx
diff --git a/contrib/libs/libpqxx/src/stream_base.cxx b/contrib/libs/libpqxx/src/stream_base.cxx
new file mode 100644
index 0000000000..598c2260e4
--- /dev/null
+++ b/contrib/libs/libpqxx/src/stream_base.cxx
@@ -0,0 +1,43 @@
+/** Implementation of the pqxx::stream_base class.
+ *
+ * pqxx::stream_base provides optimized batch access to a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/stream_base.hxx"
+#include "pqxx/transaction"
+
+
+pqxx::stream_base::stream_base(transaction_base &tb) :
+ internal::namedclass("stream_base"),
+ internal::transactionfocus{tb},
+ m_finished{false}
+{}
+
+
+pqxx::stream_base::operator bool() const noexcept
+{
+ return not m_finished;
+}
+
+
+bool pqxx::stream_base::operator!() const noexcept
+{
+ return not static_cast<bool>(*this);
+}
+
+
+void pqxx::stream_base::close()
+{
+ if (*this)
+ {
+ m_finished = true;
+ unregister_me();
+ }
+}
diff --git a/contrib/libs/libpqxx/src/stream_from.cxx b/contrib/libs/libpqxx/src/stream_from.cxx
new file mode 100644
index 0000000000..8dbe2df3f3
--- /dev/null
+++ b/contrib/libs/libpqxx/src/stream_from.cxx
@@ -0,0 +1,261 @@
+/** Implementation of the pqxx::stream_from class.
+ *
+ * pqxx::stream_from enables optimized batch reads from a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/stream_from"
+
+#include "pqxx/internal/encodings.hxx"
+#include "pqxx/internal/gates/transaction-stream_from.hxx"
+
+
+namespace
+{
+ // bool is_octalchar(char o) noexcept
+ // {
+ // return (o>='0') and (o<='7');
+ // }
+
+ /// Find first tab character at or after start position in string
+ /** If not found, returns line.size() rather than string::npos.
+ */
+ std::string::size_type find_tab(
+ pqxx::internal::encoding_group enc,
+ const std::string &line,
+ std::string::size_type start
+ )
+ {
+ auto here = pqxx::internal::find_with_encoding(enc, line, '\t', start);
+ return (here == std::string::npos) ? line.size() : here;
+ }
+} // namespace
+
+
+pqxx::stream_from::stream_from(
+ transaction_base &tb,
+ const std::string &table_name
+) :
+ namedclass{"stream_from", table_name},
+ stream_base{tb},
+ m_retry_line{false}
+{
+ set_up(tb, table_name);
+}
+
+
+pqxx::stream_from::~stream_from() noexcept
+{
+ try
+ {
+ complete();
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+}
+
+
+void pqxx::stream_from::complete()
+{
+ close();
+}
+
+
+bool pqxx::stream_from::get_raw_line(std::string &line)
+{
+ internal::gate::transaction_stream_from gate{m_trans};
+ if (*this)
+ try
+ {
+ if (not gate.read_copy_line(line)) close();
+ }
+ catch (const std::exception &)
+ {
+ close();
+ throw;
+ }
+ return *this;
+}
+
+
+void pqxx::stream_from::set_up(
+ transaction_base &tb,
+ const std::string &table_name
+)
+{
+ set_up(tb, table_name, "");
+}
+
+
+void pqxx::stream_from::set_up(
+ transaction_base &tb,
+ const std::string &table_name,
+ const std::string &columns
+)
+{
+ // Get the encoding before starting the COPY, otherwise reading the the
+ // variable will interrupt it
+ m_copy_encoding = internal::enc_group(m_trans.conn().encoding_id());
+ internal::gate::transaction_stream_from{tb}.BeginCopyRead(
+ table_name,
+ columns
+ );
+ register_me();
+}
+
+
+void pqxx::stream_from::close()
+{
+ pqxx::stream_base::close();
+ try
+ {
+ // Flush any remaining lines
+ std::string s;
+ while (get_raw_line(s));
+ }
+ catch (const broken_connection &)
+ {
+ try
+ {
+ pqxx::stream_base::close();
+ }
+ catch (const std::exception &) {}
+ throw;
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+}
+
+
+bool pqxx::stream_from::extract_field(
+ const std::string &line,
+ std::string::size_type &i,
+ std::string &s
+) const
+{
+ using namespace pqxx::internal;
+
+ const auto next_seq = get_glyph_scanner(m_copy_encoding);
+ s.clear();
+ bool is_null{false};
+ auto stop = find_tab(m_copy_encoding, line, i);
+ while (i < stop)
+ {
+ auto glyph_end = next_seq(line.c_str(), line.size(), i);
+ auto seq_len = glyph_end - i;
+ if (seq_len == 1)
+ {
+ switch (line[i])
+ {
+ case '\n':
+ // End-of-row; shouldn't happen, but we may get old-style
+ // newline-terminated lines.
+ i = stop;
+ break;
+
+ case '\\':
+ {
+ // Escape sequence.
+ if (glyph_end >= line.size())
+ throw failure{"Row ends in backslash"};
+ char n = line[glyph_end++];
+
+ /*
+ * "Presently, COPY TO will never emit an octal or hex-digits
+ * backslash sequence [...]"
+ * - https://www.postgresql.org/docs/10/sql-copy.html
+ */
+ // if (is_octalchar(n))
+ // {
+ // if (here.end_byte+2 >= line.size())
+ // throw failure{"Row ends in middle of octal value"};
+ // char n1 = line[here.end_byte++];
+ // char n2 = line[here.end_byte++];
+ // if (not is_octalchar(n1) or not is_octalchar(n2))
+ // throw failure{
+ // "Invalid octal in encoded table stream"
+ // };
+ // s += (
+ // (digit_to_number(n)<<6) |
+ // (digit_to_number(n1)<<3) |
+ // digit_to_number(n2)
+ // );
+ // break;
+ // }
+ // else
+ switch (n)
+ {
+ case 'N':
+ // Null value
+ if (not s.empty())
+ throw failure{
+ "Null sequence found in nonempty field"
+ };
+ is_null = true;
+ break;
+
+ case 'b': // Backspace
+ s += '\b'; break;
+ case 'f': // Vertical tab
+ s += '\f'; break;
+ case 'n': // Form feed
+ s += '\n'; break;
+ case 'r': // Newline
+ s += '\r'; break;
+ case 't': // Tab
+ s += '\t'; break;
+ case 'v': // Carriage return
+ s += '\v'; break;
+
+ default:
+ // Self-escaped character
+ s += n;
+ break;
+ }
+ }
+ break;
+
+ default:
+ s += line[i];
+ break;
+ }
+ }
+ else
+ {
+ // Multi-byte sequence; never treated specially, so just append
+ s.insert(s.size(), line.c_str() + i, seq_len);
+ }
+
+ i = glyph_end;
+ }
+
+ // Skip field separator
+ i += 1;
+
+ return not is_null;
+}
+
+template<> void pqxx::stream_from::extract_value<std::nullptr_t>(
+ const std::string &line,
+ std::nullptr_t&,
+ std::string::size_type &here,
+ std::string &workspace
+) const
+{
+ if (extract_field(line, here, workspace))
+ throw pqxx::conversion_error{
+ "Attempt to convert non-null '"
+ + workspace
+ + "' to null"
+ };
+}
diff --git a/contrib/libs/libpqxx/src/stream_to.cxx b/contrib/libs/libpqxx/src/stream_to.cxx
new file mode 100644
index 0000000000..18e52b1e6a
--- /dev/null
+++ b/contrib/libs/libpqxx/src/stream_to.cxx
@@ -0,0 +1,142 @@
+/** Implementation of the pqxx::stream_to class.
+ *
+ * pqxx::stream_to enables optimized batch updates to a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/stream_to.hxx"
+
+#include "pqxx/internal/gates/transaction-stream_to.hxx"
+
+
+pqxx::stream_to::stream_to(
+ transaction_base &tb,
+ const std::string &table_name
+) :
+ namedclass{"stream_to", table_name},
+ stream_base{tb}
+{
+ set_up(tb, table_name);
+}
+
+
+pqxx::stream_to::~stream_to() noexcept
+{
+ try
+ {
+ complete();
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+}
+
+
+void pqxx::stream_to::complete()
+{
+ close();
+}
+
+
+void pqxx::stream_to::write_raw_line(const std::string &line)
+{
+ internal::gate::transaction_stream_to{m_trans}.write_copy_line(line);
+}
+
+
+pqxx::stream_to & pqxx::stream_to::operator<<(stream_from &tr)
+{
+ std::string line;
+ while (tr)
+ {
+ tr.get_raw_line(line);
+ write_raw_line(line);
+ }
+ return *this;
+}
+
+
+void pqxx::stream_to::set_up(
+ transaction_base &tb,
+ const std::string &table_name
+)
+{
+ set_up(tb, table_name, "");
+}
+
+
+void pqxx::stream_to::set_up(
+ transaction_base &tb,
+ const std::string &table_name,
+ const std::string &columns
+)
+{
+ internal::gate::transaction_stream_to{tb}.BeginCopyWrite(
+ table_name,
+ columns
+ );
+ register_me();
+}
+
+
+void pqxx::stream_to::close()
+{
+ if (*this)
+ {
+ stream_base::close();
+ try
+ {
+ internal::gate::transaction_stream_to{m_trans}.end_copy_write();
+ }
+ catch (const std::exception &)
+ {
+ try
+ {
+ stream_base::close();
+ }
+ catch (const std::exception &) {}
+ throw;
+ }
+ }
+}
+
+
+std::string pqxx::internal::TypedCopyEscaper::escape(const std::string &s)
+{
+ if (s.empty())
+ return s;
+
+ std::string escaped;
+ escaped.reserve(s.size()+1);
+
+ for (auto c : s)
+ switch (c)
+ {
+ case '\b': escaped += "\\b"; break; // Backspace
+ case '\f': escaped += "\\f"; break; // Vertical tab
+ case '\n': escaped += "\\n"; break; // Form feed
+ case '\r': escaped += "\\r"; break; // Newline
+ case '\t': escaped += "\\t"; break; // Tab
+ case '\v': escaped += "\\v"; break; // Carriage return
+ case '\\': escaped += "\\\\"; break; // Backslash
+ default:
+ if (c < ' ' or c > '~')
+ {
+ escaped += "\\";
+ for (auto i = 2; i >= 0; --i)
+ escaped += number_to_digit((c >> (3*i)) & 0x07);
+ }
+ else
+ escaped += c;
+ break;
+ }
+
+ return escaped;
+}
diff --git a/contrib/libs/libpqxx/src/subtransaction.cxx b/contrib/libs/libpqxx/src/subtransaction.cxx
new file mode 100644
index 0000000000..539c3c7847
--- /dev/null
+++ b/contrib/libs/libpqxx/src/subtransaction.cxx
@@ -0,0 +1,74 @@
+/** Implementation of the pqxx::subtransaction class.
+ *
+ * pqxx::transaction is a nested transaction, i.e. one within a transaction
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <stdexcept>
+
+#include "pqxx/connection_base"
+#include "pqxx/subtransaction"
+
+#include "pqxx/internal/gates/transaction-subtransaction.hxx"
+
+using namespace pqxx::internal;
+
+
+pqxx::subtransaction::subtransaction(
+ dbtransaction &T,
+ const std::string &Name) :
+ namedclass{"subtransaction", T.conn().adorn_name(Name)},
+ transactionfocus{T},
+ dbtransaction(T.conn(), false),
+ m_parent{T}
+{
+}
+
+
+namespace
+{
+using dbtransaction_ref = pqxx::dbtransaction &;
+}
+
+
+pqxx::subtransaction::subtransaction(
+ subtransaction &T,
+ const std::string &Name) :
+ subtransaction(dbtransaction_ref(T), Name)
+{
+}
+
+
+void pqxx::subtransaction::do_begin()
+{
+ try
+ {
+ direct_exec(("SAVEPOINT " + quote_name(name())).c_str());
+ }
+ catch (const sql_error &)
+ {
+ throw;
+ }
+}
+
+
+void pqxx::subtransaction::do_commit()
+{
+ const int ra = m_reactivation_avoidance.get();
+ m_reactivation_avoidance.clear();
+ direct_exec(("RELEASE SAVEPOINT " + quote_name(name())).c_str());
+ gate::transaction_subtransaction{m_parent}.add_reactivation_avoidance_count(
+ ra);
+}
+
+
+void pqxx::subtransaction::do_abort()
+{
+ direct_exec(("ROLLBACK TO SAVEPOINT " + quote_name(name())).c_str());
+}
diff --git a/contrib/libs/libpqxx/src/tablereader.cxx b/contrib/libs/libpqxx/src/tablereader.cxx
new file mode 100644
index 0000000000..4e4f315c66
--- /dev/null
+++ b/contrib/libs/libpqxx/src/tablereader.cxx
@@ -0,0 +1,227 @@
+/** Implementation of the pqxx::tablereader class.
+ *
+ * pqxx::tablereader enables optimized batch reads from a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/tablereader"
+#include "pqxx/transaction"
+
+#include "pqxx/internal/gates/transaction-tablereader.hxx"
+
+using namespace pqxx::internal;
+
+
+pqxx::tablereader::tablereader(
+ transaction_base &T,
+ const std::string &Name,
+ const std::string &Null) :
+ namedclass{"tablereader", Name},
+ tablestream(T, Null),
+ m_done{true}
+{
+ set_up(T, Name);
+}
+
+void pqxx::tablereader::set_up(
+ transaction_base &T,
+ const std::string &Name,
+ const std::string &Columns)
+{
+ gate::transaction_tablereader{T}.BeginCopyRead(Name, Columns);
+ register_me();
+ m_done = false;
+}
+
+pqxx::tablereader::~tablereader() noexcept
+{
+ try
+ {
+ reader_close();
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+}
+
+
+bool pqxx::tablereader::get_raw_line(std::string &Line)
+{
+ if (not m_done) try
+ {
+ m_done = not gate::transaction_tablereader{m_trans}.read_copy_line(Line);
+ }
+ catch (const std::exception &)
+ {
+ m_done = true;
+ throw;
+ }
+ return not m_done;
+}
+
+
+void pqxx::tablereader::complete()
+{
+ reader_close();
+}
+
+
+void pqxx::tablereader::reader_close()
+{
+ if (not is_finished())
+ {
+ base_close();
+
+ // If any lines remain to be read, consume them to not confuse PQendcopy()
+ if (not m_done)
+ {
+ try
+ {
+ std::string Dummy;
+ while (get_raw_line(Dummy)) ;
+ }
+ catch (const broken_connection &)
+ {
+ try { base_close(); } catch (const std::exception &) {}
+ throw;
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+ }
+ }
+}
+
+
+namespace
+{
+inline bool is_octalchar(char o) noexcept
+{
+ return (o>='0') and (o<='7');
+}
+
+/// Find first tab character at or after start position in string
+/** If not found, returns Line.size() rather than string::npos.
+ */
+std::string::size_type findtab(
+ const std::string &Line,
+ std::string::size_type start)
+{
+ // TODO: Fix for multibyte encodings?
+ const auto here = Line.find('\t', start);
+ return (here == std::string::npos) ? Line.size() : here;
+}
+} // namespace
+
+
+std::string pqxx::tablereader::extract_field(
+ const std::string &Line,
+ std::string::size_type &i) const
+{
+ // TODO: Pick better exception types
+ std::string R;
+ bool isnull=false;
+ auto stop = findtab(Line, i);
+ for (; i < stop; ++i)
+ {
+ const char c = Line[i];
+ switch (c)
+ {
+ case '\n': // End of row
+ // Shouldn't happen, but we may get old-style, newline-terminated lines
+ i = stop;
+ break;
+
+ case '\\': // Escape sequence
+ {
+ const char n = Line[++i];
+ if (i >= Line.size())
+ throw failure{"Row ends in backslash."};
+
+ switch (n)
+ {
+ case 'N': // Null value
+ if (not R.empty())
+ throw failure{"Null sequence found in nonempty field."};
+ R = NullStr();
+ isnull = true;
+ break;
+
+ case '0': // Octal sequence (3 digits)
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ if ((i+2) >= Line.size())
+ throw failure{"Row ends in middle of octal value."};
+ const char n1 = Line[++i];
+ const char n2 = Line[++i];
+ if (not is_octalchar(n1) or not is_octalchar(n2))
+ throw failure{"Invalid octal in encoded table stream."};
+ R += char(
+ (digit_to_number(n)<<6) |
+ (digit_to_number(n1)<<3) |
+ digit_to_number(n2));
+ }
+ break;
+
+ case 'b':
+ // TODO: Escape code?
+ R += char(8);
+ break; // Backspace
+ case 'v':
+ // TODO: Escape code?
+ R += char(11);
+ break; // Vertical tab
+ case 'f':
+ // TODO: Escape code?
+ R += char(12);
+ break; // Form feed
+ case 'n':
+ R += '\n';
+ break; // Newline
+ case 't':
+ R += '\t';
+ break; // Tab
+ case 'r':
+ R += '\r';
+ break; // Carriage return;
+
+ default: // Self-escaped character
+ R += n;
+ // This may be a self-escaped tab that we thought was a terminator...
+ if (i == stop)
+ {
+ if ((i+1) >= Line.size())
+ throw internal_error{"COPY line ends in backslash."};
+ stop = findtab(Line, i+1);
+ }
+ break;
+ }
+ }
+ break;
+
+ default:
+ R += c;
+ break;
+ }
+ }
+ ++i;
+
+ if (isnull and (R.size() != NullStr().size()))
+ throw failure{"Field contains data behind null sequence."};
+
+ return R;
+}
diff --git a/contrib/libs/libpqxx/src/tablestream.cxx b/contrib/libs/libpqxx/src/tablestream.cxx
new file mode 100644
index 0000000000..6ab0148e1e
--- /dev/null
+++ b/contrib/libs/libpqxx/src/tablestream.cxx
@@ -0,0 +1,38 @@
+/** Implementation of the pqxx::tablestream class.
+ *
+ * pqxx::tablestream provides optimized batch access to a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/tablestream"
+#include "pqxx/transaction"
+
+
+pqxx::tablestream::tablestream(transaction_base &STrans,
+ const std::string &Null) :
+ internal::namedclass{"tablestream"},
+ internal::transactionfocus{STrans},
+ m_null{Null}
+{
+}
+
+
+pqxx::tablestream::~tablestream() noexcept
+{
+}
+
+
+void pqxx::tablestream::base_close()
+{
+ if (not is_finished())
+ {
+ m_finished = true;
+ unregister_me();
+ }
+}
diff --git a/contrib/libs/libpqxx/src/tablewriter.cxx b/contrib/libs/libpqxx/src/tablewriter.cxx
new file mode 100644
index 0000000000..3ca5dae253
--- /dev/null
+++ b/contrib/libs/libpqxx/src/tablewriter.cxx
@@ -0,0 +1,160 @@
+/** Implementation of the pqxx::tablewriter class.
+ *
+ * pqxx::tablewriter enables optimized batch updates to a database table.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/tablereader"
+#include "pqxx/tablewriter"
+#include "pqxx/transaction"
+
+#include "pqxx/internal/gates/transaction-tablewriter.hxx"
+
+using namespace pqxx::internal;
+
+
+pqxx::tablewriter::tablewriter(
+ transaction_base &T,
+ const std::string &WName,
+ const std::string &Null) :
+ namedclass{"tablewriter", WName},
+ tablestream(T, Null)
+{
+ set_up(T, WName);
+}
+
+
+pqxx::tablewriter::~tablewriter() noexcept
+{
+ try
+ {
+ writer_close();
+ }
+ catch (const std::exception &e)
+ {
+ reg_pending_error(e.what());
+ }
+}
+
+
+void pqxx::tablewriter::set_up(
+ transaction_base &T,
+ const std::string &WName,
+ const std::string &Columns)
+{
+ gate::transaction_tablewriter{T}.BeginCopyWrite(WName, Columns);
+ register_me();
+}
+
+
+pqxx::tablewriter &pqxx::tablewriter::operator<<(pqxx::tablereader &R)
+{
+ std::string Line;
+ // TODO: Can we do this in binary mode? (Might require protocol version check)
+ while (R.get_raw_line(Line)) write_raw_line(Line);
+ return *this;
+}
+
+
+void pqxx::tablewriter::write_raw_line(const std::string &Line)
+{
+ const std::string::size_type len = Line.size();
+ gate::transaction_tablewriter{m_trans}.write_copy_line(
+ ((len == 0) or (Line[len-1] != '\n')) ?
+ Line :
+ std::string{Line, 0, len-1});
+}
+
+
+void pqxx::tablewriter::complete()
+{
+ writer_close();
+}
+
+
+void pqxx::tablewriter::writer_close()
+{
+ if (not is_finished())
+ {
+ base_close();
+ try
+ {
+ gate::transaction_tablewriter{m_trans}.end_copy_write();
+ }
+ catch (const std::exception &)
+ {
+ try { base_close(); } catch (const std::exception &) {}
+ throw;
+ }
+ }
+}
+
+
+namespace
+{
+inline char escapechar(char i) noexcept
+{
+ char r = '\0';
+ switch (i)
+ {
+ case 8: r='b'; break; // backspace
+ case 11: r='v'; break; // vertical tab
+ case 12: r='f'; break; // form feed
+ case '\n': r='n'; break; // newline
+ case '\t': r='t'; break; // tab
+ case '\r': r='r'; break; // carriage return
+ case '\\': r='\\'; break; // backslash
+ }
+ return r;
+}
+
+inline bool unprintable(char i) noexcept
+{
+ return i < ' ' or i > '~';
+}
+
+inline char tooctdigit(char c, int n)
+{
+ using unsigned_char = unsigned char;
+ unsigned int i = unsigned_char(c);
+ return number_to_digit((i>>(3*n)) & 0x07);
+}
+} // namespace
+
+
+std::string pqxx::internal::escape(
+ const std::string &s,
+ const std::string &null)
+{
+ if (s == null) return "\\N";
+ if (s.empty()) return s;
+
+ std::string R;
+ R.reserve(s.size()+1);
+
+ for (const auto c: s)
+ {
+ const char e = escapechar(c);
+ if (e)
+ {
+ R += '\\';
+ R += e;
+ }
+ else if (unprintable(c))
+ {
+ R += "\\";
+ for (int n=2; n>=0; --n) R += tooctdigit(c, n);
+ }
+ else
+ {
+ R += c;
+ }
+ }
+ return R;
+}
diff --git a/contrib/libs/libpqxx/src/transaction.cxx b/contrib/libs/libpqxx/src/transaction.cxx
new file mode 100644
index 0000000000..ff0f469e6c
--- /dev/null
+++ b/contrib/libs/libpqxx/src/transaction.cxx
@@ -0,0 +1,72 @@
+/** Implementation of the pqxx::transaction class.
+ *
+ * pqxx::transaction represents a regular database transaction.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <stdexcept>
+
+#include "pqxx/connection_base"
+#include "pqxx/result"
+#include "pqxx/transaction"
+
+
+pqxx::internal::basic_transaction::basic_transaction(
+ connection_base &C,
+ const std::string &IsolationLevel,
+ readwrite_policy rw) :
+ namedclass{"transaction"},
+ dbtransaction(C, IsolationLevel, rw)
+{
+}
+
+
+void pqxx::internal::basic_transaction::do_commit()
+{
+ try
+ {
+ direct_exec("COMMIT");
+ }
+ catch (const statement_completion_unknown &e)
+ {
+ // Outcome of "commit" is unknown. This is a disaster: we don't know the
+ // resulting state of the database.
+ process_notice(e.what() + std::string{"\n"});
+ const std::string msg =
+ "WARNING: Commit of transaction '" + name() + "' is unknown. "
+ "There is no way to tell whether the transaction succeeded "
+ "or was aborted except to check manually.";
+ process_notice(msg + "\n");
+ throw in_doubt_error{msg};
+ }
+ catch (const std::exception &e)
+ {
+ if (not conn().is_open())
+ {
+ // We've lost the connection while committing. There is just no way of
+ // telling what happened on the other end. >8-O
+ process_notice(e.what() + std::string{"\n"});
+
+ const std::string Msg =
+ "WARNING: Connection lost while committing transaction "
+ "'" + name() + "'. "
+ "There is no way to tell whether the transaction succeeded "
+ "or was aborted except to check manually.";
+
+ process_notice(Msg + "\n");
+ throw in_doubt_error{Msg};
+ }
+ else
+ {
+ // Commit failed--probably due to a constraint violation or something
+ // similar.
+ throw;
+ }
+ }
+}
diff --git a/contrib/libs/libpqxx/src/transaction_base.cxx b/contrib/libs/libpqxx/src/transaction_base.cxx
new file mode 100644
index 0000000000..84a7ab7e1b
--- /dev/null
+++ b/contrib/libs/libpqxx/src/transaction_base.cxx
@@ -0,0 +1,577 @@
+/** Common code and definitions for the transaction classes.
+ *
+ * pqxx::transaction_base defines the interface for any abstract class that
+ * represents a database transaction.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cstring>
+#include <stdexcept>
+
+#include "pqxx/connection_base"
+#include "pqxx/result"
+#include "pqxx/transaction_base"
+
+#include "pqxx/internal/gates/connection-transaction.hxx"
+#include "pqxx/internal/gates/connection-parameterized_invocation.hxx"
+#include "pqxx/internal/gates/transaction-transactionfocus.hxx"
+
+#include "pqxx/internal/encodings.hxx"
+
+
+using namespace pqxx::internal;
+
+
+pqxx::internal::parameterized_invocation::parameterized_invocation(
+ connection_base &c,
+ const std::string &query) :
+ m_home{c},
+ m_query{query}
+{
+}
+
+
+pqxx::result pqxx::internal::parameterized_invocation::exec()
+{
+ std::vector<const char *> values;
+ std::vector<int> lengths;
+ std::vector<int> binaries;
+ const int elements = marshall(values, lengths, binaries);
+
+ return gate::connection_parameterized_invocation{m_home}.parameterized_exec(
+ m_query,
+ values.data(),
+ lengths.data(),
+ binaries.data(),
+ elements);
+}
+
+
+pqxx::transaction_base::transaction_base(connection_base &C, bool direct) :
+ namedclass{"transaction_base"},
+ m_conn{C}
+{
+ if (direct)
+ {
+ gate::connection_transaction gate{conn()};
+ gate.register_transaction(this);
+ m_registered = true;
+ }
+}
+
+
+pqxx::transaction_base::~transaction_base()
+{
+ try
+ {
+ reactivation_avoidance_clear();
+ if (not m_pending_error.empty())
+ process_notice("UNPROCESSED ERROR: " + m_pending_error + "\n");
+
+ if (m_registered)
+ {
+ m_conn.process_notice(description() + " was never closed properly!\n");
+ gate::connection_transaction gate{conn()};
+ gate.unregister_transaction(this);
+ }
+ }
+ catch (const std::exception &e)
+ {
+ try
+ {
+ process_notice(std::string{e.what()} + "\n");
+ }
+ catch (const std::exception &)
+ {
+ process_notice(e.what());
+ }
+ }
+}
+
+
+void pqxx::transaction_base::commit()
+{
+ CheckPendingError();
+
+ // Check previous status code. Caller should only call this function if
+ // we're in "implicit" state, but multiple commits are silently accepted.
+ switch (m_status)
+ {
+ case st_nascent: // Empty transaction. No skin off our nose.
+ return;
+
+ case st_active: // Just fine. This is what we expect.
+ break;
+
+ case st_aborted:
+ throw usage_error{"Attempt to commit previously aborted " + description()};
+
+ case st_committed:
+ // Transaction has been committed already. This is not exactly proper
+ // behaviour, but throwing an exception here would only give the impression
+ // that an abort is needed--which would only confuse things further at this
+ // stage.
+ // Therefore, multiple commits are accepted, though under protest.
+ m_conn.process_notice(description() + " committed more than once.\n");
+ return;
+
+ case st_in_doubt:
+ // Transaction may or may not have been committed. The only thing we can
+ // really do is keep telling the caller that the transaction is in doubt.
+ throw in_doubt_error{
+ description() + " committed again while in an indeterminate state."};
+
+ default:
+ throw internal_error{"pqxx::transaction: invalid status code."};
+ }
+
+ // Tricky one. If stream is nested in transaction but inside the same scope,
+ // the commit() will come before the stream is closed. Which means the
+ // commit is premature. Punish this swiftly and without fail to discourage
+ // the habit from forming.
+ if (m_focus.get())
+ throw failure{
+ "Attempt to commit " + description() + " with " +
+ m_focus.get()->description() + " still open."};
+
+ // Check that we're still connected (as far as we know--this is not an
+ // absolute thing!) before trying to commit. If the connection was broken
+ // already, the commit would fail anyway but this way at least we don't remain
+ // in-doubt as to whether the backend got the commit order at all.
+ if (not m_conn.is_open())
+ throw broken_connection{
+ "Broken connection to backend; cannot complete transaction."};
+
+ try
+ {
+ do_commit();
+ m_status = st_committed;
+ }
+ catch (const in_doubt_error &)
+ {
+ m_status = st_in_doubt;
+ throw;
+ }
+ catch (const std::exception &)
+ {
+ m_status = st_aborted;
+ throw;
+ }
+
+ gate::connection_transaction gate{conn()};
+ gate.add_variables(m_vars);
+
+ End();
+}
+
+
+void pqxx::transaction_base::abort()
+{
+ // Check previous status code. Quietly accept multiple aborts to
+ // simplify emergency bailout code.
+ switch (m_status)
+ {
+ case st_nascent: // Never began transaction. No need to issue rollback.
+ break;
+
+ case st_active:
+ try { do_abort(); } catch (const std::exception &) { }
+ break;
+
+ case st_aborted:
+ return;
+
+ case st_committed:
+ throw usage_error{"Attempt to abort previously committed " + description()};
+
+ case st_in_doubt:
+ // Aborting an in-doubt transaction is probably a reasonably sane response
+ // to an insane situation. Log it, but do not complain.
+ m_conn.process_notice(
+ "Warning: " + description() + " aborted after going into "
+ "indeterminate state; it may have been executed anyway.\n");
+ return;
+
+ default:
+ throw internal_error{"Invalid transaction status."};
+ }
+
+ m_status = st_aborted;
+ End();
+}
+
+
+std::string pqxx::transaction_base::esc_raw(const std::string &str) const
+{
+ const unsigned char *p = reinterpret_cast<const unsigned char *>(str.c_str());
+ return conn().esc_raw(p, str.size());
+}
+
+
+std::string pqxx::transaction_base::quote_raw(const std::string &str) const
+{
+ const unsigned char *p = reinterpret_cast<const unsigned char *>(str.c_str());
+ return conn().quote_raw(p, str.size());
+}
+
+
+void pqxx::transaction_base::activate()
+{
+ switch (m_status)
+ {
+ case st_nascent:
+ // Make sure transaction has begun before executing anything
+ Begin();
+ break;
+
+ case st_active:
+ break;
+
+ case st_committed:
+ case st_aborted:
+ case st_in_doubt:
+ throw usage_error{
+ "Attempt to activate " + description() + " "
+ "which is already closed."};
+
+ default:
+ throw internal_error{"pqxx::transaction: invalid status code."};
+ }
+}
+
+
+pqxx::result pqxx::transaction_base::exec(
+ const std::string &Query,
+ const std::string &Desc)
+{
+ CheckPendingError();
+
+ const std::string N = (Desc.empty() ? "" : "'" + Desc + "' ");
+
+ if (m_focus.get())
+ throw usage_error{
+ "Attempt to execute query " + N +
+ "on " + description() + " "
+ "with " + m_focus.get()->description() + " still open."};
+
+ try
+ {
+ activate();
+ }
+ catch (const usage_error &e)
+ {
+ throw usage_error{"Error executing query " + N + ". " + e.what()};
+ }
+
+ // TODO: Pass Desc to do_exec(), and from there on down
+ return do_exec(Query.c_str());
+}
+
+
+pqxx::result pqxx::transaction_base::exec_n(
+ size_t rows,
+ const std::string &Query,
+ const std::string &Desc)
+{
+ const result r = exec(Query, Desc);
+ if (r.size() != rows)
+ {
+ const std::string N = (Desc.empty() ? "" : "'" + Desc + "'");
+ throw unexpected_rows{
+ "Expected " + to_string(rows) + " row(s) of data "
+ "from query " + N + ", got " + to_string(r.size()) + "."};
+ }
+ return r;
+}
+
+
+void pqxx::transaction_base::check_rowcount_prepared(
+ const std::string &statement,
+ size_t expected_rows,
+ size_t actual_rows)
+{
+ if (actual_rows != expected_rows)
+ {
+ throw unexpected_rows{
+ "Expected " + to_string(expected_rows) + " row(s) of data "
+ "from prepared statement '" + statement + "', got " +
+ to_string(actual_rows) + "."};
+ }
+}
+
+
+void pqxx::transaction_base::check_rowcount_params(
+ size_t expected_rows,
+ size_t actual_rows)
+{
+ if (actual_rows != expected_rows)
+ {
+ throw unexpected_rows{
+ "Expected " + to_string(expected_rows) + " row(s) of data "
+ "from parameterised query, got " + to_string(actual_rows) + "."};
+ }
+}
+
+
+pqxx::internal::parameterized_invocation
+pqxx::transaction_base::parameterized(const std::string &query)
+{
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ return internal::parameterized_invocation{conn(), query};
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+}
+
+
+pqxx::prepare::invocation
+pqxx::transaction_base::prepared(const std::string &statement)
+{
+ try
+ {
+ activate();
+ }
+ catch (const usage_error &e)
+ {
+ throw usage_error{
+ "Error executing prepared statement " + statement + ". " + e.what()};
+ }
+#include "pqxx/internal/ignore-deprecated-pre.hxx"
+ return prepare::invocation{*this, statement};
+#include "pqxx/internal/ignore-deprecated-post.hxx"
+}
+
+
+pqxx::result pqxx::transaction_base::internal_exec_prepared(
+ const std::string &statement,
+ const internal::params &args,
+ result_format format)
+{
+ gate::connection_transaction gate{conn()};
+ return gate.exec_prepared(statement, args, format);
+}
+
+
+pqxx::result pqxx::transaction_base::internal_exec_params(
+ const std::string &query,
+ const internal::params &args)
+{
+ gate::connection_transaction gate{conn()};
+ return gate.exec_params(query, args);
+}
+
+
+void pqxx::transaction_base::set_variable(
+ const std::string &Var,
+ const std::string &Value)
+{
+ // Before committing to this new value, see what the backend thinks about it
+ gate::connection_transaction gate{conn()};
+ gate.raw_set_var(Var, Value);
+ m_vars[Var] = Value;
+}
+
+
+std::string pqxx::transaction_base::get_variable(const std::string &Var)
+{
+ const std::map<std::string,std::string>::const_iterator i = m_vars.find(Var);
+ if (i != m_vars.end()) return i->second;
+ return gate::connection_transaction{conn()}.raw_get_var(Var);
+}
+
+
+void pqxx::transaction_base::Begin()
+{
+ if (m_status != st_nascent)
+ throw internal_error{
+ "pqxx::transaction: Begin() called while not in nascent state."};
+
+ try
+ {
+ // Better handle any pending notifications before we begin
+ m_conn.get_notifs();
+
+ do_begin();
+ m_status = st_active;
+ }
+ catch (const std::exception &)
+ {
+ End();
+ throw;
+ }
+}
+
+
+void pqxx::transaction_base::End() noexcept
+{
+ try
+ {
+ try { CheckPendingError(); }
+ catch (const std::exception &e) { m_conn.process_notice(e.what()); }
+
+ gate::connection_transaction gate{conn()};
+ if (m_registered)
+ {
+ m_registered = false;
+ gate.unregister_transaction(this);
+ }
+
+ if (m_status != st_active) return;
+
+ if (m_focus.get())
+ m_conn.process_notice(
+ "Closing " + description() + " with " +
+ m_focus.get()->description() + " still open.\n");
+
+ try { abort(); }
+ catch (const std::exception &e) { m_conn.process_notice(e.what()); }
+
+ gate.take_reactivation_avoidance(m_reactivation_avoidance.get());
+ m_reactivation_avoidance.clear();
+ }
+ catch (const std::exception &e)
+ {
+ try { m_conn.process_notice(e.what()); } catch (const std::exception &) {}
+ }
+}
+
+
+void pqxx::transaction_base::register_focus(internal::transactionfocus *S)
+{
+ m_focus.register_guest(S);
+}
+
+
+void pqxx::transaction_base::unregister_focus(internal::transactionfocus *S)
+ noexcept
+{
+ try
+ {
+ m_focus.unregister_guest(S);
+ }
+ catch (const std::exception &e)
+ {
+ m_conn.process_notice(std::string{e.what()} + "\n");
+ }
+}
+
+
+pqxx::result pqxx::transaction_base::direct_exec(const char C[], int Retries)
+{
+ CheckPendingError();
+ return gate::connection_transaction{conn()}.exec(C, Retries);
+}
+
+
+void pqxx::transaction_base::register_pending_error(const std::string &Err)
+ noexcept
+{
+ if (m_pending_error.empty() and not Err.empty())
+ {
+ try
+ {
+ m_pending_error = Err;
+ }
+ catch (const std::exception &e)
+ {
+ try
+ {
+ process_notice("UNABLE TO PROCESS ERROR\n");
+ process_notice(e.what());
+ process_notice("ERROR WAS:");
+ process_notice(Err);
+ }
+ catch (...)
+ {
+ }
+ }
+ }
+}
+
+
+void pqxx::transaction_base::CheckPendingError()
+{
+ if (not m_pending_error.empty())
+ {
+ const std::string Err{m_pending_error};
+ m_pending_error.clear();
+ throw failure{Err};
+ }
+}
+
+
+namespace
+{
+std::string MakeCopyString(
+ const std::string &Table,
+ const std::string &Columns)
+{
+ std::string Q = "COPY " + Table + " ";
+ if (not Columns.empty()) Q += "(" + Columns + ") ";
+ return Q;
+}
+} // namespace
+
+
+void pqxx::transaction_base::BeginCopyRead(
+ const std::string &Table,
+ const std::string &Columns)
+{
+ exec(MakeCopyString(Table, Columns) + "TO STDOUT");
+}
+
+
+void pqxx::transaction_base::BeginCopyWrite(
+ const std::string &Table,
+ const std::string &Columns)
+{
+ exec(MakeCopyString(Table, Columns) + "FROM STDIN");
+}
+
+
+bool pqxx::transaction_base::read_copy_line(std::string &line)
+{
+ return gate::connection_transaction{conn()}.read_copy_line(line);
+}
+
+
+void pqxx::transaction_base::write_copy_line(const std::string &line)
+{
+ gate::connection_transaction gate{conn()};
+ gate.write_copy_line(line);
+}
+
+
+void pqxx::transaction_base::end_copy_write()
+{
+ gate::connection_transaction gate{conn()};
+ gate.end_copy_write();
+}
+
+
+void pqxx::internal::transactionfocus::register_me()
+{
+ gate::transaction_transactionfocus gate{m_trans};
+ gate.register_focus(this);
+ m_registered = true;
+}
+
+
+void pqxx::internal::transactionfocus::unregister_me() noexcept
+{
+ gate::transaction_transactionfocus gate{m_trans};
+ gate.unregister_focus(this);
+ m_registered = false;
+}
+
+void
+pqxx::internal::transactionfocus::reg_pending_error(const std::string &err)
+ noexcept
+{
+ gate::transaction_transactionfocus gate{m_trans};
+ gate.register_pending_error(err);
+}
diff --git a/contrib/libs/libpqxx/src/util.cxx b/contrib/libs/libpqxx/src/util.cxx
new file mode 100644
index 0000000000..646ace9930
--- /dev/null
+++ b/contrib/libs/libpqxx/src/util.cxx
@@ -0,0 +1,121 @@
+/** Various utility functions.
+ *
+ * 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.
+ */
+#include "pqxx/compiler-internal.hxx"
+
+#include <cerrno>
+#include <chrono>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+#include <thread>
+
+extern "C"
+{
+#include "libpq-fe.h"
+}
+
+#include "pqxx/except"
+#include "pqxx/util"
+
+
+using namespace pqxx::internal;
+
+
+pqxx::thread_safety_model pqxx::describe_thread_safety() noexcept
+{
+ thread_safety_model model;
+
+ if (PQisthreadsafe())
+ {
+ model.safe_libpq = true;
+ }
+ else
+ {
+ model.safe_libpq = false;
+ model.description += "Using a libpq build that is not thread-safe.\n";
+ }
+
+ // Sadly I'm not aware of any way to avoid this just yet.
+ model.safe_kerberos = false;
+ model.description +=
+ "Kerberos is not thread-safe. If your application uses Kerberos, "
+ "protect all calls to Kerberos or libpqxx using a global lock.\n";
+
+ return model;
+}
+
+
+std::string pqxx::internal::namedclass::description() const
+{
+ try
+ {
+ std::string desc = classname();
+ if (not name().empty()) desc += " '" + name() + "'";
+ return desc;
+ }
+ catch (const std::exception &)
+ {
+ // Oops, string composition failed! Probably out of memory.
+ // Let's try something easier.
+ }
+ return name().empty() ? classname() : name();
+}
+
+
+void pqxx::internal::CheckUniqueRegistration(const namedclass *New,
+ const namedclass *Old)
+{
+ if (New == nullptr)
+ throw internal_error{"null pointer registered."};
+ if (Old)
+ {
+ if (Old == New)
+ throw usage_error{"Started twice: " + New->description()};
+ throw usage_error{
+ "Started " + New->description() + " while " + Old->description() +
+ " still active."};
+ }
+}
+
+
+void pqxx::internal::CheckUniqueUnregistration(const namedclass *New,
+ const namedclass *Old)
+{
+ if (New != Old)
+ {
+ if (New == nullptr)
+ throw usage_error{
+ "Expected to close " + Old->description() + ", "
+ "but got null pointer instead."};
+ if (Old == nullptr)
+ throw usage_error{"Closed while not open: " + New->description()};
+ throw usage_error{
+ "Closed " + New->description() + "; "
+ "expected to close " + Old->description()};
+ }
+}
+
+
+void pqxx::internal::freepqmem(const void *p) noexcept
+{
+ PQfreemem(const_cast<void *>(p));
+}
+
+
+void pqxx::internal::freemallocmem(const void *p) noexcept
+{
+ free(const_cast<void *>(p));
+}
+
+
+void pqxx::internal::sleep_seconds(int s)
+{
+ std::this_thread::sleep_for(std::chrono::seconds(s));
+}
diff --git a/contrib/libs/libpqxx/src/version.cxx b/contrib/libs/libpqxx/src/version.cxx
new file mode 100644
index 0000000000..1fba1ec6d4
--- /dev/null
+++ b/contrib/libs/libpqxx/src/version.cxx
@@ -0,0 +1,18 @@
+#include "pqxx/compiler-internal.hxx"
+
+#include "pqxx/version"
+
+namespace pqxx
+{
+namespace internal
+{
+// One, single definition of this function. If a call fails to link, then the
+// libpqxx binary was built against a different libpqxx version than the code
+// which is being linked against it.
+template<> PQXX_LIBEXPORT
+int check_library_version<PQXX_VERSION_MAJOR, PQXX_VERSION_MINOR>() noexcept
+{
+ return 0;
+}
+}
+}
diff --git a/contrib/libs/libpqxx/ya.make b/contrib/libs/libpqxx/ya.make
new file mode 100644
index 0000000000..cd0e48d9a2
--- /dev/null
+++ b/contrib/libs/libpqxx/ya.make
@@ -0,0 +1,66 @@
+# Generated by devtools/yamaker from nixpkgs 22.05.
+
+LIBRARY()
+
+LICENSE(BSD-3-Clause)
+
+LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
+
+VERSION(6.4.5)
+
+ORIGINAL_SOURCE(https://github.com/jtv/libpqxx/archive/6.4.5.tar.gz)
+
+PEERDIR(
+ contrib/libs/libpq
+)
+
+ADDINCL(
+ GLOBAL contrib/libs/libpqxx/include
+ contrib/libs/libpq
+ contrib/libs/libpq/src/interfaces/libpq
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+CFLAGS(
+ -DHAVE_CONFIG_H
+)
+
+SRCS(
+ src/array.cxx
+ src/binarystring.cxx
+ src/connection.cxx
+ src/connection_base.cxx
+ src/cursor.cxx
+ src/dbtransaction.cxx
+ src/encodings.cxx
+ src/errorhandler.cxx
+ src/except.cxx
+ src/field.cxx
+ src/largeobject.cxx
+ src/nontransaction.cxx
+ src/notification.cxx
+ src/pipeline.cxx
+ src/prepared_statement.cxx
+ src/result.cxx
+ src/robusttransaction.cxx
+ src/row.cxx
+ src/sql_cursor.cxx
+ src/statement_parameters.cxx
+ src/strconv.cxx
+ src/stream_base.cxx
+ src/stream_from.cxx
+ src/stream_to.cxx
+ src/subtransaction.cxx
+ src/tablereader.cxx
+ src/tablestream.cxx
+ src/tablewriter.cxx
+ src/transaction.cxx
+ src/transaction_base.cxx
+ src/util.cxx
+ src/version.cxx
+)
+
+END()