transaction_base.hxx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /** Common code and definitions for the transaction classes.
  2. *
  3. * pqxx::transaction_base defines the interface for any abstract class that
  4. * represents a database transaction.
  5. *
  6. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/transaction_base instead.
  7. *
  8. * Copyright (c) 2000-2019, Jeroen T. Vermeulen.
  9. *
  10. * See COPYING for copyright license. If you did not receive a file called
  11. * COPYING with this source code, please notify the distributor of this mistake,
  12. * or contact the author.
  13. */
  14. #ifndef PQXX_H_TRANSACTION_BASE
  15. #define PQXX_H_TRANSACTION_BASE
  16. #include "pqxx/compiler-public.hxx"
  17. #include "pqxx/compiler-internal-pre.hxx"
  18. /* End-user programs need not include this file, unless they define their own
  19. * transaction classes. This is not something the typical program should want
  20. * to do.
  21. *
  22. * However, reading this file is worthwhile because it defines the public
  23. * interface for the available transaction classes such as transaction and
  24. * nontransaction.
  25. */
  26. #include "pqxx/connection_base.hxx"
  27. #include "pqxx/internal/encoding_group.hxx"
  28. #include "pqxx/isolation.hxx"
  29. #include "pqxx/result.hxx"
  30. #include "pqxx/row.hxx"
  31. // Methods tested in eg. test module test01 are marked with "//[t01]".
  32. namespace pqxx
  33. {
  34. namespace internal
  35. {
  36. class sql_cursor;
  37. class PQXX_LIBEXPORT transactionfocus : public virtual namedclass
  38. {
  39. public:
  40. explicit transactionfocus(transaction_base &t) :
  41. namedclass{"transactionfocus"},
  42. m_trans{t},
  43. m_registered{false}
  44. {
  45. }
  46. transactionfocus() =delete;
  47. transactionfocus(const transactionfocus &) =delete;
  48. transactionfocus &operator=(const transactionfocus &) =delete;
  49. protected:
  50. void register_me();
  51. void unregister_me() noexcept;
  52. void reg_pending_error(const std::string &) noexcept;
  53. bool registered() const noexcept { return m_registered; }
  54. transaction_base &m_trans;
  55. private:
  56. bool m_registered;
  57. };
  58. /// Helper class to construct an invocation of a parameterised statement.
  59. /** @deprecated Use @c exec_params and friends instead.
  60. */
  61. class PQXX_LIBEXPORT parameterized_invocation : statement_parameters
  62. {
  63. public:
  64. PQXX_DEPRECATED parameterized_invocation(
  65. connection_base &, const std::string &query);
  66. parameterized_invocation &operator()() { add_param(); return *this; }
  67. parameterized_invocation &operator()(const binarystring &v)
  68. { add_binary_param(v, true); return *this; }
  69. template<typename T> parameterized_invocation &operator()(const T &v)
  70. { add_param(v, true); return *this; }
  71. parameterized_invocation &operator()(const binarystring &v, bool nonnull)
  72. { add_binary_param(v, nonnull); return *this; }
  73. template<typename T>
  74. parameterized_invocation &operator()(const T &v, bool nonnull)
  75. { add_param(v, nonnull); return *this; }
  76. result exec();
  77. private:
  78. /// Not allowed
  79. parameterized_invocation &operator=(const parameterized_invocation &)
  80. =delete;
  81. connection_base &m_home;
  82. const std::string m_query;
  83. };
  84. } // namespace internal
  85. namespace internal
  86. {
  87. namespace gate
  88. {
  89. class transaction_subtransaction;
  90. class transaction_tablereader;
  91. class transaction_sql_cursor;
  92. class transaction_stream_from;
  93. class transaction_tablewriter;
  94. class transaction_stream_to;
  95. class transaction_transactionfocus;
  96. } // namespace internal::gate
  97. } // namespace internal
  98. /**
  99. * @defgroup transaction Transaction classes
  100. *
  101. * All database access goes through instances of these classes.
  102. * However, not all implementations of this interface need to provide
  103. * full transactional integrity.
  104. *
  105. * Several implementations of this interface are shipped with libpqxx, including
  106. * the plain transaction class, the entirely unprotected nontransaction, and the
  107. * more cautious robusttransaction.
  108. */
  109. /// Interface definition (and common code) for "transaction" classes.
  110. /**
  111. * @ingroup transaction
  112. *
  113. * Abstract base class for all transaction types.
  114. */
  115. class PQXX_LIBEXPORT PQXX_NOVTABLE transaction_base :
  116. public virtual internal::namedclass
  117. {
  118. public:
  119. /// If nothing else is known, our isolation level is at least read_committed
  120. using isolation_tag = isolation_traits<read_committed>;
  121. transaction_base() =delete;
  122. transaction_base(const transaction_base &) =delete;
  123. transaction_base &operator=(const transaction_base &) =delete;
  124. virtual ~transaction_base() =0; //[t01]
  125. /// Commit the transaction
  126. /** Unless this function is called explicitly, the transaction will not be
  127. * committed (actually the nontransaction implementation breaks this rule,
  128. * hence the name).
  129. *
  130. * Once this function returns, the whole transaction will typically be
  131. * irrevocably completed in the database. There is also, however, a minute
  132. * risk that the connection to the database may be lost at just the wrong
  133. * moment. In that case, libpqxx may be unable to determine whether the
  134. * transaction was completed or aborted and an in_doubt_error will be thrown
  135. * to make this fact known to the caller. The robusttransaction
  136. * implementation takes some special precautions to reduce this risk.
  137. */
  138. void commit(); //[t01]
  139. /// Abort the transaction
  140. /** No special effort is required to call this function; it will be called
  141. * implicitly when the transaction is destructed.
  142. */
  143. void abort(); //[t10]
  144. /**
  145. * @ingroup escaping-functions
  146. */
  147. //@{
  148. /// Escape string for use as SQL string literal in this transaction
  149. std::string esc(const char str[]) const { return conn().esc(str); }
  150. /// Escape string for use as SQL string literal in this transaction
  151. std::string esc(const char str[], size_t maxlen) const
  152. { return conn().esc(str, maxlen); }
  153. /// Escape string for use as SQL string literal in this transaction
  154. std::string esc(const std::string &str) const { return conn().esc(str); }
  155. /// Escape binary data for use as SQL string literal in this transaction
  156. /** Raw, binary data is treated differently from regular strings. Binary
  157. * strings are never interpreted as text, so they may safely include byte
  158. * values or byte sequences that don't happen to represent valid characters in
  159. * the character encoding being used.
  160. *
  161. * The binary string does not stop at the first zero byte, as is the case with
  162. * textual strings. Instead, they may contain zero bytes anywhere. If it
  163. * happens to contain bytes that look like quote characters, or other things
  164. * that can disrupt their use in SQL queries, they will be replaced with
  165. * special escape sequences.
  166. */
  167. std::string esc_raw(const unsigned char data[], size_t len) const //[t62]
  168. { return conn().esc_raw(data, len); }
  169. /// Escape binary data for use as SQL string literal in this transaction
  170. std::string esc_raw(const std::string &) const; //[t62]
  171. /// Unescape binary data, e.g. from a table field or notification payload.
  172. /** Takes a binary string as escaped by PostgreSQL, and returns a restored
  173. * copy of the original binary data.
  174. */
  175. std::string unesc_raw(const std::string &text) const
  176. { return conn().unesc_raw(text); }
  177. /// Unescape binary data, e.g. from a table field or notification payload.
  178. /** Takes a binary string as escaped by PostgreSQL, and returns a restored
  179. * copy of the original binary data.
  180. */
  181. std::string unesc_raw(const char *text) const
  182. { return conn().unesc_raw(text); }
  183. /// Represent object as SQL string, including quoting & escaping.
  184. /** Nulls are recognized and represented as SQL nulls. */
  185. template<typename T> std::string quote(const T &t) const
  186. { return conn().quote(t); }
  187. /// Binary-escape and quote a binarystring for use as an SQL constant.
  188. std::string quote_raw(const unsigned char str[], size_t len) const
  189. { return conn().quote_raw(str, len); }
  190. std::string quote_raw(const std::string &str) const;
  191. /// Escape an SQL identifier for use in a query.
  192. std::string quote_name(const std::string &identifier) const
  193. { return conn().quote_name(identifier); }
  194. /// Escape string for literal LIKE match.
  195. std::string esc_like(const std::string &str, char escape_char='\\') const
  196. { return conn().esc_like(str, escape_char); }
  197. //@}
  198. /// Execute query
  199. /** Perform a query in this transaction.
  200. *
  201. * This is one of the most important functions in libpqxx.
  202. *
  203. * Most libpqxx exceptions can be thrown from here, including sql_error,
  204. * broken_connection, and many sql_error subtypes such as
  205. * feature_not_supported or insufficient_privilege. But any exception thrown
  206. * by the C++ standard library may also occur here. All exceptions will be
  207. * derived from std::exception, however, and all libpqxx-specific exception
  208. * types are derived from pqxx::pqxx_exception.
  209. *
  210. * @param Query Query or command to execute
  211. * @param Desc Optional identifier for query, to help pinpoint SQL errors
  212. * @return A result set describing the query's or command's result
  213. */
  214. result exec(
  215. const std::string &Query,
  216. const std::string &Desc=std::string{}); //[t01]
  217. result exec(
  218. const std::stringstream &Query,
  219. const std::string &Desc=std::string{})
  220. { return exec(Query.str(), Desc); }
  221. /// Execute query, which should zero rows of data.
  222. /** Works like exec, but fails if the result contains data. It still returns
  223. * a result, however, which may contain useful metadata.
  224. *
  225. * @throw unexpected_rows If the query returned the wrong number of rows.
  226. */
  227. result exec0(
  228. const std::string &Query,
  229. const std::string &Desc=std::string{})
  230. { return exec_n(0, Query, Desc); }
  231. /// Execute query returning a single row of data.
  232. /** Works like exec, but requires the result to contain exactly one row.
  233. * The row can be addressed directly, without the need to find the first row
  234. * in a result set.
  235. *
  236. * @throw unexpected_rows If the query returned the wrong number of rows.
  237. */
  238. row exec1(const std::string &Query, const std::string &Desc=std::string{})
  239. { return exec_n(1, Query, Desc).front(); }
  240. /// Execute query, expect given number of rows.
  241. /** Works like exec, but checks that the number of rows is exactly what's
  242. * expected.
  243. *
  244. * @throw unexpected_rows If the query returned the wrong number of rows.
  245. */
  246. result exec_n(
  247. size_t rows,
  248. const std::string &Query,
  249. const std::string &Desc=std::string{});
  250. /**
  251. * @name Parameterized statements
  252. *
  253. * You'll often need parameters in the queries you execute: "select the
  254. * car with this licence plate." If the parameter is a string, you need to
  255. * quote it and escape any special characters inside it, or it may become a
  256. * target for an SQL injection attack. If it's an integer (for example),
  257. * you need to convert it to a string, but in the database's format, without
  258. * locale-specific niceties like "," separators between the thousands.
  259. *
  260. * Parameterised statements are an easier and safer way to do this. They're
  261. * like prepared statements, but for a single use. You don't need to name
  262. * them, and you don't need to prepare them first.
  263. *
  264. * Your query will include placeholders like @c $1 and $2 etc. in the places
  265. * where you want the arguments to go. Then, you pass the argument values
  266. * and the actual query is constructed for you.
  267. *
  268. * Pass the exact right number of parameters, and in the right order. The
  269. * parameters in the query don't have to be neatly ordered from @c $1 to
  270. * @c $2 to @c $3 - but you must pass the argument for @c $1 first, the one
  271. * for @c $2 second, etc.
  272. *
  273. * @warning Beware of "nul" bytes. Any string you pass as a parameter will
  274. * end at the first char with value zero. If you pass a @c std::string that
  275. * contains a zero byte, the last byte in the value will be the one just
  276. * before the zero.
  277. */
  278. //@{
  279. /// Execute an SQL statement with parameters.
  280. template<typename ...Args>
  281. result exec_params(const std::string &query, Args &&...args)
  282. {
  283. return internal_exec_params(
  284. query, internal::params(std::forward<Args>(args)...));
  285. }
  286. // Execute parameterised statement, expect a single-row result.
  287. /** @throw unexpected_rows if the result does not consist of exactly one row.
  288. */
  289. template<typename ...Args>
  290. row exec_params1(const std::string &query, Args&&... args)
  291. {
  292. return exec_params_n(1, query, std::forward<Args>(args)...).front();
  293. }
  294. // Execute parameterised statement, expect a result with zero rows.
  295. /** @throw unexpected_rows if the result contains rows.
  296. */
  297. template<typename ...Args>
  298. result exec_params0(const std::string &query, Args &&...args)
  299. {
  300. return exec_params_n(0, query, std::forward<Args>(args)...);
  301. }
  302. // Execute parameterised statement, expect exactly a given number of rows.
  303. /** @throw unexpected_rows if the result contains the wrong number of rows.
  304. */
  305. template<typename ...Args>
  306. result exec_params_n(size_t rows, const std::string &query, Args &&...args)
  307. {
  308. const auto r = exec_params(query, std::forward<Args>(args)...);
  309. check_rowcount_params(rows, r.size());
  310. return r;
  311. }
  312. /// Parameterize a statement. @deprecated Use @c exec_params instead.
  313. /* Use this to build up a parameterized statement invocation, then invoke it
  314. * using @c exec()
  315. *
  316. * Example: @c trans.parameterized("SELECT $1 + 1")(1).exec();
  317. *
  318. * This is the old, pre-C++11 way of handling parameterised statements. As
  319. * of libpqxx 6.0, it's made much easier using variadic templates.
  320. */
  321. PQXX_DEPRECATED internal::parameterized_invocation
  322. parameterized(const std::string &query);
  323. //@}
  324. /**
  325. * @name Prepared statements
  326. *
  327. * These are very similar to parameterised statements. The difference is
  328. * that you prepare them in advance, giving them identifying names. You can
  329. * then call them by these names, passing in the argument values appropriate
  330. * for that call.
  331. *
  332. * You prepare a statement on the connection, using
  333. * @c pqxx::connection_base::prepare(). But you then call the statement in a
  334. * transaction, using the functions you see here.
  335. *
  336. * Never try to prepare, execute, or unprepare a prepared statement manually
  337. * using direct SQL queries. Always use the functions provided by libpqxx.
  338. *
  339. * See \ref prepared for a full discussion.
  340. *
  341. * @warning Beware of "nul" bytes. Any string you pass as a parameter will
  342. * end at the first char with value zero. If you pass a @c std::string that
  343. * contains a zero byte, the last byte in the value will be the one just
  344. * before the zero. If you need a zero byte, consider using
  345. * pqxx::binarystring and/or SQL's @c bytea type.
  346. */
  347. //@{
  348. /// Execute a prepared statement, with optional arguments.
  349. template<typename ...Args>
  350. result exec_prepared(const std::string &statement, Args&&... args)
  351. {
  352. return internal_exec_prepared(
  353. statement, internal::params(std::forward<Args>(args)...), result_format::text);
  354. }
  355. /// Execute a prepared statement, with optional arguments.
  356. template<typename ...Args>
  357. result exec_prepared_binary(const std::string &statement, Args&&... args)
  358. {
  359. return internal_exec_prepared(
  360. statement, internal::params(std::forward<Args>(args)...), result_format::binary);
  361. }
  362. /// Execute a prepared statement, and expect a single-row result.
  363. /** @throw pqxx::unexpected_rows if the result was not exactly 1 row.
  364. */
  365. template<typename ...Args>
  366. row exec_prepared1(const std::string &statement, Args&&... args)
  367. {
  368. return exec_prepared_n(1, statement, std::forward<Args>(args)...).front();
  369. }
  370. /// Execute a prepared statement, and expect a result with zero rows.
  371. /** @throw pqxx::unexpected_rows if the result contained rows.
  372. */
  373. template<typename ...Args>
  374. result exec_prepared0(const std::string &statement, Args&&... args)
  375. {
  376. return exec_prepared_n(0, statement, std::forward<Args>(args)...);
  377. }
  378. /// Execute a prepared statement, expect a result with given number of rows.
  379. /** @throw pqxx::unexpected_rows if the result did not contain exactly the
  380. * given number of rows.
  381. */
  382. template<typename ...Args>
  383. result exec_prepared_n(
  384. size_t rows,
  385. const std::string &statement,
  386. Args&&... args)
  387. {
  388. const auto r = exec_prepared(statement, std::forward<Args>(args)...);
  389. check_rowcount_prepared(statement, rows, r.size());
  390. return r;
  391. }
  392. /// Execute prepared statement. @deprecated Use exec_prepared instead.
  393. /** Just like param_declaration is a helper class that lets you tag parameter
  394. * declarations onto the statement declaration, the invocation class returned
  395. * here lets you tag parameter values onto the call:
  396. *
  397. * @code
  398. * result run_mystatement(transaction_base &T)
  399. * {
  400. * return T.exec_prepared("mystatement", "param1", 2, nullptr, 4);
  401. * }
  402. * @endcode
  403. *
  404. * Here, parameter 1 (written as "<tt>$1</tt>" in the statement's body) is a
  405. * string that receives the value "param1"; the second parameter is an integer
  406. * with the value 2; the third receives a null, making its type irrelevant;
  407. * and number 4 again is an integer. The ultimate invocation of exec() is
  408. * essential; if you forget this, nothing happens.
  409. *
  410. * To see whether any prepared statement has been defined under a given name,
  411. * use:
  412. *
  413. * @code
  414. * T.prepared("mystatement").exists()
  415. * @endcode
  416. *
  417. * @warning Do not try to execute a prepared statement manually through direct
  418. * SQL statements. This is likely not to work, and even if it does, is likely
  419. * to be slower than using the proper libpqxx functions. Also, libpqxx knows
  420. * how to emulate prepared statements if some part of the infrastructure does
  421. * not support them.
  422. *
  423. * @warning Actual definition of the prepared statement on the backend may be
  424. * deferred until its first use, which means that any errors in the prepared
  425. * statement may not show up until it is executed--and perhaps abort the
  426. * ongoing transaction in the process.
  427. *
  428. * If you leave out the statement name, the call refers to the nameless
  429. * statement instead.
  430. */
  431. PQXX_DEPRECATED prepare::invocation
  432. prepared(const std::string &statement=std::string{});
  433. //@}
  434. /**
  435. * @name Error/warning output
  436. */
  437. //@{
  438. /// Have connection process warning message
  439. void process_notice(const char Msg[]) const //[t14]
  440. { m_conn.process_notice(Msg); }
  441. /// Have connection process warning message
  442. void process_notice(const std::string &Msg) const //[t14]
  443. { m_conn.process_notice(Msg); }
  444. //@}
  445. /// Connection this transaction is running in
  446. connection_base &conn() const { return m_conn; } //[t04]
  447. /// Set session variable in this connection
  448. /** The new value is typically forgotten if the transaction aborts.
  449. * However nontransaction is an exception to this rule: in that case the set
  450. * value will be kept regardless. Also, if the connection ever needs to be
  451. * recovered, a value you set in a nontransaction will not be restored.
  452. * @param Var The variable to set
  453. * @param Val The new value to store in the variable
  454. */
  455. void set_variable(const std::string &Var, const std::string &Val); //[t61]
  456. /// Get currently applicable value of variable
  457. /** First consults an internal cache of variables that have been set (whether
  458. * in the ongoing transaction or in the connection) using the set_variable
  459. * functions. If it is not found there, the database is queried.
  460. *
  461. * @warning Do not mix the set_variable with raw "SET" queries, and do not
  462. * try to set or get variables while a pipeline or table stream is active.
  463. *
  464. * @warning This function used to be declared as @c const but isn't anymore.
  465. */
  466. std::string get_variable(const std::string &); //[t61]
  467. protected:
  468. /// Create a transaction (to be called by implementation classes only)
  469. /** The optional name, if nonempty, must begin with a letter and may contain
  470. * letters and digits only.
  471. *
  472. * @param c The connection that this transaction is to act on.
  473. * @param direct Running directly in connection context (i.e. not nested)?
  474. */
  475. explicit transaction_base(connection_base &c, bool direct=true);
  476. /// Begin transaction (to be called by implementing class)
  477. /** Will typically be called from implementing class' constructor.
  478. */
  479. void Begin();
  480. /// End transaction. To be called by implementing class' destructor
  481. void End() noexcept;
  482. /// To be implemented by derived implementation class: start transaction
  483. virtual void do_begin() =0;
  484. /// To be implemented by derived implementation class: perform query
  485. virtual result do_exec(const char Query[]) =0;
  486. /// To be implemented by derived implementation class: commit transaction
  487. virtual void do_commit() =0;
  488. /// To be implemented by derived implementation class: abort transaction
  489. virtual void do_abort() =0;
  490. // For use by implementing class:
  491. /// Execute query on connection directly
  492. /**
  493. * @param C Query or command to execute
  494. * @param Retries Number of times to retry the query if it fails. Be
  495. * extremely careful with this option; if you retry in the middle of a
  496. * transaction, you may be setting up a new connection transparently and
  497. * executing the latter part of the transaction without a backend transaction
  498. * being active (and with the former part aborted).
  499. */
  500. result direct_exec(const char C[], int Retries=0);
  501. /// Forget about any reactivation-blocking resources we tried to allocate
  502. void reactivation_avoidance_clear() noexcept
  503. {m_reactivation_avoidance.clear();}
  504. protected:
  505. /// Resources allocated in this transaction that make reactivation impossible
  506. /** This number may be negative!
  507. */
  508. internal::reactivation_avoidance_counter m_reactivation_avoidance;
  509. private:
  510. /* A transaction goes through the following stages in its lifecycle:
  511. * <ul>
  512. * <li> nascent: the transaction hasn't actually begun yet. If our connection
  513. * fails at this stage, it may recover and the transaction can attempt to
  514. * establish itself again.
  515. * <li> active: the transaction has begun. Since no commit command has been
  516. * issued, abortion is implicit if the connection fails now.
  517. * <li> aborted: an abort has been issued; the transaction is terminated and
  518. * its changes to the database rolled back. It will accept no further
  519. * commands.
  520. * <li> committed: the transaction has completed successfully, meaning that a
  521. * commit has been issued. No further commands are accepted.
  522. * <li> in_doubt: the connection was lost at the exact wrong time, and there
  523. * is no way of telling whether the transaction was committed or aborted.
  524. * </ul>
  525. *
  526. * Checking and maintaining state machine logic is the responsibility of the
  527. * base class (ie., this one).
  528. */
  529. enum Status
  530. {
  531. st_nascent,
  532. st_active,
  533. st_aborted,
  534. st_committed,
  535. st_in_doubt
  536. };
  537. /// Make sure transaction is opened on backend, if appropriate
  538. PQXX_PRIVATE void activate();
  539. PQXX_PRIVATE void CheckPendingError();
  540. template<typename T> bool parm_is_null(T *p) const noexcept
  541. { return p == nullptr; }
  542. template<typename T> bool parm_is_null(T) const noexcept
  543. { return false; }
  544. result internal_exec_prepared(
  545. const std::string &statement,
  546. const internal::params &args,
  547. result_format format);
  548. result internal_exec_params(
  549. const std::string &query,
  550. const internal::params &args);
  551. /// Throw unexpected_rows if prepared statement returned wrong no. of rows.
  552. void check_rowcount_prepared(
  553. const std::string &statement,
  554. size_t expected_rows,
  555. size_t actual_rows);
  556. /// Throw unexpected_rows if wrong row count from parameterised statement.
  557. void check_rowcount_params(
  558. size_t expected_rows, size_t actual_rows);
  559. friend class pqxx::internal::gate::transaction_transactionfocus;
  560. PQXX_PRIVATE void register_focus(internal::transactionfocus *);
  561. PQXX_PRIVATE void unregister_focus(internal::transactionfocus *) noexcept;
  562. PQXX_PRIVATE void register_pending_error(const std::string &) noexcept;
  563. friend class pqxx::internal::gate::transaction_tablereader;
  564. friend class pqxx::internal::gate::transaction_stream_from;
  565. PQXX_PRIVATE void BeginCopyRead(const std::string &, const std::string &);
  566. bool read_copy_line(std::string &);
  567. friend class pqxx::internal::gate::transaction_tablewriter;
  568. friend class pqxx::internal::gate::transaction_stream_to;
  569. PQXX_PRIVATE void BeginCopyWrite(
  570. const std::string &Table,
  571. const std::string &Columns);
  572. void write_copy_line(const std::string &);
  573. void end_copy_write();
  574. friend class pqxx::internal::gate::transaction_subtransaction;
  575. connection_base &m_conn;
  576. internal::unique<internal::transactionfocus> m_focus;
  577. Status m_status = st_nascent;
  578. bool m_registered = false;
  579. std::map<std::string, std::string> m_vars;
  580. std::string m_pending_error;
  581. };
  582. } // namespace pqxx
  583. #include "pqxx/compiler-internal-post.hxx"
  584. #endif