From 80f791465219968e55a1867de8fb5b7d44a997c6 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Wed, 25 Dec 2024 23:24:52 +0100 Subject: [PATCH 01/17] Experimental log handler --- include/tao/pq/connection.hpp | 65 +++++++++++-- include/tao/pq/log.hpp | 100 ++++++++++++++++++++ src/lib/pq/connection.cpp | 138 +++++++++++++++------------ src/test/pq/log.cpp | 172 ++++++++++++++++++++++++++++++++++ 4 files changed, 409 insertions(+), 66 deletions(-) create mode 100644 include/tao/pq/log.hpp create mode 100644 src/test/pq/log.cpp diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 658e5b4..4bc17cb 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ namespace tao::pq std::function< poll::callback > m_poll; std::function< void( const notification& ) > m_notification_handler; std::map< std::string, std::function< void( const char* ) >, std::less<> > m_notification_handlers; + std::shared_ptr< log > m_log; [[nodiscard]] auto escape_identifier( const std::string_view identifier ) const -> std::unique_ptr< char, decltype( &PQfreemem ) >; @@ -122,19 +124,57 @@ namespace tao::pq [[nodiscard]] auto error_message() const -> const char*; - [[nodiscard]] auto poll_callback() const noexcept -> const std::function< poll::callback >&; - void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept; - void reset_poll_callback(); + [[nodiscard]] auto poll_callback() const noexcept -> decltype( auto ) + { + return m_poll; + } + + void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept + { + m_poll = std::move( poll_cb ); + } + + void reset_poll_callback() + { + m_poll = internal::poll; + } + + [[nodiscard]] auto notification_handler() const noexcept -> decltype( auto ) + { + return m_notification_handler; + } + + void set_notification_handler( std::function< void( const notification& ) > handler ) noexcept + { + m_notification_handler = std::move( handler ); + } + + void reset_notification_handler() noexcept + { + m_notification_handler = nullptr; + } - [[nodiscard]] auto notification_handler() const -> std::function< void( const notification& ) >; [[nodiscard]] auto notification_handler( const std::string_view channel ) const -> std::function< void( const char* payload ) >; - void set_notification_handler( const std::function< void( const notification& ) >& handler ); void set_notification_handler( const std::string_view channel, const std::function< void( const char* payload ) >& handler ); - void reset_notification_handler() noexcept; void reset_notification_handler( const std::string_view channel ) noexcept; + [[nodiscard]] auto log_handler() const noexcept -> decltype( auto ) + { + return m_log; + } + + void set_log_handler( const std::shared_ptr< pq::log >& log ) noexcept + { + m_log = log; + } + + void reset_log_handler() noexcept + { + m_log = nullptr; + } + [[nodiscard]] auto status() const noexcept -> connection_status; [[nodiscard]] auto transaction_status() const noexcept -> pq::transaction_status; @@ -156,6 +196,8 @@ namespace tao::pq [[nodiscard]] auto is_busy() const noexcept -> bool; + [[nodiscard]] auto flush() -> bool; + [[nodiscard]] auto direct() -> std::shared_ptr< pq::transaction >; [[nodiscard]] auto transaction() -> std::shared_ptr< pq::transaction >; @@ -190,8 +232,15 @@ namespace tao::pq return m_timeout; } - void set_timeout( const std::chrono::milliseconds timeout ); - void reset_timeout() noexcept; + void set_timeout( const std::chrono::milliseconds timeout ) noexcept + { + m_timeout = timeout; + } + + void reset_timeout() noexcept + { + m_timeout = std::nullopt; + } [[nodiscard]] auto password( const internal::zsv passwd, const internal::zsv user, const internal::zsv algorithm = "scram-sha-256" ) -> std::string; diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp new file mode 100644 index 0000000..5e3f4c9 --- /dev/null +++ b/include/tao/pq/log.hpp @@ -0,0 +1,100 @@ +// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#ifndef TAO_PQ_LOG_HPP +#define TAO_PQ_LOG_HPP + +#include +#include + +#include + +#include + +namespace tao::pq +{ + class connection; + + struct log + { + struct connection_pool_t + { + // TODO... + + } connection_pool; + + struct connection_t + { + using send_query_t = std::function< void( connection&, const char* statement, int n_params, const Oid types[], const char* const values[], const int lengths[], const int formats[] ) >; + using send_query_result_t = std::function< void( connection&, int result ) >; + + using send_query_prepared_t = std::function< void( connection&, const char* statement, int n_params, const char* const values[], const int lengths[], const int formats[] ) >; + using send_query_prepared_result_t = std::function< void( connection&, int result ) >; + + using wait_t = std::function< void( connection&, bool wait_for_write, std::chrono::steady_clock::time_point end ) >; + + using poll_t = std::function< void( connection&, int socket, bool wait_for_write, int timeout_ms ) >; + using poll_result_t = std::function< void( connection&, int socket, poll::status status ) >; + + using is_busy_result_t = std::function< void( const connection&, int result ) >; // noexcept + + using consume_input_t = std::function< void( connection& ) >; + using consume_input_result_t = std::function< void( connection&, int result ) >; + + using flush_t = std::function< void( connection& ) >; + using flush_result_t = std::function< void( connection&, int result ) >; + + using get_result_t = std::function< void( connection&, std::chrono::steady_clock::time_point end ) >; + + struct : send_query_t + { + send_query_result_t result; + using send_query_t::operator=; + } send_query; + + struct : send_query_prepared_t + { + send_query_prepared_result_t result; + using send_query_prepared_t::operator=; + } send_query_prepared; + + wait_t wait; + + struct : poll_t + { + poll_result_t result; + using poll_t::operator=; + } poll; + + struct + { + is_busy_result_t result; + } is_busy; + + struct : consume_input_t + { + consume_input_result_t result; + using consume_input_t::operator=; + } consume_input; + + struct : flush_t + { + flush_result_t result; + using flush_t::operator=; + } flush; + + get_result_t get_result; + + } connection; + + struct transaction_t + { + // TODO... + + } transaction; + }; + +} // namespace tao::pq + +#endif diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index 98946a0..92530d5 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -224,9 +224,34 @@ namespace tao::pq const int lengths[], const int formats[] ) { - const auto result = m_prepared_statements.contains( statement ) ? + const auto is_prepared = m_prepared_statements.contains( statement ); + if( m_log ) { + if( is_prepared ) { + if( m_log->connection.send_query_prepared ) { + m_log->connection.send_query_prepared( *this, statement, n_params, values, lengths, formats ); + } + } + else { + if( m_log->connection.send_query ) { + m_log->connection.send_query( *this, statement, n_params, types, values, lengths, formats ); + } + } + } + const auto result = is_prepared ? PQsendQueryPrepared( m_pgconn.get(), statement, n_params, values, lengths, formats, 0 ) : PQsendQueryParams( m_pgconn.get(), statement, n_params, types, values, lengths, formats, 0 ); + if( m_log ) { + if( is_prepared ) { + if( m_log->connection.send_query_prepared.result ) { + m_log->connection.send_query_prepared.result( *this, result ); + } + } + else { + if( m_log->connection.send_query.result ) { + m_log->connection.send_query.result( *this, result ); + } + } + } if( result == 0 ) { throw pq::connection_error( error_message() ); // LCOV_EXCL_LINE } @@ -234,13 +259,24 @@ namespace tao::pq void connection::wait( const bool wait_for_write, const std::chrono::steady_clock::time_point end ) { + if( m_log && m_log->connection.wait ) { + m_log->connection.wait( *this, wait_for_write, end ); + } while( true ) { int timeout_ms = -1; if( m_timeout ) { timeout_ms = std::max( static_cast< int >( std::chrono::duration_cast< std::chrono::milliseconds >( end - std::chrono::steady_clock::now() ).count() ), 0 ); } - switch( m_poll( socket(), wait_for_write, timeout_ms ) ) { + const auto so = socket(); + if( m_log && m_log->connection.poll ) { + m_log->connection.poll( *this, so, wait_for_write, timeout_ms ); + } + const auto status = m_poll( so, wait_for_write, timeout_ms ); + if( m_log && m_log->connection.poll.result ) { + m_log->connection.poll.result( *this, so, status ); + } + switch( status ) { case poll::status::timeout: m_pgconn.reset(); throw timeout_reached( "timeout reached" ); @@ -276,22 +312,13 @@ namespace tao::pq auto connection::get_result( const std::chrono::steady_clock::time_point end ) -> std::unique_ptr< PGresult, decltype( &PQclear ) > { + if( m_log && m_log->connection.get_result ) { + m_log->connection.get_result( *this, end ); + } bool wait_for_write = true; while( is_busy() ) { if( wait_for_write ) { - switch( PQflush( m_pgconn.get() ) ) { - case 0: - wait_for_write = false; - break; - - // LCOV_EXCL_START - case 1: - break; - - default: - throw pq::error( std::format( "PQflush() failed: {}", error_message() ) ); - // LCOV_EXCL_STOP - } + wait_for_write = flush(); } connection::wait( wait_for_write, end ); } @@ -435,26 +462,6 @@ namespace tao::pq return PQerrorMessage( m_pgconn.get() ); } - auto connection::poll_callback() const noexcept -> const std::function< poll::callback >& - { - return m_poll; - } - - void connection::set_poll_callback( std::function< poll::callback > poll_cb ) noexcept - { - m_poll = std::move( poll_cb ); - } - - void connection::reset_poll_callback() - { - m_poll = internal::poll; - } - - auto connection::notification_handler() const -> std::function< void( const notification& ) > - { - return m_notification_handler; - } - auto connection::notification_handler( const std::string_view channel ) const -> std::function< void( const char* payload ) > { const auto it = m_notification_handlers.find( channel ); @@ -464,24 +471,17 @@ namespace tao::pq return {}; } - void connection::set_notification_handler( const std::function< void( const notification& ) >& handler ) - { - m_notification_handler = handler; - } - void connection::set_notification_handler( const std::string_view channel, const std::function< void( const char* payload ) >& handler ) { m_notification_handlers[ std::string( channel ) ] = handler; } - void connection::reset_notification_handler() noexcept - { - m_notification_handler = nullptr; - } - void connection::reset_notification_handler( const std::string_view channel ) noexcept { - m_notification_handlers.erase( std::string( channel ) ); + const auto it = m_notification_handlers.find( channel ); + if( it != m_notification_handlers.end() ) { + m_notification_handlers.erase( it ); + } } auto connection::status() const noexcept -> connection_status @@ -522,7 +522,32 @@ namespace tao::pq auto connection::is_busy() const noexcept -> bool { - return PQisBusy( m_pgconn.get() ) != 0; + const auto result = PQisBusy( m_pgconn.get() ); + if( m_log && m_log->connection.is_busy.result ) { + m_log->connection.is_busy.result( *this, result ); + } + return result != 0; + } + + auto connection::flush() -> bool + { + if( m_log && m_log->connection.flush ) { + m_log->connection.flush( *this ); + } + const auto result = PQflush( m_pgconn.get() ); + if( m_log && m_log->connection.flush.result ) { + m_log->connection.flush.result( *this, result ); + } + switch( result ) { + case 0: + return false; + + case 1: + return true; + + default: + throw pq::error( std::format( "PQflush() failed: {}", error_message() ) ); + } } auto connection::direct() -> std::shared_ptr< pq::transaction > @@ -632,7 +657,14 @@ namespace tao::pq void connection::get_notifications() { - if( PQconsumeInput( m_pgconn.get() ) == 0 ) { + if( m_log && m_log->connection.consume_input ) { + m_log->connection.consume_input( *this ); + } + const auto result = PQconsumeInput( m_pgconn.get() ); + if( m_log && m_log->connection.consume_input.result ) { + m_log->connection.consume_input.result( *this, result ); + } + if( result == 0 ) { throw pq::connection_error( error_message() ); } handle_notifications(); @@ -647,16 +679,6 @@ namespace tao::pq return fd; } - void connection::set_timeout( const std::chrono::milliseconds timeout ) - { - m_timeout = timeout; - } - - void connection::reset_timeout() noexcept - { - m_timeout = std::nullopt; - } - auto connection::password( const internal::zsv passwd, const internal::zsv user, const internal::zsv algorithm ) -> std::string { const std::unique_ptr< char, decltype( &PQfreemem ) > buffer( PQencryptPasswordConn( m_pgconn.get(), passwd, user, algorithm ), &PQfreemem ); diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp new file mode 100644 index 0000000..584955e --- /dev/null +++ b/src/test/pq/log.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#include "../getenv.hpp" +#include "../macros.hpp" + +#include +#include +#include +#include +#include + +#include + +namespace +{ + template< typename E > + [[nodiscard]] constexpr auto to_underlying( const E e ) noexcept + { + return static_cast< std::underlying_type_t< E > >( e ); + } + + [[nodiscard]] auto to_millis( std::chrono::steady_clock::time_point end ) noexcept + { + return std::chrono::duration_cast< std::chrono::milliseconds >( end - std::chrono::steady_clock::now() ).count(); + } + + void log_send_query( tao::pq::connection& c, const char* s, int n, const Oid types[], const char* const values[], const int lengths[], const int formats[] ) + { + std::ignore = types; + std::ignore = lengths; + std::ignore = formats; + std::cout << std::format( "send_query(connection={}, statement={}, n_params={})", (void*)( &c ), s, n ) << '\n'; + for( int i = 0; i != n; ++i ) { + std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; + } + } + + void log_send_query_result( tao::pq::connection& c, int r ) + { + std::cout << std::format( "send_query(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + } + + void log_send_query_prepared( tao::pq::connection& c, const char* s, int n, const char* const values[], const int lengths[], const int formats[] ) + { + std::ignore = lengths; + std::ignore = formats; + std::cout << std::format( "send_query_prepared(connection={}, statement={}, n_params={})", (void*)( &c ), s, n ) << '\n'; + for( int i = 0; i != n; ++i ) { + std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; + } + } + + void log_send_query_prepared_result( tao::pq::connection& c, int r ) + { + std::cout << std::format( "send_query_prepared(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + } + + void log_wait( tao::pq::connection& c, bool w, std::chrono::steady_clock::time_point e ) + { + std::cout << std::format( "wait(connection={}, wait_for_write={}, timeout={}ms)", (void*)( &c ), w, to_millis( e ) ) << '\n'; + } + + void log_poll( tao::pq::connection& c, int s, bool w, int t ) + { + std::cout << std::format( "poll(connection={},socket={}, wait_for_write={}, timeout={}ms)", (void*)( &c ), s, w, t ) << '\n'; + } + + void log_poll_result( tao::pq::connection& c, int s, tao::pq::poll::status r ) + { + std::cout << std::format( "poll(connection={},socket={}) -> {}", (void*)( &c ), s, to_underlying( r ) ) << '\n'; + } + + void log_is_busy_result( const tao::pq::connection& c, int r ) + { + std::cout << std::format( "is_busy(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + } + + void log_consume_input( tao::pq::connection& c ) + { + std::cout << std::format( "consume_input(connection={})", (void*)( &c ) ) << '\n'; + } + + void log_consume_input_result( tao::pq::connection& c, int r ) + { + std::cout << std::format( "consume_input(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + } + + void log_flush( tao::pq::connection& c ) + { + std::cout << std::format( "flush(connection={})", (void*)( &c ) ) << '\n'; + } + + void log_flush_result( tao::pq::connection& c, int r ) + { + std::cout << std::format( "flush(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + } + + void run() + { + // overwrite the default with an environment variable if needed + const auto connection_string = tao::pq::internal::getenv( "TAOPQ_TEST_DATABASE", "dbname=template1" ); + + // open a connection to the database + const auto conn = tao::pq::connection::create( connection_string ); + + // attach a log receiver + const auto log = std::make_shared< tao::pq::log >(); + + log->connection.send_query = log_send_query; + log->connection.send_query.result = log_send_query_result; + log->connection.send_query_prepared = log_send_query_prepared; + log->connection.send_query_prepared.result = log_send_query_prepared_result; + log->connection.wait = log_wait; + log->connection.poll = log_poll; + log->connection.poll.result = log_poll_result; + log->connection.is_busy.result = log_is_busy_result; + log->connection.consume_input = log_consume_input; + log->connection.consume_input.result = log_consume_input_result; + log->connection.flush = log_flush; + log->connection.flush.result = log_flush_result; + conn->set_log_handler( log ); + + // execute statements + conn->execute( "DROP TABLE IF EXISTS tao_example" ); + conn->execute( "CREATE TABLE tao_example ( name TEXT PRIMARY KEY, age INTEGER NOT NULL )" ); + + // prepare statements + conn->prepare( "insert_user", "INSERT INTO tao_example ( name, age ) VALUES ( $1, $2 )" ); + + { + // begin transaction + const auto tr = conn->transaction(); + + // execute previously prepared statements + tr->execute( "insert_user", "Daniel", 42 ); + tr->execute( "insert_user", "Tom", 41 ); + tr->execute( "insert_user", "Jerry", 29 ); + + // commit transaction + tr->commit(); + } + + // query data + const auto users = conn->execute( "SELECT name, age FROM tao_example WHERE age >= $1", 40 ); + + // iterate and convert results + for( const auto& row : users ) { + std::cout << row[ "name" ].as< std::string >() << " is " + << row[ "age" ].as< unsigned >() << " years old.\n"; + } + } + +} // namespace + +auto main() -> int +{ + try { + run(); + } + // LCOV_EXCL_START + catch( const std::exception& e ) { + std::cerr << "exception: " << e.what() << '\n'; + throw; + } + catch( ... ) { + std::cerr << "unknown exception\n"; + throw; + } + // LCOV_EXCL_STOP +} From 19fcf5c858fe2457a4837943e0dc1e422bad1b91 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Wed, 25 Dec 2024 23:32:14 +0100 Subject: [PATCH 02/17] Cleanup --- CMakeLists.txt | 1 + include/tao/pq.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08e3ef9..49505c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set(taopq_INCLUDE_FILES ${taopq_INCLUDE_DIRS}/tao/pq/is_array.hpp ${taopq_INCLUDE_DIRS}/tao/pq/isolation_level.hpp ${taopq_INCLUDE_DIRS}/tao/pq/large_object.hpp + ${taopq_INCLUDE_DIRS}/tao/pq/log.hpp ${taopq_INCLUDE_DIRS}/tao/pq/notification.hpp ${taopq_INCLUDE_DIRS}/tao/pq/null.hpp ${taopq_INCLUDE_DIRS}/tao/pq/oid.hpp diff --git a/include/tao/pq.hpp b/include/tao/pq.hpp index 4172345..53680d8 100644 --- a/include/tao/pq.hpp +++ b/include/tao/pq.hpp @@ -27,6 +27,7 @@ #include #include +#include #include #include From 65b30dbd74a4c16ddb56b66f974da4a667467809 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 12:19:43 +0100 Subject: [PATCH 03/17] Fix casts --- src/test/pq/log.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index 584955e..beb915b 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -31,7 +31,7 @@ namespace std::ignore = types; std::ignore = lengths; std::ignore = formats; - std::cout << std::format( "send_query(connection={}, statement={}, n_params={})", (void*)( &c ), s, n ) << '\n'; + std::cout << std::format( "send_query(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; for( int i = 0; i != n; ++i ) { std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; } @@ -39,14 +39,14 @@ namespace void log_send_query_result( tao::pq::connection& c, int r ) { - std::cout << std::format( "send_query(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + std::cout << std::format( "send_query(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } void log_send_query_prepared( tao::pq::connection& c, const char* s, int n, const char* const values[], const int lengths[], const int formats[] ) { std::ignore = lengths; std::ignore = formats; - std::cout << std::format( "send_query_prepared(connection={}, statement={}, n_params={})", (void*)( &c ), s, n ) << '\n'; + std::cout << std::format( "send_query_prepared(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; for( int i = 0; i != n; ++i ) { std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; } @@ -54,47 +54,47 @@ namespace void log_send_query_prepared_result( tao::pq::connection& c, int r ) { - std::cout << std::format( "send_query_prepared(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + std::cout << std::format( "send_query_prepared(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } void log_wait( tao::pq::connection& c, bool w, std::chrono::steady_clock::time_point e ) { - std::cout << std::format( "wait(connection={}, wait_for_write={}, timeout={}ms)", (void*)( &c ), w, to_millis( e ) ) << '\n'; + std::cout << std::format( "wait(connection={}, wait_for_write={}, timeout={}ms)", static_cast< const void* >( &c ), w, to_millis( e ) ) << '\n'; } void log_poll( tao::pq::connection& c, int s, bool w, int t ) { - std::cout << std::format( "poll(connection={},socket={}, wait_for_write={}, timeout={}ms)", (void*)( &c ), s, w, t ) << '\n'; + std::cout << std::format( "poll(connection={},socket={}, wait_for_write={}, timeout={}ms)", static_cast< const void* >( &c ), s, w, t ) << '\n'; } void log_poll_result( tao::pq::connection& c, int s, tao::pq::poll::status r ) { - std::cout << std::format( "poll(connection={},socket={}) -> {}", (void*)( &c ), s, to_underlying( r ) ) << '\n'; + std::cout << std::format( "poll(connection={},socket={}) -> {}", static_cast< const void* >( &c ), s, to_underlying( r ) ) << '\n'; } void log_is_busy_result( const tao::pq::connection& c, int r ) { - std::cout << std::format( "is_busy(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + std::cout << std::format( "is_busy(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } void log_consume_input( tao::pq::connection& c ) { - std::cout << std::format( "consume_input(connection={})", (void*)( &c ) ) << '\n'; + std::cout << std::format( "consume_input(connection={})", static_cast< const void* >( &c ) ) << '\n'; } void log_consume_input_result( tao::pq::connection& c, int r ) { - std::cout << std::format( "consume_input(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + std::cout << std::format( "consume_input(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } void log_flush( tao::pq::connection& c ) { - std::cout << std::format( "flush(connection={})", (void*)( &c ) ) << '\n'; + std::cout << std::format( "flush(connection={})", static_cast< const void* >( &c ) ) << '\n'; } void log_flush_result( tao::pq::connection& c, int r ) { - std::cout << std::format( "flush(connection={}) -> {}", (void*)( &c ), r ) << '\n'; + std::cout << std::format( "flush(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } void run() From 930fb7c9a732e0a5e3ec6c9ececf9e36fbf5ddaa Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 15:08:07 +0100 Subject: [PATCH 04/17] Format support for tao::pq::poll::status --- CMakeLists.txt | 1 + include/tao/pq/internal/format_as.hpp | 21 +++++++++++++++++++++ include/tao/pq/poll.hpp | 23 +++++++++++++++++++++++ src/test/pq/log.cpp | 8 +------- 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 include/tao/pq/internal/format_as.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 49505c7..af0a34b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ set(taopq_INCLUDE_FILES ${taopq_INCLUDE_DIRS}/tao/pq/internal/aggregate.hpp ${taopq_INCLUDE_DIRS}/tao/pq/internal/demangle.hpp ${taopq_INCLUDE_DIRS}/tao/pq/internal/exclusive_scan.hpp + ${taopq_INCLUDE_DIRS}/tao/pq/internal/format_as.hpp ${taopq_INCLUDE_DIRS}/tao/pq/internal/from_chars.hpp ${taopq_INCLUDE_DIRS}/tao/pq/internal/gen.hpp ${taopq_INCLUDE_DIRS}/tao/pq/internal/parameter_traits_helper.hpp diff --git a/include/tao/pq/internal/format_as.hpp b/include/tao/pq/internal/format_as.hpp new file mode 100644 index 0000000..892c49c --- /dev/null +++ b/include/tao/pq/internal/format_as.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +#ifndef TAO_PQ_INTERNAL_FORMAT_AS_HPP +#define TAO_PQ_INTERNAL_FORMAT_AS_HPP + +#include +#include + +template< typename T > + requires requires { taopq_format_as( std::declval< T >() ); } +struct std::formatter< T > : std::formatter< decltype( taopq_format_as( std::declval< T >() ) ) > +{ + auto format( const T& v, auto& ctx ) const + { + return std::formatter< decltype( taopq_format_as( v ) ) >::format( taopq_format_as( v ), ctx ); + } +}; + +#endif diff --git a/include/tao/pq/poll.hpp b/include/tao/pq/poll.hpp index 31b6dc5..f8c92fa 100644 --- a/include/tao/pq/poll.hpp +++ b/include/tao/pq/poll.hpp @@ -6,6 +6,9 @@ #define TAO_PQ_POLL_HPP #include +#include + +#include namespace tao::pq::poll { @@ -17,6 +20,26 @@ namespace tao::pq::poll again }; + [[nodiscard]] constexpr auto taopq_format_as( const status st ) noexcept -> std::string_view + { + switch( st ) { + case status::timeout: + return "timeout"; + + case status::readable: + return "readable"; + + case status::writable: + return "writable"; + + case status::again: + return "again"; + + default: + return "unknown"; + } + } + using callback = status( const int socket, const bool wait_for_write, const int timeout_ms ); } // namespace tao::pq::poll diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index beb915b..518735c 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -15,12 +15,6 @@ namespace { - template< typename E > - [[nodiscard]] constexpr auto to_underlying( const E e ) noexcept - { - return static_cast< std::underlying_type_t< E > >( e ); - } - [[nodiscard]] auto to_millis( std::chrono::steady_clock::time_point end ) noexcept { return std::chrono::duration_cast< std::chrono::milliseconds >( end - std::chrono::steady_clock::now() ).count(); @@ -69,7 +63,7 @@ namespace void log_poll_result( tao::pq::connection& c, int s, tao::pq::poll::status r ) { - std::cout << std::format( "poll(connection={},socket={}) -> {}", static_cast< const void* >( &c ), s, to_underlying( r ) ) << '\n'; + std::cout << std::format( "poll(connection={},socket={}) -> {}", static_cast< const void* >( &c ), s, r ) << '\n'; } void log_is_busy_result( const tao::pq::connection& c, int r ) From 12bb0d2d3aafa3783de7d0da0e270106a899c597 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 15:56:40 +0100 Subject: [PATCH 05/17] Format support for other enums --- include/tao/pq/access_mode.hpp | 20 +++++++++++ include/tao/pq/connection_status.hpp | 17 ++++++++++ include/tao/pq/isolation_level.hpp | 26 ++++++++++++++ include/tao/pq/pipeline_status.hpp | 20 +++++++++++ include/tao/pq/poll.hpp | 4 +-- include/tao/pq/result_status.hpp | 49 +++++++++++++++++++++++++++ include/tao/pq/transaction_status.hpp | 26 ++++++++++++++ 7 files changed, 160 insertions(+), 2 deletions(-) diff --git a/include/tao/pq/access_mode.hpp b/include/tao/pq/access_mode.hpp index 6280816..aed7f0e 100644 --- a/include/tao/pq/access_mode.hpp +++ b/include/tao/pq/access_mode.hpp @@ -6,6 +6,9 @@ #define TAO_PQ_ACCESS_MODE_HPP #include +#include + +#include namespace tao::pq { @@ -16,6 +19,23 @@ namespace tao::pq read_only }; + [[nodiscard]] inline constexpr auto taopq_format_as( const access_mode am ) noexcept -> std::string_view + { + switch( am ) { + case access_mode::default_access_mode: + return "default_access_mode"; + + case access_mode::read_write: + return "read_write"; + + case access_mode::read_only: + return "read_only"; + + default: + return ""; + } + } + } // namespace tao::pq #endif diff --git a/include/tao/pq/connection_status.hpp b/include/tao/pq/connection_status.hpp index 933358f..64324e3 100644 --- a/include/tao/pq/connection_status.hpp +++ b/include/tao/pq/connection_status.hpp @@ -6,9 +6,12 @@ #define TAO_PQ_CONNECTION_STATUS_HPP #include +#include #include +#include + namespace tao::pq { enum class connection_status : std::uint8_t @@ -17,6 +20,20 @@ namespace tao::pq bad = CONNECTION_BAD }; + [[nodiscard]] inline constexpr auto taopq_format_as( const connection_status cs ) noexcept -> std::string_view + { + switch( cs ) { + case connection_status::ok: + return "ok"; + + case connection_status::bad: + return "bad"; + + default: + return ""; + } + } + } // namespace tao::pq #endif diff --git a/include/tao/pq/isolation_level.hpp b/include/tao/pq/isolation_level.hpp index e1228f5..8d41b9d 100644 --- a/include/tao/pq/isolation_level.hpp +++ b/include/tao/pq/isolation_level.hpp @@ -6,6 +6,9 @@ #define TAO_PQ_ISOLATION_LEVEL_HPP #include +#include + +#include namespace tao::pq { @@ -18,6 +21,29 @@ namespace tao::pq read_uncommitted }; + [[nodiscard]] inline constexpr auto taopq_format_as( const isolation_level il ) noexcept -> std::string_view + { + switch( il ) { + case isolation_level::default_isolation_level: + return "default_isolation_level"; + + case isolation_level::serializable: + return "serializable"; + + case isolation_level::repeatable_read: + return "repeatable_read"; + + case isolation_level::read_committed: + return "read_committed"; + + case isolation_level::read_uncommitted: + return "read_uncommitted"; + + default: + return ""; + } + } + } // namespace tao::pq #endif diff --git a/include/tao/pq/pipeline_status.hpp b/include/tao/pq/pipeline_status.hpp index 0c5e796..b5c7181 100644 --- a/include/tao/pq/pipeline_status.hpp +++ b/include/tao/pq/pipeline_status.hpp @@ -6,9 +6,12 @@ #define TAO_PQ_PIPELINE_STATUS_HPP #include +#include #include +#include + namespace tao::pq { enum class pipeline_status : std::uint8_t @@ -18,6 +21,23 @@ namespace tao::pq aborted = PQ_PIPELINE_ABORTED }; + [[nodiscard]] inline constexpr auto taopq_format_as( const pipeline_status ps ) noexcept -> std::string_view + { + switch( ps ) { + case pipeline_status::on: + return "on"; + + case pipeline_status::off: + return "off"; + + case pipeline_status::aborted: + return "aborted"; + + default: + return ""; + } + } + } // namespace tao::pq #endif diff --git a/include/tao/pq/poll.hpp b/include/tao/pq/poll.hpp index f8c92fa..7f102da 100644 --- a/include/tao/pq/poll.hpp +++ b/include/tao/pq/poll.hpp @@ -20,7 +20,7 @@ namespace tao::pq::poll again }; - [[nodiscard]] constexpr auto taopq_format_as( const status st ) noexcept -> std::string_view + [[nodiscard]] inline constexpr auto taopq_format_as( const status st ) noexcept -> std::string_view { switch( st ) { case status::timeout: @@ -36,7 +36,7 @@ namespace tao::pq::poll return "again"; default: - return "unknown"; + return ""; } } diff --git a/include/tao/pq/result_status.hpp b/include/tao/pq/result_status.hpp index 5d43cf8..b45e37e 100644 --- a/include/tao/pq/result_status.hpp +++ b/include/tao/pq/result_status.hpp @@ -6,9 +6,12 @@ #define TAO_PQ_RESULT_STATUS_HPP #include +#include #include +#include + namespace tao::pq { enum class result_status : std::uint8_t @@ -29,6 +32,52 @@ namespace tao::pq pipeline_aborted = PGRES_PIPELINE_ABORTED }; + [[nodiscard]] inline constexpr auto taopq_format_as( const result_status rs ) noexcept -> std::string_view + { + switch( rs ) { + case result_status::empty_query: + return "empty_query"; + + case result_status::command_ok: + return "command_ok"; + + case result_status::tuples_ok: + return "tuples_ok"; + + case result_status::copy_out: + return "copy_out"; + + case result_status::copy_in: + return "copy_in"; + + case result_status::bad_response: + return "bad_response"; + + case result_status::nonfatal_error: + return "nonfatal_error"; + + case result_status::fatal_error: + return "fatal_error"; + + case result_status::single_tuple: + return "single_tuple"; + +#if defined( LIBPQ_HAS_CHUNK_MODE ) + case result_status::tuples_chunk: + return "tuples_chunk"; +#endif + + case result_status::pipeline_sync: + return "pipeline_sync"; + + case result_status::pipeline_aborted: + return "pipeline_aborted"; + + default: + return ""; + } + } + } // namespace tao::pq #endif diff --git a/include/tao/pq/transaction_status.hpp b/include/tao/pq/transaction_status.hpp index dc5d765..0219f7f 100644 --- a/include/tao/pq/transaction_status.hpp +++ b/include/tao/pq/transaction_status.hpp @@ -6,9 +6,12 @@ #define TAO_PQ_TRANSACTION_STATUS_HPP #include +#include #include +#include + namespace tao::pq { enum class transaction_status : std::uint8_t @@ -20,6 +23,29 @@ namespace tao::pq unknown = PQTRANS_UNKNOWN }; + [[nodiscard]] inline constexpr auto taopq_format_as( const transaction_status ts ) noexcept -> std::string_view + { + switch( ts ) { + case transaction_status::idle: + return "idle"; + + case transaction_status::in_transaction: + return "in_transaction"; + + case transaction_status::active: + return "active"; + + case transaction_status::error: + return "error"; + + case transaction_status::unknown: + return "unknown"; + + default: + return ""; + } + } + } // namespace tao::pq #endif From d4d7484e82785651dbd9505957c7327dde2fc6b2 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 16:22:34 +0100 Subject: [PATCH 06/17] Remove redundant inline --- include/tao/pq/access_mode.hpp | 2 +- include/tao/pq/connection_status.hpp | 2 +- include/tao/pq/isolation_level.hpp | 2 +- include/tao/pq/pipeline_status.hpp | 2 +- include/tao/pq/poll.hpp | 2 +- include/tao/pq/result_status.hpp | 2 +- include/tao/pq/transaction_status.hpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/tao/pq/access_mode.hpp b/include/tao/pq/access_mode.hpp index aed7f0e..9feb5eb 100644 --- a/include/tao/pq/access_mode.hpp +++ b/include/tao/pq/access_mode.hpp @@ -19,7 +19,7 @@ namespace tao::pq read_only }; - [[nodiscard]] inline constexpr auto taopq_format_as( const access_mode am ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const access_mode am ) noexcept -> std::string_view { switch( am ) { case access_mode::default_access_mode: diff --git a/include/tao/pq/connection_status.hpp b/include/tao/pq/connection_status.hpp index 64324e3..1c01530 100644 --- a/include/tao/pq/connection_status.hpp +++ b/include/tao/pq/connection_status.hpp @@ -20,7 +20,7 @@ namespace tao::pq bad = CONNECTION_BAD }; - [[nodiscard]] inline constexpr auto taopq_format_as( const connection_status cs ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const connection_status cs ) noexcept -> std::string_view { switch( cs ) { case connection_status::ok: diff --git a/include/tao/pq/isolation_level.hpp b/include/tao/pq/isolation_level.hpp index 8d41b9d..225e427 100644 --- a/include/tao/pq/isolation_level.hpp +++ b/include/tao/pq/isolation_level.hpp @@ -21,7 +21,7 @@ namespace tao::pq read_uncommitted }; - [[nodiscard]] inline constexpr auto taopq_format_as( const isolation_level il ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const isolation_level il ) noexcept -> std::string_view { switch( il ) { case isolation_level::default_isolation_level: diff --git a/include/tao/pq/pipeline_status.hpp b/include/tao/pq/pipeline_status.hpp index b5c7181..c52c9db 100644 --- a/include/tao/pq/pipeline_status.hpp +++ b/include/tao/pq/pipeline_status.hpp @@ -21,7 +21,7 @@ namespace tao::pq aborted = PQ_PIPELINE_ABORTED }; - [[nodiscard]] inline constexpr auto taopq_format_as( const pipeline_status ps ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const pipeline_status ps ) noexcept -> std::string_view { switch( ps ) { case pipeline_status::on: diff --git a/include/tao/pq/poll.hpp b/include/tao/pq/poll.hpp index 7f102da..1c09999 100644 --- a/include/tao/pq/poll.hpp +++ b/include/tao/pq/poll.hpp @@ -20,7 +20,7 @@ namespace tao::pq::poll again }; - [[nodiscard]] inline constexpr auto taopq_format_as( const status st ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const status st ) noexcept -> std::string_view { switch( st ) { case status::timeout: diff --git a/include/tao/pq/result_status.hpp b/include/tao/pq/result_status.hpp index b45e37e..a8ad979 100644 --- a/include/tao/pq/result_status.hpp +++ b/include/tao/pq/result_status.hpp @@ -32,7 +32,7 @@ namespace tao::pq pipeline_aborted = PGRES_PIPELINE_ABORTED }; - [[nodiscard]] inline constexpr auto taopq_format_as( const result_status rs ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const result_status rs ) noexcept -> std::string_view { switch( rs ) { case result_status::empty_query: diff --git a/include/tao/pq/transaction_status.hpp b/include/tao/pq/transaction_status.hpp index 0219f7f..805173d 100644 --- a/include/tao/pq/transaction_status.hpp +++ b/include/tao/pq/transaction_status.hpp @@ -23,7 +23,7 @@ namespace tao::pq unknown = PQTRANS_UNKNOWN }; - [[nodiscard]] inline constexpr auto taopq_format_as( const transaction_status ts ) noexcept -> std::string_view + [[nodiscard]] constexpr auto taopq_format_as( const transaction_status ts ) noexcept -> std::string_view { switch( ts ) { case transaction_status::idle: From 7d2321663f90211862b0998a1c3344bddd95a7c7 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 16:32:17 +0100 Subject: [PATCH 07/17] Add ostream support --- include/tao/pq/internal/format_as.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/tao/pq/internal/format_as.hpp b/include/tao/pq/internal/format_as.hpp index 892c49c..184e39a 100644 --- a/include/tao/pq/internal/format_as.hpp +++ b/include/tao/pq/internal/format_as.hpp @@ -6,6 +6,7 @@ #define TAO_PQ_INTERNAL_FORMAT_AS_HPP #include +#include #include template< typename T > @@ -18,4 +19,11 @@ struct std::formatter< T > : std::formatter< decltype( taopq_format_as( std::dec } }; +template< typename T > + requires requires { taopq_format_as( std::declval< T >() ); } +std::ostream& operator<<( std::ostream& os, const T& v ) +{ + return os << taopq_format_as( v ); +} + #endif From 5f263c38ff25f9804eb3a82a5a66adb35564300a Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 17:21:14 +0100 Subject: [PATCH 08/17] clang-tidy --- include/tao/pq/internal/format_as.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/tao/pq/internal/format_as.hpp b/include/tao/pq/internal/format_as.hpp index 184e39a..2015291 100644 --- a/include/tao/pq/internal/format_as.hpp +++ b/include/tao/pq/internal/format_as.hpp @@ -21,7 +21,7 @@ struct std::formatter< T > : std::formatter< decltype( taopq_format_as( std::dec template< typename T > requires requires { taopq_format_as( std::declval< T >() ); } -std::ostream& operator<<( std::ostream& os, const T& v ) +auto operator<<( std::ostream& os, const T& v ) -> std::ostream& { return os << taopq_format_as( v ); } From 701046768e0ebefc3ceb1b5009b5d8beedd991a8 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 18:31:00 +0100 Subject: [PATCH 09/17] Cleanup --- include/tao/pq/connection.hpp | 4 ++-- include/tao/pq/connection_pool.hpp | 36 +++++++++++++++++++++------- src/lib/pq/connection.cpp | 8 +++---- src/lib/pq/connection_pool.cpp | 38 ++++-------------------------- 4 files changed, 38 insertions(+), 48 deletions(-) diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 4bc17cb..8cad384 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -111,7 +111,7 @@ namespace tao::pq }; public: - connection( const private_key /*unused*/, const std::string& connection_info, std::function< poll::callback > poll_cb ); + connection( const private_key /*unused*/, const std::string& connection_info ); connection( const connection& ) = delete; connection( connection&& ) = delete; @@ -120,7 +120,7 @@ namespace tao::pq ~connection() = default; - [[nodiscard]] static auto create( const std::string& connection_info, std::function< poll::callback > poll_cb = internal::poll ) -> std::shared_ptr< connection >; + [[nodiscard]] static auto create( const std::string& connection_info ) -> std::shared_ptr< connection >; [[nodiscard]] auto error_message() const -> const char*; diff --git a/include/tao/pq/connection_pool.hpp b/include/tao/pq/connection_pool.hpp index 657519a..9b0d572 100644 --- a/include/tao/pq/connection_pool.hpp +++ b/include/tao/pq/connection_pool.hpp @@ -48,12 +48,14 @@ namespace tao::pq }; public: - connection_pool( const private_key /*unused*/, const std::string_view connection_info, std::function< poll::callback > poll_cb ); + connection_pool( const private_key /*unused*/, const std::string_view connection_info ); + + void get() const = delete; template< typename T = connection_pool > - [[nodiscard]] static auto create( const std::string_view connection_info, std::function< poll::callback > poll_cb = internal::poll ) -> std::shared_ptr< T > + [[nodiscard]] static auto create( const std::string_view connection_info ) -> std::shared_ptr< T > { - return std::make_shared< T >( private_key(), connection_info, std::move( poll_cb ) ); + return std::make_shared< T >( private_key(), connection_info ); } [[nodiscard]] auto timeout() const noexcept -> decltype( auto ) @@ -61,12 +63,30 @@ namespace tao::pq return m_timeout; } - void set_timeout( const std::chrono::milliseconds timeout ) noexcept; - void reset_timeout() noexcept; + void set_timeout( const std::chrono::milliseconds timeout ) noexcept + { + m_timeout = timeout; + } + + void reset_timeout() noexcept + { + m_timeout = std::nullopt; + } + + [[nodiscard]] auto poll_callback() const noexcept -> decltype( auto ) + { + return m_poll; + } - [[nodiscard]] auto poll_callback() const noexcept -> const std::function< poll::callback >&; - void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept; - void reset_poll_callback(); + void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept + { + m_poll = std::move( poll_cb ); + } + + void reset_poll_callback() + { + m_poll = internal::poll; + } [[nodiscard]] auto connection() -> std::shared_ptr< connection >; diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index 92530d5..ceb926b 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -436,10 +436,10 @@ namespace tao::pq } } - connection::connection( const private_key /*unused*/, const std::string& connection_info, std::function< poll::callback > poll_cb ) + connection::connection( const private_key /*unused*/, const std::string& connection_info ) : m_pgconn( PQconnectdb( connection_info.c_str() ), &PQfinish ), m_current_transaction( nullptr ), - m_poll( std::move( poll_cb ) ) + m_poll( internal::poll ) { if( !is_open() ) { // note that we can not access the sqlstate after PQconnectdb(), @@ -452,9 +452,9 @@ namespace tao::pq } } - auto connection::create( const std::string& connection_info, std::function< poll::callback > poll_cb ) -> std::shared_ptr< connection > + auto connection::create( const std::string& connection_info ) -> std::shared_ptr< connection > { - return std::make_shared< connection >( private_key(), connection_info, std::move( poll_cb ) ); + return std::make_shared< connection >( private_key(), connection_info ); } auto connection::error_message() const -> const char* diff --git a/src/lib/pq/connection_pool.cpp b/src/lib/pq/connection_pool.cpp index 2bb8939..509f88a 100644 --- a/src/lib/pq/connection_pool.cpp +++ b/src/lib/pq/connection_pool.cpp @@ -4,57 +4,27 @@ #include -#include -#include #include -#include #include -#include #include #include -#include namespace tao::pq { auto connection_pool::v_create() const -> std::unique_ptr< pq::connection > { - return std::make_unique< pq::connection >( pq::connection::private_key(), m_connection_info, m_poll ); + return std::make_unique< pq::connection >( pq::connection::private_key(), m_connection_info ); } - connection_pool::connection_pool( const private_key /*unused*/, const std::string_view connection_info, std::function< poll::callback > poll_cb ) + connection_pool::connection_pool( const private_key /*unused*/, const std::string_view connection_info ) : m_connection_info( connection_info ), - m_poll( std::move( poll_cb ) ) + m_poll( internal::poll ) {} - void connection_pool::set_timeout( const std::chrono::milliseconds timeout ) noexcept - { - m_timeout = timeout; - } - - void connection_pool::reset_timeout() noexcept - { - m_timeout = std::nullopt; - } - - auto connection_pool::poll_callback() const noexcept -> const std::function< poll::callback >& - { - return m_poll; - } - - void connection_pool::set_poll_callback( std::function< poll::callback > poll_cb ) noexcept - { - m_poll = std::move( poll_cb ); - } - - void connection_pool::reset_poll_callback() - { - m_poll = internal::poll; - } - auto connection_pool::connection() -> std::shared_ptr< pq::connection > { - auto result = get(); + auto result = internal::pool< pq::connection >::get(); if( m_timeout ) { result->set_timeout( *m_timeout ); } From 8ea74748343cf56cd37b94a8d29cb4af742df4a3 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 19:46:49 +0100 Subject: [PATCH 10/17] Cleanup --- include/tao/pq/connection_pool.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/tao/pq/connection_pool.hpp b/include/tao/pq/connection_pool.hpp index 9b0d572..c98b2f0 100644 --- a/include/tao/pq/connection_pool.hpp +++ b/include/tao/pq/connection_pool.hpp @@ -24,7 +24,7 @@ namespace tao::pq { class connection_pool - : public internal::pool< connection > + : public internal::pool< pq::connection > { private: const std::string m_connection_info; @@ -34,7 +34,7 @@ namespace tao::pq protected: [[nodiscard]] auto v_create() const -> std::unique_ptr< pq::connection > override; - [[nodiscard]] auto v_is_valid( connection& c ) const noexcept -> bool override + [[nodiscard]] auto v_is_valid( pq::connection& c ) const noexcept -> bool override { return c.is_idle(); } @@ -88,7 +88,7 @@ namespace tao::pq m_poll = internal::poll; } - [[nodiscard]] auto connection() -> std::shared_ptr< connection >; + [[nodiscard]] auto connection() -> std::shared_ptr< pq::connection >; template< parameter_type... As > auto execute( const internal::zsv statement, As&&... as ) From 4131292bcf7ff7c1f5d42936c1f8e0c26b9e80f6 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 20:57:11 +0100 Subject: [PATCH 11/17] Add get_result logging --- include/tao/pq/log.hpp | 7 ++++++- src/lib/pq/connection.cpp | 3 +++ src/test/pq/log.cpp | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp index 5e3f4c9..9cad652 100644 --- a/include/tao/pq/log.hpp +++ b/include/tao/pq/log.hpp @@ -46,6 +46,7 @@ namespace tao::pq using flush_result_t = std::function< void( connection&, int result ) >; using get_result_t = std::function< void( connection&, std::chrono::steady_clock::time_point end ) >; + using get_result_result_t = std::function< void( connection&, PGresult* ) >; struct : send_query_t { @@ -84,7 +85,11 @@ namespace tao::pq using flush_t::operator=; } flush; - get_result_t get_result; + struct : get_result_t + { + get_result_result_t result; + using get_result_t::operator=; + } get_result; } connection; diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index ceb926b..cffdad7 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -324,6 +324,9 @@ namespace tao::pq } std::unique_ptr< PGresult, decltype( &PQclear ) > result( PQgetResult( m_pgconn.get() ), &PQclear ); + if( m_log && m_log->connection.get_result.result ) { + m_log->connection.get_result.result( *this, result.get() ); + } handle_notifications(); return result; } diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index 518735c..dc213cd 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -91,6 +91,16 @@ namespace std::cout << std::format( "flush(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; } + void log_get_result( tao::pq::connection& c, std::chrono::steady_clock::time_point e ) + { + std::cout << std::format( "get_result(connection={}, timeout={}ms)", static_cast< const void* >( &c ), to_millis( e ) ) << '\n'; + } + + void log_get_result_result( tao::pq::connection& c, PGresult* r ) + { + std::cout << std::format( "get_result(connection={}) -> {}", static_cast< const void* >( &c ), static_cast< const void* >( r ) ) << '\n'; + } + void run() { // overwrite the default with an environment variable if needed @@ -114,6 +124,8 @@ namespace log->connection.consume_input.result = log_consume_input_result; log->connection.flush = log_flush; log->connection.flush.result = log_flush_result; + log->connection.get_result = log_get_result; + log->connection.get_result.result = log_get_result_result; conn->set_log_handler( log ); // execute statements From d06323ef6f73e8fc6110a6221de74bb85d3b1460 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Fri, 27 Dec 2024 23:51:16 +0100 Subject: [PATCH 12/17] More logging --- include/tao/pq/connection.hpp | 2 ++ include/tao/pq/log.hpp | 25 ++++++++++++++++++ src/lib/pq/connection.cpp | 49 +++++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 8cad384..6c969cb 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -198,6 +198,8 @@ namespace tao::pq [[nodiscard]] auto flush() -> bool; + void consume_input(); + [[nodiscard]] auto direct() -> std::shared_ptr< pq::transaction >; [[nodiscard]] auto transaction() -> std::shared_ptr< pq::transaction >; diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp index 9cad652..e97f922 100644 --- a/include/tao/pq/log.hpp +++ b/include/tao/pq/log.hpp @@ -48,6 +48,14 @@ namespace tao::pq using get_result_t = std::function< void( connection&, std::chrono::steady_clock::time_point end ) >; using get_result_result_t = std::function< void( connection&, PGresult* ) >; + using enter_pipeline_mode_result_t = std::function< void( connection&, int result ) >; + + using exit_pipeline_mode_t = std::function< void( connection& ) >; + using exit_pipeline_mode_result_t = std::function< void( connection&, int result ) >; + + using pipeline_sync_t = std::function< void( connection& ) >; + using pipeline_sync_result_t = std::function< void( connection&, int result ) >; + struct : send_query_t { send_query_result_t result; @@ -91,6 +99,23 @@ namespace tao::pq using get_result_t::operator=; } get_result; + struct + { + enter_pipeline_mode_result_t result; + } enter_pipeline_mode; + + struct : exit_pipeline_mode_t + { + exit_pipeline_mode_result_t result; + using exit_pipeline_mode_t::operator=; + } exit_pipeline_mode; + + struct : pipeline_sync_t + { + pipeline_sync_result_t result; + using pipeline_sync_t::operator=; + } pipeline_sync; + } connection; struct transaction_t diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index cffdad7..31bcccb 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -504,21 +504,39 @@ namespace tao::pq void connection::enter_pipeline_mode() { - if( PQenterPipelineMode( m_pgconn.get() ) == 0 ) { + const auto result = PQenterPipelineMode( m_pgconn.get() ); + if( m_log && m_log->connection.enter_pipeline_mode.result ) { + m_log->connection.enter_pipeline_mode.result( *this, result ); + } + if( result == 0 ) { throw pq::connection_error( "unable to enter pipeline mode" ); } } void connection::exit_pipeline_mode() { - if( PQexitPipelineMode( m_pgconn.get() ) == 0 ) { + if( m_log && m_log->connection.exit_pipeline_mode ) { + m_log->connection.exit_pipeline_mode( *this ); + } + const auto result = PQexitPipelineMode( m_pgconn.get() ); + if( m_log && m_log->connection.exit_pipeline_mode.result ) { + m_log->connection.exit_pipeline_mode.result( *this, result ); + } + if( result == 0 ) { throw pq::connection_error( error_message() ); } } void connection::pipeline_sync() { - if( PQpipelineSync( m_pgconn.get() ) == 0 ) { + if( m_log && m_log->connection.pipeline_sync ) { + m_log->connection.pipeline_sync( *this ); + } + const auto result = PQpipelineSync( m_pgconn.get() ); + if( m_log && m_log->connection.pipeline_sync.result ) { + m_log->connection.pipeline_sync.result( *this, result ); + } + if( result == 0 ) { throw pq::connection_error( "unable to sync pipeline" ); } } @@ -553,6 +571,20 @@ namespace tao::pq } } + void connection::consume_input() + { + if( m_log && m_log->connection.consume_input ) { + m_log->connection.consume_input( *this ); + } + const auto result = PQconsumeInput( m_pgconn.get() ); + if( m_log && m_log->connection.consume_input.result ) { + m_log->connection.consume_input.result( *this, result ); + } + if( result == 0 ) { + throw pq::connection_error( error_message() ); + } + } + auto connection::direct() -> std::shared_ptr< pq::transaction > { return std::make_shared< internal::autocommit_transaction >( shared_from_this() ); @@ -660,16 +692,7 @@ namespace tao::pq void connection::get_notifications() { - if( m_log && m_log->connection.consume_input ) { - m_log->connection.consume_input( *this ); - } - const auto result = PQconsumeInput( m_pgconn.get() ); - if( m_log && m_log->connection.consume_input.result ) { - m_log->connection.consume_input.result( *this, result ); - } - if( result == 0 ) { - throw pq::connection_error( error_message() ); - } + consume_input(); handle_notifications(); } From 18765018859d2f8e08b7b903d2ba44d78f81ffbc Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Wed, 1 Jan 2025 12:03:59 +0100 Subject: [PATCH 13/17] Welcome 2025 --- .clang-format | 2 +- .clang-tidy | 2 +- Makefile | 2 +- README.md | 2 +- doc/Aggregate-Support.md | 2 +- doc/Binary-Data.md | 2 +- doc/Bulk-Transfer.md | 2 +- doc/Connection-Pool.md | 2 +- doc/Connection.md | 2 +- doc/Error-Handling.md | 2 +- doc/Getting-Started.md | 2 +- doc/Installation.md | 2 +- doc/Large-Object.md | 2 +- doc/Parameter-Type-Conversion.md | 2 +- doc/Performance.md | 2 +- doc/Requirements.md | 2 +- doc/Result-Type-Conversion.md | 2 +- doc/Result.md | 2 +- doc/Statement.md | 2 +- doc/Transaction.md | 2 +- include/tao/pq.hpp | 2 +- include/tao/pq/access_mode.hpp | 2 +- include/tao/pq/binary.hpp | 2 +- include/tao/pq/bind.hpp | 2 +- include/tao/pq/connection.hpp | 2 +- include/tao/pq/connection_pool.hpp | 2 +- include/tao/pq/connection_status.hpp | 2 +- include/tao/pq/exception.hpp | 2 +- include/tao/pq/field.hpp | 2 +- include/tao/pq/internal/aggregate.hpp | 2 +- include/tao/pq/internal/demangle.hpp | 2 +- include/tao/pq/internal/exclusive_scan.hpp | 2 +- include/tao/pq/internal/format_as.hpp | 2 +- include/tao/pq/internal/from_chars.hpp | 2 +- include/tao/pq/internal/gen.hpp | 2 +- include/tao/pq/internal/parameter_traits_helper.hpp | 2 +- include/tao/pq/internal/poll.hpp | 2 +- include/tao/pq/internal/pool.hpp | 2 +- include/tao/pq/internal/resize_uninitialized.hpp | 2 +- include/tao/pq/internal/strtox.hpp | 2 +- include/tao/pq/internal/unreachable.hpp | 2 +- include/tao/pq/internal/zsv.hpp | 2 +- include/tao/pq/is_aggregate.hpp | 2 +- include/tao/pq/is_array.hpp | 2 +- include/tao/pq/isolation_level.hpp | 2 +- include/tao/pq/large_object.hpp | 2 +- include/tao/pq/log.hpp | 2 +- include/tao/pq/notification.hpp | 2 +- include/tao/pq/null.hpp | 2 +- include/tao/pq/oid.hpp | 2 +- include/tao/pq/parameter.hpp | 2 +- include/tao/pq/parameter_traits.hpp | 2 +- include/tao/pq/parameter_traits_aggregate.hpp | 2 +- include/tao/pq/parameter_traits_array.hpp | 2 +- include/tao/pq/parameter_traits_optional.hpp | 2 +- include/tao/pq/parameter_traits_pair.hpp | 2 +- include/tao/pq/parameter_traits_tuple.hpp | 2 +- include/tao/pq/pipeline.hpp | 2 +- include/tao/pq/pipeline_status.hpp | 2 +- include/tao/pq/poll.hpp | 2 +- include/tao/pq/result.hpp | 2 +- include/tao/pq/result_status.hpp | 2 +- include/tao/pq/result_traits.hpp | 2 +- include/tao/pq/result_traits_aggregate.hpp | 2 +- include/tao/pq/result_traits_array.hpp | 2 +- include/tao/pq/result_traits_optional.hpp | 2 +- include/tao/pq/result_traits_pair.hpp | 2 +- include/tao/pq/result_traits_tuple.hpp | 2 +- include/tao/pq/row.hpp | 2 +- include/tao/pq/table_field.hpp | 2 +- include/tao/pq/table_reader.hpp | 2 +- include/tao/pq/table_row.hpp | 2 +- include/tao/pq/table_writer.hpp | 2 +- include/tao/pq/transaction.hpp | 2 +- include/tao/pq/transaction_base.hpp | 2 +- include/tao/pq/transaction_status.hpp | 2 +- include/tao/pq/version.hpp | 2 +- src/lib/pq/connection.cpp | 2 +- src/lib/pq/connection_pool.cpp | 2 +- src/lib/pq/exception.cpp | 2 +- src/lib/pq/field.cpp | 2 +- src/lib/pq/internal/demangle.cpp | 2 +- src/lib/pq/internal/poll.cpp | 2 +- src/lib/pq/internal/strtox.cpp | 2 +- src/lib/pq/large_object.cpp | 2 +- src/lib/pq/parameter_traits.cpp | 2 +- src/lib/pq/pipeline.cpp | 2 +- src/lib/pq/result.cpp | 2 +- src/lib/pq/result_traits.cpp | 2 +- src/lib/pq/result_traits_array.cpp | 2 +- src/lib/pq/row.cpp | 2 +- src/lib/pq/table_field.cpp | 2 +- src/lib/pq/table_reader.cpp | 2 +- src/lib/pq/table_row.cpp | 2 +- src/lib/pq/table_writer.cpp | 2 +- src/lib/pq/transaction.cpp | 2 +- src/lib/pq/transaction_base.cpp | 2 +- src/test/compare.hpp | 2 +- src/test/getenv.hpp | 2 +- src/test/macros.hpp | 2 +- src/test/pq/aggregate.cpp | 2 +- src/test/pq/array.cpp | 2 +- src/test/pq/basic_datatypes.cpp | 2 +- src/test/pq/chunk_mode.cpp | 2 +- src/test/pq/connection.cpp | 2 +- src/test/pq/connection_pool.cpp | 2 +- src/test/pq/example.cpp | 2 +- src/test/pq/exception.cpp | 2 +- src/test/pq/getenv.cpp | 2 +- src/test/pq/large_object.cpp | 2 +- src/test/pq/log.cpp | 2 +- src/test/pq/notifications.cpp | 2 +- src/test/pq/parameter.cpp | 2 +- src/test/pq/parameter_type.cpp | 2 +- src/test/pq/password.cpp | 2 +- src/test/pq/pipeline_mode.cpp | 2 +- src/test/pq/resize_uninitialized.cpp | 2 +- src/test/pq/result.cpp | 2 +- src/test/pq/result_type.cpp | 2 +- src/test/pq/row.cpp | 2 +- src/test/pq/single_row_mode.cpp | 2 +- src/test/pq/strtox.cpp | 2 +- src/test/pq/table_reader.cpp | 2 +- src/test/pq/table_writer.cpp | 2 +- src/test/pq/traits.cpp | 2 +- src/test/pq/transaction.cpp | 2 +- 126 files changed, 126 insertions(+), 126 deletions(-) diff --git a/.clang-format b/.clang-format index 5eece0c..71aac94 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,7 @@ # The Art of C++ # https://github.com/taocpp -# Copyright (c) 2016-2024 Dr. Colin Hirsch and Daniel Frey +# Copyright (c) 2016-2025 Dr. Colin Hirsch and Daniel Frey # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/.clang-tidy b/.clang-tidy index b3148be..fc1c51e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,7 +1,7 @@ # The Art of C++ # https://github.com/taocpp -# Copyright (c) 2016-2024 Dr. Colin Hirsch and Daniel Frey +# Copyright (c) 2016-2025 Dr. Colin Hirsch and Daniel Frey # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/Makefile b/Makefile index ae63709..83f09ab 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # The Art of C++ # https://github.com/taocpp -# Copyright (c) 2016-2024 Daniel Frey +# Copyright (c) 2016-2025 Daniel Frey # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/README.md b/README.md index 5af33ca..43fd8af 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ taoPQ is part of [The Art of C++](https://taocpp.github.io/). Open Source Initiative -Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch taoPQ is certified [Open Sourceâžš](http://www.opensource.org/docs/definition.html) software. It is [licensedâžš](https://pdimov.github.io/blog/2020/09/06/why-use-the-boost-license/) under the terms of the [Boost Software License, Version 1.0âžš](https://www.boost.org/LICENSE_1_0.txt) reproduced here. diff --git a/doc/Aggregate-Support.md b/doc/Aggregate-Support.md index 405d279..e86663e 100644 --- a/doc/Aggregate-Support.md +++ b/doc/Aggregate-Support.md @@ -94,6 +94,6 @@ int main() This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Binary-Data.md b/doc/Binary-Data.md index b192305..198c455 100644 --- a/doc/Binary-Data.md +++ b/doc/Binary-Data.md @@ -53,6 +53,6 @@ In some cases other alternatives are offered, i.e. you may provide a buffer that This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Bulk-Transfer.md b/doc/Bulk-Transfer.md index e78fa7c..9bef5f6 100644 --- a/doc/Bulk-Transfer.md +++ b/doc/Bulk-Transfer.md @@ -248,6 +248,6 @@ namespace tao::pq This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Connection-Pool.md b/doc/Connection-Pool.md index e54cc23..40d8689 100644 --- a/doc/Connection-Pool.md +++ b/doc/Connection-Pool.md @@ -178,6 +178,6 @@ We minimized the work in the [critical sectionsâžš](https://en.wikipedia.org/wik This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Connection.md b/doc/Connection.md index 611b2b0..1779678 100644 --- a/doc/Connection.md +++ b/doc/Connection.md @@ -411,6 +411,6 @@ When taoPQ throws an exception this is usually done internally and the message i This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Error-Handling.md b/doc/Error-Handling.md index e683294..cbaebf6 100644 --- a/doc/Error-Handling.md +++ b/doc/Error-Handling.md @@ -78,6 +78,6 @@ The same exception can also be thrown when calling the connection's `get_notific This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Getting-Started.md b/doc/Getting-Started.md index 60f7717..b79b4e0 100644 --- a/doc/Getting-Started.md +++ b/doc/Getting-Started.md @@ -67,6 +67,6 @@ The following chapters are good next steps to get to know taoPQ: This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Installation.md b/doc/Installation.md index 3b662fa..90b22e9 100644 --- a/doc/Installation.md +++ b/doc/Installation.md @@ -40,6 +40,6 @@ When executing the build step, taoPQ will be built first, as its target is requi This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Large-Object.md b/doc/Large-Object.md index 14c42db..b43460c 100644 --- a/doc/Large-Object.md +++ b/doc/Large-Object.md @@ -222,6 +222,6 @@ If an error occurs an exception will be thrown. This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Parameter-Type-Conversion.md b/doc/Parameter-Type-Conversion.md index 848c95a..a2db51f 100644 --- a/doc/Parameter-Type-Conversion.md +++ b/doc/Parameter-Type-Conversion.md @@ -186,6 +186,6 @@ TODO: Write proper documentation. This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Performance.md b/doc/Performance.md index 06d5d8e..5552488 100644 --- a/doc/Performance.md +++ b/doc/Performance.md @@ -6,6 +6,6 @@ This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Requirements.md b/doc/Requirements.md index 2237356..369ba59 100644 --- a/doc/Requirements.md +++ b/doc/Requirements.md @@ -42,6 +42,6 @@ You can decide which options you want to use in your project, we just try to not This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Result-Type-Conversion.md b/doc/Result-Type-Conversion.md index 6b8eca0..c7abb28 100644 --- a/doc/Result-Type-Conversion.md +++ b/doc/Result-Type-Conversion.md @@ -146,6 +146,6 @@ TODO: Write proper documentation. This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Result.md b/doc/Result.md index 2cff59e..6bbba70 100644 --- a/doc/Result.md +++ b/doc/Result.md @@ -482,6 +482,6 @@ auto tao::pq::field::optional() const This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Statement.md b/doc/Statement.md index 611d222..0632fb5 100644 --- a/doc/Statement.md +++ b/doc/Statement.md @@ -125,6 +125,6 @@ The [Parameter Type Conversion](Parameter-Type-Conversion.md) chapter explains w This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/doc/Transaction.md b/doc/Transaction.md index 9af4fa3..78d83cd 100644 --- a/doc/Transaction.md +++ b/doc/Transaction.md @@ -160,6 +160,6 @@ auto tao::pq::transaction::connection() const noexcept This document is part of [taoPQ](https://github.com/taocpp/taopq). -Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch
+Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch
Distributed under the Boost Software License, Version 1.0
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt diff --git a/include/tao/pq.hpp b/include/tao/pq.hpp index 53680d8..fbcde9f 100644 --- a/include/tao/pq.hpp +++ b/include/tao/pq.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/access_mode.hpp b/include/tao/pq/access_mode.hpp index 9feb5eb..5237aa4 100644 --- a/include/tao/pq/access_mode.hpp +++ b/include/tao/pq/access_mode.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/binary.hpp b/include/tao/pq/binary.hpp index 25229aa..0a38180 100644 --- a/include/tao/pq/binary.hpp +++ b/include/tao/pq/binary.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/bind.hpp b/include/tao/pq/bind.hpp index 0345193..122d595 100644 --- a/include/tao/pq/bind.hpp +++ b/include/tao/pq/bind.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 6c969cb..4eb8bfd 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/connection_pool.hpp b/include/tao/pq/connection_pool.hpp index c98b2f0..4418e9d 100644 --- a/include/tao/pq/connection_pool.hpp +++ b/include/tao/pq/connection_pool.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/connection_status.hpp b/include/tao/pq/connection_status.hpp index 1c01530..4011161 100644 --- a/include/tao/pq/connection_status.hpp +++ b/include/tao/pq/connection_status.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2022-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/exception.hpp b/include/tao/pq/exception.hpp index 4a3a64c..8645f47 100644 --- a/include/tao/pq/exception.hpp +++ b/include/tao/pq/exception.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/field.hpp b/include/tao/pq/field.hpp index 438e337..64b72a6 100644 --- a/include/tao/pq/field.hpp +++ b/include/tao/pq/field.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/aggregate.hpp b/include/tao/pq/internal/aggregate.hpp index d7e627c..a4bf63d 100644 --- a/include/tao/pq/internal/aggregate.hpp +++ b/include/tao/pq/internal/aggregate.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/demangle.hpp b/include/tao/pq/internal/demangle.hpp index 027739b..93d13ab 100644 --- a/include/tao/pq/internal/demangle.hpp +++ b/include/tao/pq/internal/demangle.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/exclusive_scan.hpp b/include/tao/pq/internal/exclusive_scan.hpp index d464115..d0b4d4d 100644 --- a/include/tao/pq/internal/exclusive_scan.hpp +++ b/include/tao/pq/internal/exclusive_scan.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2019-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/format_as.hpp b/include/tao/pq/internal/format_as.hpp index 2015291..dbabd6d 100644 --- a/include/tao/pq/internal/format_as.hpp +++ b/include/tao/pq/internal/format_as.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/from_chars.hpp b/include/tao/pq/internal/from_chars.hpp index abe525b..adda411 100644 --- a/include/tao/pq/internal/from_chars.hpp +++ b/include/tao/pq/internal/from_chars.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/gen.hpp b/include/tao/pq/internal/gen.hpp index b9585e6..ff6aca1 100644 --- a/include/tao/pq/internal/gen.hpp +++ b/include/tao/pq/internal/gen.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2019-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/parameter_traits_helper.hpp b/include/tao/pq/internal/parameter_traits_helper.hpp index fc0eefc..3fcb8b7 100644 --- a/include/tao/pq/internal/parameter_traits_helper.hpp +++ b/include/tao/pq/internal/parameter_traits_helper.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/poll.hpp b/include/tao/pq/internal/poll.hpp index 8463366..fc9fda4 100644 --- a/include/tao/pq/internal/poll.hpp +++ b/include/tao/pq/internal/poll.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/pool.hpp b/include/tao/pq/internal/pool.hpp index 80f91d3..418d643 100644 --- a/include/tao/pq/internal/pool.hpp +++ b/include/tao/pq/internal/pool.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/resize_uninitialized.hpp b/include/tao/pq/internal/resize_uninitialized.hpp index ced6ea9..61a3f93 100644 --- a/include/tao/pq/internal/resize_uninitialized.hpp +++ b/include/tao/pq/internal/resize_uninitialized.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/strtox.hpp b/include/tao/pq/internal/strtox.hpp index b4284ad..aafe579 100644 --- a/include/tao/pq/internal/strtox.hpp +++ b/include/tao/pq/internal/strtox.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/unreachable.hpp b/include/tao/pq/internal/unreachable.hpp index a17ea28..95f25f2 100644 --- a/include/tao/pq/internal/unreachable.hpp +++ b/include/tao/pq/internal/unreachable.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/internal/zsv.hpp b/include/tao/pq/internal/zsv.hpp index 2c8d561..4c43f34 100644 --- a/include/tao/pq/internal/zsv.hpp +++ b/include/tao/pq/internal/zsv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/is_aggregate.hpp b/include/tao/pq/is_aggregate.hpp index 3b4aefe..ec53b4a 100644 --- a/include/tao/pq/is_aggregate.hpp +++ b/include/tao/pq/is_aggregate.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/is_array.hpp b/include/tao/pq/is_array.hpp index ebefb16..26c0601 100644 --- a/include/tao/pq/is_array.hpp +++ b/include/tao/pq/is_array.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/isolation_level.hpp b/include/tao/pq/isolation_level.hpp index 225e427..bdf7ed2 100644 --- a/include/tao/pq/isolation_level.hpp +++ b/include/tao/pq/isolation_level.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/large_object.hpp b/include/tao/pq/large_object.hpp index 1f27676..624cfec 100644 --- a/include/tao/pq/large_object.hpp +++ b/include/tao/pq/large_object.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp index e97f922..ed95661 100644 --- a/include/tao/pq/log.hpp +++ b/include/tao/pq/log.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/notification.hpp b/include/tao/pq/notification.hpp index 7169f03..8bbeb0b 100644 --- a/include/tao/pq/notification.hpp +++ b/include/tao/pq/notification.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/null.hpp b/include/tao/pq/null.hpp index f149e30..02d664f 100644 --- a/include/tao/pq/null.hpp +++ b/include/tao/pq/null.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/oid.hpp b/include/tao/pq/oid.hpp index 33ba150..eb607bb 100644 --- a/include/tao/pq/oid.hpp +++ b/include/tao/pq/oid.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter.hpp b/include/tao/pq/parameter.hpp index 78b8012..aa3a4da 100644 --- a/include/tao/pq/parameter.hpp +++ b/include/tao/pq/parameter.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits.hpp b/include/tao/pq/parameter_traits.hpp index 13819ab..e92965c 100644 --- a/include/tao/pq/parameter_traits.hpp +++ b/include/tao/pq/parameter_traits.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits_aggregate.hpp b/include/tao/pq/parameter_traits_aggregate.hpp index 034a584..f49b8e5 100644 --- a/include/tao/pq/parameter_traits_aggregate.hpp +++ b/include/tao/pq/parameter_traits_aggregate.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits_array.hpp b/include/tao/pq/parameter_traits_array.hpp index 628b374..e819dc3 100644 --- a/include/tao/pq/parameter_traits_array.hpp +++ b/include/tao/pq/parameter_traits_array.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits_optional.hpp b/include/tao/pq/parameter_traits_optional.hpp index b2b68a1..4c79ad8 100644 --- a/include/tao/pq/parameter_traits_optional.hpp +++ b/include/tao/pq/parameter_traits_optional.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits_pair.hpp b/include/tao/pq/parameter_traits_pair.hpp index 964ac07..9d185bd 100644 --- a/include/tao/pq/parameter_traits_pair.hpp +++ b/include/tao/pq/parameter_traits_pair.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/parameter_traits_tuple.hpp b/include/tao/pq/parameter_traits_tuple.hpp index cc2cfd1..514136d 100644 --- a/include/tao/pq/parameter_traits_tuple.hpp +++ b/include/tao/pq/parameter_traits_tuple.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/pipeline.hpp b/include/tao/pq/pipeline.hpp index f4eae9e..8bc5bf5 100644 --- a/include/tao/pq/pipeline.hpp +++ b/include/tao/pq/pipeline.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/pipeline_status.hpp b/include/tao/pq/pipeline_status.hpp index c52c9db..e9ccec9 100644 --- a/include/tao/pq/pipeline_status.hpp +++ b/include/tao/pq/pipeline_status.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/poll.hpp b/include/tao/pq/poll.hpp index 1c09999..231e38c 100644 --- a/include/tao/pq/poll.hpp +++ b/include/tao/pq/poll.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result.hpp b/include/tao/pq/result.hpp index d1fb43b..c285dc4 100644 --- a/include/tao/pq/result.hpp +++ b/include/tao/pq/result.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_status.hpp b/include/tao/pq/result_status.hpp index a8ad979..0930bf2 100644 --- a/include/tao/pq/result_status.hpp +++ b/include/tao/pq/result_status.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits.hpp b/include/tao/pq/result_traits.hpp index b06a6b1..2e0ea7a 100644 --- a/include/tao/pq/result_traits.hpp +++ b/include/tao/pq/result_traits.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits_aggregate.hpp b/include/tao/pq/result_traits_aggregate.hpp index 9e12dd6..0ce3192 100644 --- a/include/tao/pq/result_traits_aggregate.hpp +++ b/include/tao/pq/result_traits_aggregate.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits_array.hpp b/include/tao/pq/result_traits_array.hpp index 120e8cb..f4f0801 100644 --- a/include/tao/pq/result_traits_array.hpp +++ b/include/tao/pq/result_traits_array.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits_optional.hpp b/include/tao/pq/result_traits_optional.hpp index 7409e8a..cf74430 100644 --- a/include/tao/pq/result_traits_optional.hpp +++ b/include/tao/pq/result_traits_optional.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits_pair.hpp b/include/tao/pq/result_traits_pair.hpp index f5e24c3..8170b1a 100644 --- a/include/tao/pq/result_traits_pair.hpp +++ b/include/tao/pq/result_traits_pair.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/result_traits_tuple.hpp b/include/tao/pq/result_traits_tuple.hpp index eb86c66..87cde99 100644 --- a/include/tao/pq/result_traits_tuple.hpp +++ b/include/tao/pq/result_traits_tuple.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/row.hpp b/include/tao/pq/row.hpp index 7abd494..55b204b 100644 --- a/include/tao/pq/row.hpp +++ b/include/tao/pq/row.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/table_field.hpp b/include/tao/pq/table_field.hpp index 88efd5e..60dc10d 100644 --- a/include/tao/pq/table_field.hpp +++ b/include/tao/pq/table_field.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/table_reader.hpp b/include/tao/pq/table_reader.hpp index 5dbfc98..0f1a12b 100644 --- a/include/tao/pq/table_reader.hpp +++ b/include/tao/pq/table_reader.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/table_row.hpp b/include/tao/pq/table_row.hpp index f39b611..f623829 100644 --- a/include/tao/pq/table_row.hpp +++ b/include/tao/pq/table_row.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/table_writer.hpp b/include/tao/pq/table_writer.hpp index 360ea20..a74fba4 100644 --- a/include/tao/pq/table_writer.hpp +++ b/include/tao/pq/table_writer.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/transaction.hpp b/include/tao/pq/transaction.hpp index a8d2a91..7c7febb 100644 --- a/include/tao/pq/transaction.hpp +++ b/include/tao/pq/transaction.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/transaction_base.hpp b/include/tao/pq/transaction_base.hpp index 1015bfc..03eff20 100644 --- a/include/tao/pq/transaction_base.hpp +++ b/include/tao/pq/transaction_base.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/transaction_status.hpp b/include/tao/pq/transaction_status.hpp index 805173d..0cd4b12 100644 --- a/include/tao/pq/transaction_status.hpp +++ b/include/tao/pq/transaction_status.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2022-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/include/tao/pq/version.hpp b/include/tao/pq/version.hpp index a4a20e5..eadb81d 100644 --- a/include/tao/pq/version.hpp +++ b/include/tao/pq/version.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index 31bcccb..580580d 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/connection_pool.cpp b/src/lib/pq/connection_pool.cpp index 509f88a..f9486ea 100644 --- a/src/lib/pq/connection_pool.cpp +++ b/src/lib/pq/connection_pool.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/exception.cpp b/src/lib/pq/exception.cpp index 52f96be..04ca9e5 100644 --- a/src/lib/pq/exception.cpp +++ b/src/lib/pq/exception.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/field.cpp b/src/lib/pq/field.cpp index 4ade4d3..3cf6c53 100644 --- a/src/lib/pq/field.cpp +++ b/src/lib/pq/field.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/internal/demangle.cpp b/src/lib/pq/internal/demangle.cpp index 6709eb3..01507b8 100644 --- a/src/lib/pq/internal/demangle.cpp +++ b/src/lib/pq/internal/demangle.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/internal/poll.cpp b/src/lib/pq/internal/poll.cpp index 63689e8..7740fdf 100644 --- a/src/lib/pq/internal/poll.cpp +++ b/src/lib/pq/internal/poll.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/internal/strtox.cpp b/src/lib/pq/internal/strtox.cpp index b16f870..626b98f 100644 --- a/src/lib/pq/internal/strtox.cpp +++ b/src/lib/pq/internal/strtox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/large_object.cpp b/src/lib/pq/large_object.cpp index 348195b..80aee01 100644 --- a/src/lib/pq/large_object.cpp +++ b/src/lib/pq/large_object.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/parameter_traits.cpp b/src/lib/pq/parameter_traits.cpp index 9315338..5001793 100644 --- a/src/lib/pq/parameter_traits.cpp +++ b/src/lib/pq/parameter_traits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/pipeline.cpp b/src/lib/pq/pipeline.cpp index 896936c..3ce9669 100644 --- a/src/lib/pq/pipeline.cpp +++ b/src/lib/pq/pipeline.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/result.cpp b/src/lib/pq/result.cpp index dc44fe7..1a24ea3 100644 --- a/src/lib/pq/result.cpp +++ b/src/lib/pq/result.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/result_traits.cpp b/src/lib/pq/result_traits.cpp index 5892384..198605c 100644 --- a/src/lib/pq/result_traits.cpp +++ b/src/lib/pq/result_traits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/result_traits_array.cpp b/src/lib/pq/result_traits_array.cpp index bc7db40..cc51297 100644 --- a/src/lib/pq/result_traits_array.cpp +++ b/src/lib/pq/result_traits_array.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/row.cpp b/src/lib/pq/row.cpp index 39432fe..7907fe7 100644 --- a/src/lib/pq/row.cpp +++ b/src/lib/pq/row.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/table_field.cpp b/src/lib/pq/table_field.cpp index cf53cff..5f5c584 100644 --- a/src/lib/pq/table_field.cpp +++ b/src/lib/pq/table_field.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/table_reader.cpp b/src/lib/pq/table_reader.cpp index c4647ae..4fd2797 100644 --- a/src/lib/pq/table_reader.cpp +++ b/src/lib/pq/table_reader.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/table_row.cpp b/src/lib/pq/table_row.cpp index 14b84db..5e4e5df 100644 --- a/src/lib/pq/table_row.cpp +++ b/src/lib/pq/table_row.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/table_writer.cpp b/src/lib/pq/table_writer.cpp index 9a2b976..6c0f6dc 100644 --- a/src/lib/pq/table_writer.cpp +++ b/src/lib/pq/table_writer.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/transaction.cpp b/src/lib/pq/transaction.cpp index b774802..ff78442 100644 --- a/src/lib/pq/transaction.cpp +++ b/src/lib/pq/transaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/lib/pq/transaction_base.cpp b/src/lib/pq/transaction_base.cpp index e187507..37cd7e9 100644 --- a/src/lib/pq/transaction_base.cpp +++ b/src/lib/pq/transaction_base.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/compare.hpp b/src/test/compare.hpp index 99db069..79b1210 100644 --- a/src/test/compare.hpp +++ b/src/test/compare.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/getenv.hpp b/src/test/getenv.hpp index 42f0dc0..bc730f8 100644 --- a/src/test/getenv.hpp +++ b/src/test/getenv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/macros.hpp b/src/test/macros.hpp index a1d37d3..6a71d4e 100644 --- a/src/test/macros.hpp +++ b/src/test/macros.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/aggregate.cpp b/src/test/pq/aggregate.cpp index b52f135..7716587 100644 --- a/src/test/pq/aggregate.cpp +++ b/src/test/pq/aggregate.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/array.cpp b/src/test/pq/array.cpp index f5a3acb..87247a0 100644 --- a/src/test/pq/array.cpp +++ b/src/test/pq/array.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/basic_datatypes.cpp b/src/test/pq/basic_datatypes.cpp index 4bd7948..1398d8a 100644 --- a/src/test/pq/basic_datatypes.cpp +++ b/src/test/pq/basic_datatypes.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/chunk_mode.cpp b/src/test/pq/chunk_mode.cpp index 67ae6a1..eb5dec6 100644 --- a/src/test/pq/chunk_mode.cpp +++ b/src/test/pq/chunk_mode.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/connection.cpp b/src/test/pq/connection.cpp index 104b84c..592f509 100644 --- a/src/test/pq/connection.cpp +++ b/src/test/pq/connection.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/connection_pool.cpp b/src/test/pq/connection_pool.cpp index 66c332a..045afc8 100644 --- a/src/test/pq/connection_pool.cpp +++ b/src/test/pq/connection_pool.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/example.cpp b/src/test/pq/example.cpp index f9bc488..c2849ac 100644 --- a/src/test/pq/example.cpp +++ b/src/test/pq/example.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/exception.cpp b/src/test/pq/exception.cpp index 691a3d0..3407a0f 100644 --- a/src/test/pq/exception.cpp +++ b/src/test/pq/exception.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/getenv.cpp b/src/test/pq/getenv.cpp index e900ea0..d70a8a6 100644 --- a/src/test/pq/getenv.cpp +++ b/src/test/pq/getenv.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/large_object.cpp b/src/test/pq/large_object.cpp index 988dcf1..c53eacf 100644 --- a/src/test/pq/large_object.cpp +++ b/src/test/pq/large_object.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index dc213cd..1100cd9 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/notifications.cpp b/src/test/pq/notifications.cpp index a6ec036..d9c002c 100644 --- a/src/test/pq/notifications.cpp +++ b/src/test/pq/notifications.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/parameter.cpp b/src/test/pq/parameter.cpp index 111c49c..38c8d0a 100644 --- a/src/test/pq/parameter.cpp +++ b/src/test/pq/parameter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/parameter_type.cpp b/src/test/pq/parameter_type.cpp index 0ce3e60..4a0d9b5 100644 --- a/src/test/pq/parameter_type.cpp +++ b/src/test/pq/parameter_type.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/password.cpp b/src/test/pq/password.cpp index 4a46095..75a5b1a 100644 --- a/src/test/pq/password.cpp +++ b/src/test/pq/password.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/pipeline_mode.cpp b/src/test/pq/pipeline_mode.cpp index ccca866..31e5465 100644 --- a/src/test/pq/pipeline_mode.cpp +++ b/src/test/pq/pipeline_mode.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2024-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/resize_uninitialized.cpp b/src/test/pq/resize_uninitialized.cpp index 7e51656..229f161 100644 --- a/src/test/pq/resize_uninitialized.cpp +++ b/src/test/pq/resize_uninitialized.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/result.cpp b/src/test/pq/result.cpp index 01dce31..09e72ca 100644 --- a/src/test/pq/result.cpp +++ b/src/test/pq/result.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/result_type.cpp b/src/test/pq/result_type.cpp index 20fd9c1..01f268b 100644 --- a/src/test/pq/result_type.cpp +++ b/src/test/pq/result_type.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2023-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/row.cpp b/src/test/pq/row.cpp index 3a73572..23af8d4 100644 --- a/src/test/pq/row.cpp +++ b/src/test/pq/row.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/single_row_mode.cpp b/src/test/pq/single_row_mode.cpp index 8e806b5..7d58b50 100644 --- a/src/test/pq/single_row_mode.cpp +++ b/src/test/pq/single_row_mode.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/strtox.cpp b/src/test/pq/strtox.cpp index 39a9d2a..b9c0b31 100644 --- a/src/test/pq/strtox.cpp +++ b/src/test/pq/strtox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/table_reader.cpp b/src/test/pq/table_reader.cpp index bcfa5c7..efb91bd 100644 --- a/src/test/pq/table_reader.cpp +++ b/src/test/pq/table_reader.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2021-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/table_writer.cpp b/src/test/pq/table_writer.cpp index de95574..7f77256 100644 --- a/src/test/pq/table_writer.cpp +++ b/src/test/pq/table_writer.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/traits.cpp b/src/test/pq/traits.cpp index f3e181c..ec05d1e 100644 --- a/src/test/pq/traits.cpp +++ b/src/test/pq/traits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2020-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) diff --git a/src/test/pq/transaction.cpp b/src/test/pq/transaction.cpp index 2706e01..23b3e82 100644 --- a/src/test/pq/transaction.cpp +++ b/src/test/pq/transaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2024 Daniel Frey and Dr. Colin Hirsch +// Copyright (c) 2016-2025 Daniel Frey and Dr. Colin Hirsch // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) From 73749016508b8023d5c9d3edf498e49aedda7a27 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Thu, 2 Jan 2025 21:44:30 +0100 Subject: [PATCH 14/17] Refactor rollback handling in dtor --- include/tao/pq/connection.hpp | 1 + include/tao/pq/log.hpp | 6 ++++- include/tao/pq/transaction.hpp | 2 ++ src/lib/pq/connection.cpp | 13 +---------- src/lib/pq/transaction.cpp | 42 ++++++++++++++++------------------ 5 files changed, 29 insertions(+), 35 deletions(-) diff --git a/include/tao/pq/connection.hpp b/include/tao/pq/connection.hpp index 4eb8bfd..a6c334d 100644 --- a/include/tao/pq/connection.hpp +++ b/include/tao/pq/connection.hpp @@ -54,6 +54,7 @@ namespace tao::pq friend class connection_pool; friend class table_reader; friend class table_writer; + friend class transaction; friend class transaction_base; friend class internal::top_level_transaction; diff --git a/include/tao/pq/log.hpp b/include/tao/pq/log.hpp index ed95661..e938c60 100644 --- a/include/tao/pq/log.hpp +++ b/include/tao/pq/log.hpp @@ -15,6 +15,7 @@ namespace tao::pq { class connection; + class transaction; struct log { @@ -120,7 +121,10 @@ namespace tao::pq struct transaction_t { - // TODO... + // check std::current_exception() for more information + using destructor_rollback_failed_t = std::function< void( transaction& ) >; // noexcept + + destructor_rollback_failed_t destructor_rollback_failed; } transaction; }; diff --git a/include/tao/pq/transaction.hpp b/include/tao/pq/transaction.hpp index 7c7febb..6e6500b 100644 --- a/include/tao/pq/transaction.hpp +++ b/include/tao/pq/transaction.hpp @@ -32,6 +32,8 @@ namespace tao::pq virtual void v_reset() noexcept = 0; + void rollback_in_dtor() noexcept; + public: [[nodiscard]] auto subtransaction() -> std::shared_ptr< transaction >; [[nodiscard]] auto pipeline() -> std::shared_ptr< pq::pipeline >; diff --git a/src/lib/pq/connection.cpp b/src/lib/pq/connection.cpp index 580580d..55a7c52 100644 --- a/src/lib/pq/connection.cpp +++ b/src/lib/pq/connection.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -137,17 +136,7 @@ namespace tao::pq ~top_level_transaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( const std::exception& ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing exception: " + std::string( e.what() ) ); - } - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing unknown exception" ); - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } diff --git a/src/lib/pq/transaction.cpp b/src/lib/pq/transaction.cpp index ff78442..aad8d0c 100644 --- a/src/lib/pq/transaction.cpp +++ b/src/lib/pq/transaction.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -33,17 +32,7 @@ namespace tao::pq ~top_level_subtransaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( const std::exception& ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing exception: " + std::string( e.what() ) ); - } - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TAO_LOG( WARNING, "unable to rollback transaction, swallowing unknown exception" ); - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } @@ -79,14 +68,7 @@ namespace tao::pq ~nested_subtransaction() override { if( m_connection && m_connection->attempt_rollback() ) { - try { - rollback(); - } - // LCOV_EXCL_START - catch( ... ) { // NOLINT(bugprone-empty-catch) - // TODO: How to handle this case properly? - } - // LCOV_EXCL_STOP + rollback_in_dtor(); } } @@ -130,8 +112,8 @@ namespace tao::pq void transaction::commit() { - check_current_transaction(); try { + check_current_transaction(); v_commit(); } // LCOV_EXCL_START @@ -145,8 +127,8 @@ namespace tao::pq void transaction::rollback() { - check_current_transaction(); try { + check_current_transaction(); v_rollback(); } // LCOV_EXCL_START @@ -158,4 +140,20 @@ namespace tao::pq v_reset(); } + void transaction::rollback_in_dtor() noexcept + { + try { + check_current_transaction(); + v_rollback(); + } + // LCOV_EXCL_START + catch( ... ) { + if( m_connection->m_log && m_connection->m_log->transaction.destructor_rollback_failed ) { + m_connection->m_log->transaction.destructor_rollback_failed( *this ); + } + } + // LCOV_EXCL_STOP + v_reset(); + } + } // namespace tao::pq From 3e6cf593845bc8a25450efbe73221873677ea0f7 Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Thu, 2 Jan 2025 22:32:51 +0100 Subject: [PATCH 15/17] Secure pipeline ctor --- include/tao/pq/pipeline.hpp | 12 +++++++++++- src/lib/pq/pipeline.cpp | 2 +- src/lib/pq/transaction.cpp | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/tao/pq/pipeline.hpp b/include/tao/pq/pipeline.hpp index 8bc5bf5..e938b70 100644 --- a/include/tao/pq/pipeline.hpp +++ b/include/tao/pq/pipeline.hpp @@ -13,6 +13,7 @@ namespace tao::pq { class connection; + class transaction; class pipeline : public transaction_base @@ -20,8 +21,17 @@ namespace tao::pq private: std::shared_ptr< transaction_base > m_previous; + friend class transaction; + + // pass-key idiom + class private_key final + { + private_key() = default; + friend class transaction; + }; + public: - explicit pipeline( const std::shared_ptr< pq::connection >& connection ); + pipeline( const private_key /*unused*/, const std::shared_ptr< pq::connection >& connection ); ~pipeline() override { diff --git a/src/lib/pq/pipeline.cpp b/src/lib/pq/pipeline.cpp index 3ce9669..2a1f170 100644 --- a/src/lib/pq/pipeline.cpp +++ b/src/lib/pq/pipeline.cpp @@ -10,7 +10,7 @@ namespace tao::pq { - pipeline::pipeline( const std::shared_ptr< pq::connection >& connection ) + pipeline::pipeline( const pipeline::private_key /*unused*/, const std::shared_ptr< pq::connection >& connection ) : transaction_base( connection ), m_previous( current_transaction()->shared_from_this() ) { diff --git a/src/lib/pq/transaction.cpp b/src/lib/pq/transaction.cpp index aad8d0c..e171dd9 100644 --- a/src/lib/pq/transaction.cpp +++ b/src/lib/pq/transaction.cpp @@ -107,7 +107,7 @@ namespace tao::pq auto transaction::pipeline() -> std::shared_ptr< pq::pipeline > { check_current_transaction(); - return std::make_shared< pq::pipeline >( m_connection ); + return std::make_shared< pq::pipeline >( pq::pipeline::private_key(), m_connection ); } void transaction::commit() From 0562721614d0575fb89cc76525eaaa849d3a13ff Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Sat, 4 Jan 2025 10:17:42 +0100 Subject: [PATCH 16/17] Use lambdas --- src/test/pq/log.cpp | 152 +++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 95 deletions(-) diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index 1100cd9..7cf93ac 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -20,87 +20,6 @@ namespace return std::chrono::duration_cast< std::chrono::milliseconds >( end - std::chrono::steady_clock::now() ).count(); } - void log_send_query( tao::pq::connection& c, const char* s, int n, const Oid types[], const char* const values[], const int lengths[], const int formats[] ) - { - std::ignore = types; - std::ignore = lengths; - std::ignore = formats; - std::cout << std::format( "send_query(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; - for( int i = 0; i != n; ++i ) { - std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; - } - } - - void log_send_query_result( tao::pq::connection& c, int r ) - { - std::cout << std::format( "send_query(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; - } - - void log_send_query_prepared( tao::pq::connection& c, const char* s, int n, const char* const values[], const int lengths[], const int formats[] ) - { - std::ignore = lengths; - std::ignore = formats; - std::cout << std::format( "send_query_prepared(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; - for( int i = 0; i != n; ++i ) { - std::cout << std::format( " parameter[{}]={})", i, values[ i ] ) << '\n'; - } - } - - void log_send_query_prepared_result( tao::pq::connection& c, int r ) - { - std::cout << std::format( "send_query_prepared(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; - } - - void log_wait( tao::pq::connection& c, bool w, std::chrono::steady_clock::time_point e ) - { - std::cout << std::format( "wait(connection={}, wait_for_write={}, timeout={}ms)", static_cast< const void* >( &c ), w, to_millis( e ) ) << '\n'; - } - - void log_poll( tao::pq::connection& c, int s, bool w, int t ) - { - std::cout << std::format( "poll(connection={},socket={}, wait_for_write={}, timeout={}ms)", static_cast< const void* >( &c ), s, w, t ) << '\n'; - } - - void log_poll_result( tao::pq::connection& c, int s, tao::pq::poll::status r ) - { - std::cout << std::format( "poll(connection={},socket={}) -> {}", static_cast< const void* >( &c ), s, r ) << '\n'; - } - - void log_is_busy_result( const tao::pq::connection& c, int r ) - { - std::cout << std::format( "is_busy(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; - } - - void log_consume_input( tao::pq::connection& c ) - { - std::cout << std::format( "consume_input(connection={})", static_cast< const void* >( &c ) ) << '\n'; - } - - void log_consume_input_result( tao::pq::connection& c, int r ) - { - std::cout << std::format( "consume_input(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; - } - - void log_flush( tao::pq::connection& c ) - { - std::cout << std::format( "flush(connection={})", static_cast< const void* >( &c ) ) << '\n'; - } - - void log_flush_result( tao::pq::connection& c, int r ) - { - std::cout << std::format( "flush(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; - } - - void log_get_result( tao::pq::connection& c, std::chrono::steady_clock::time_point e ) - { - std::cout << std::format( "get_result(connection={}, timeout={}ms)", static_cast< const void* >( &c ), to_millis( e ) ) << '\n'; - } - - void log_get_result_result( tao::pq::connection& c, PGresult* r ) - { - std::cout << std::format( "get_result(connection={}) -> {}", static_cast< const void* >( &c ), static_cast< const void* >( r ) ) << '\n'; - } - void run() { // overwrite the default with an environment variable if needed @@ -112,20 +31,63 @@ namespace // attach a log receiver const auto log = std::make_shared< tao::pq::log >(); - log->connection.send_query = log_send_query; - log->connection.send_query.result = log_send_query_result; - log->connection.send_query_prepared = log_send_query_prepared; - log->connection.send_query_prepared.result = log_send_query_prepared_result; - log->connection.wait = log_wait; - log->connection.poll = log_poll; - log->connection.poll.result = log_poll_result; - log->connection.is_busy.result = log_is_busy_result; - log->connection.consume_input = log_consume_input; - log->connection.consume_input.result = log_consume_input_result; - log->connection.flush = log_flush; - log->connection.flush.result = log_flush_result; - log->connection.get_result = log_get_result; - log->connection.get_result.result = log_get_result_result; + log->connection.send_query = []( tao::pq::connection& c, const char* s, int n, const Oid types[], const char* const values[], const int lengths[], const int formats[] ) { + std::ignore = types; + std::ignore = lengths; + std::ignore = formats; + std::cout << std::format( "send_query(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; + for( int i = 0; i != n; ++i ) { + std::cout << std::format( " parameter[{}]={}", i, values[ i ] ) << '\n'; + } + }; + log->connection.send_query.result = []( tao::pq::connection& c, int r ) { + std::cout << std::format( "send_query(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; + }; + log->connection.send_query_prepared = []( tao::pq::connection& c, const char* s, int n, const char* const values[], const int lengths[], const int formats[] ) { + std::ignore = lengths; + std::ignore = formats; + std::cout << std::format( "send_query_prepared(connection={}, statement={}, n_params={})", static_cast< const void* >( &c ), s, n ) << '\n'; + for( int i = 0; i != n; ++i ) { + std::cout << std::format( " parameter[{}]={}", i, values[ i ] ) << '\n'; + } + }; + log->connection.send_query_prepared.result = []( tao::pq::connection& c, int r ) { + std::cout << std::format( "send_query_prepared(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; + }; + log->connection.wait = []( tao::pq::connection& c, bool w, std::chrono::steady_clock::time_point e ) { + std::cout << std::format( "wait(connection={}, wait_for_write={}, timeout={} ms)", static_cast< const void* >( &c ), w, to_millis( e ) ) << '\n'; + }; + log->connection.poll = []( tao::pq::connection& c, int s, bool w, int t ) { + std::cout << std::format( "poll(connection={},socket={}, wait_for_write={}, timeout={} ms)", static_cast< const void* >( &c ), s, w, t ) << '\n'; + }; + log->connection.poll.result = []( tao::pq::connection& c, int s, tao::pq::poll::status r ) { + std::cout << std::format( "poll(connection={},socket={}) -> {}", static_cast< const void* >( &c ), s, r ) << '\n'; + }; + log->connection.is_busy.result = []( const tao::pq::connection& c, int r ) { + std::cout << std::format( "is_busy(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; + }; + log->connection.consume_input = []( tao::pq::connection& c ) { + std::cout << std::format( "consume_input(connection={})", static_cast< const void* >( &c ) ) << '\n'; + }; + log->connection.consume_input.result = []( tao::pq::connection& c, int r ) { + std::cout << std::format( "consume_input(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; + }; + log->connection.flush = []( tao::pq::connection& c ) { + std::cout << std::format( "flush(connection={})", static_cast< const void* >( &c ) ) << '\n'; + }; + log->connection.flush.result = []( tao::pq::connection& c, int r ) { + std::cout << std::format( "flush(connection={}) -> {}", static_cast< const void* >( &c ), r ) << '\n'; + }; + log->connection.get_result = []( tao::pq::connection& c, std::chrono::steady_clock::time_point e ) { + std::cout << std::format( "get_result(connection={}, timeout={} ms)", static_cast< const void* >( &c ), to_millis( e ) ) << '\n'; + }; + log->connection.get_result.result = []( tao::pq::connection& c, PGresult* r ) { + std::cout << std::format( "get_result(connection={}) -> {}", static_cast< const void* >( &c ), static_cast< const void* >( r ) ) << '\n'; + if( r ) { + std::cout << std::format( " columns={}, rows={}", PQnfields( r ), PQntuples( r ) ) << '\n'; + } + }; + conn->set_log_handler( log ); // execute statements From 5c4ec5f3cb0669ac16493d4fefd5d8314f5542de Mon Sep 17 00:00:00 2001 From: Daniel Frey Date: Sat, 4 Jan 2025 10:49:21 +0100 Subject: [PATCH 17/17] Improve result logging --- src/test/pq/log.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/pq/log.cpp b/src/test/pq/log.cpp index 7cf93ac..6dacd0b 100644 --- a/src/test/pq/log.cpp +++ b/src/test/pq/log.cpp @@ -83,8 +83,19 @@ namespace }; log->connection.get_result.result = []( tao::pq::connection& c, PGresult* r ) { std::cout << std::format( "get_result(connection={}) -> {}", static_cast< const void* >( &c ), static_cast< const void* >( r ) ) << '\n'; - if( r ) { - std::cout << std::format( " columns={}, rows={}", PQnfields( r ), PQntuples( r ) ) << '\n'; + if( r != nullptr ) { + const auto st = PQresultStatus( r ); + std::cout << std::format( " status={}", PQresStatus( st ) ) << '\n'; + const auto cols = PQnfields( r ); + if( cols != 0 ) { + std::cout << std::format( " columns={}, rows={}", cols, PQntuples( r ) ) << '\n'; + } + else { + const char* str = PQcmdTuples( r ); + if( str[ 0 ] != '\0' ) { + std::cout << std::format( " rows_affected={}", str ) << '\n'; + } + } } };