diff options
author | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 11:26:33 +0300 |
---|---|---|
committer | galaxycrab <UgnineSirdis@ydb.tech> | 2023-11-23 12:01:57 +0300 |
commit | 44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300 (patch) | |
tree | cb4d75cd1c6dbc3da0ed927337fd8d1b6ed9da84 /contrib/libs/libpqxx/src/tablewriter.cxx | |
parent | 0e69bf615395fdd48ecee032faaec81bc468b0b8 (diff) | |
download | ydb-44354d0fc55926c1d4510d1d2c9c9f6a1a5e9300.tar.gz |
YQ Connector:test INNER JOIN
Diffstat (limited to 'contrib/libs/libpqxx/src/tablewriter.cxx')
-rw-r--r-- | contrib/libs/libpqxx/src/tablewriter.cxx | 160 |
1 files changed, 160 insertions, 0 deletions
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; +} |