diff --git a/src/core/providers/qgssqlconnpool.h b/src/core/providers/qgssqlconnpool.h index 00b3baa99054..200abc4a721c 100644 --- a/src/core/providers/qgssqlconnpool.h +++ b/src/core/providers/qgssqlconnpool.h @@ -97,6 +97,21 @@ class QgsSqlConnectionPool : public QgsConnectionPool sInstance = nullptr; } + + /** + * Call instance and acquire a connection, return a shared pointer with a destructor + * that will call the connection pool instance's release of the connection. + */ + static std::shared_ptr getConnectionFromInstance( const QString &connInfo ) + { + return std::shared_ptr( instance()->acquireConnection( connInfo ), + []( T * connection ) + { + if ( connection ) + instance()->releaseConnection( connection ); + } ); + } + QString connectionToName( T *connection ) override { return connection->connInfo(); diff --git a/src/providers/postgres/qgspostgresconn.cpp b/src/providers/postgres/qgspostgresconn.cpp index 6c8491ab7ce3..ad2c3a7c40c4 100644 --- a/src/providers/postgres/qgspostgresconn.cpp +++ b/src/providers/postgres/qgspostgresconn.cpp @@ -49,18 +49,6 @@ const int PG_DEFAULT_TIMEOUT = 30; -QgsPoolPostgresConn::QgsPoolPostgresConn( const QString &connInfo ) - : mPgConn( QgsPostgresConnPool::instance()->acquireConnection( connInfo ) ) -{ -} - -QgsPoolPostgresConn::~QgsPoolPostgresConn() -{ - if ( mPgConn ) - QgsPostgresConnPool::instance()->releaseConnection( mPgConn ); -} - - QMap QgsPostgresConn::sConnectionsRO; QMap QgsPostgresConn::sConnectionsRW; diff --git a/src/providers/postgres/qgspostgresconn.h b/src/providers/postgres/qgspostgresconn.h index 7783406006ec..09e9598e9288 100644 --- a/src/providers/postgres/qgspostgresconn.h +++ b/src/providers/postgres/qgspostgresconn.h @@ -153,18 +153,6 @@ struct QgsPostgresLayerProperty #endif }; -//! Wraps acquireConnection() and releaseConnection() from a QgsPostgresConnPool. -// This can be used for creating std::shared_ptr. -class QgsPoolPostgresConn -{ - class QgsPostgresConn *mPgConn; - public: - QgsPoolPostgresConn( const QString &connInfo ); - ~QgsPoolPostgresConn(); - - class QgsPostgresConn *get() const { return mPgConn; } -}; - #include "qgsconfig.h" constexpr int sPostgresConQueryLogFilePrefixLength = CMAKE_SOURCE_DIR[sizeof( CMAKE_SOURCE_DIR ) - 1] == '/' ? sizeof( CMAKE_SOURCE_DIR ) + 1 : sizeof( CMAKE_SOURCE_DIR ); #define LoggedPQexecNR(_class, query) PQexecNR( query, _class, QString(QString( __FILE__ ).mid( sPostgresConQueryLogFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + ")") ) diff --git a/src/providers/postgres/qgspostgresproviderconnection.cpp b/src/providers/postgres/qgspostgresproviderconnection.cpp index a243110856f2..0cc16cd64c5d 100644 --- a/src/providers/postgres/qgspostgresproviderconnection.cpp +++ b/src/providers/postgres/qgspostgresproviderconnection.cpp @@ -261,17 +261,13 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection return execSqlPrivate( sql, true, feedback ); } -QList QgsPostgresProviderConnection::executeSqlPrivate( const QString &sql, bool resolveTypes, QgsFeedback *feedback, std::shared_ptr pgconn ) const +QList QgsPostgresProviderConnection::executeSqlPrivate( const QString &sql, bool resolveTypes, QgsFeedback *feedback, std::shared_ptr pgconn ) const { return execSqlPrivate( sql, resolveTypes, feedback, pgconn ).rows(); } -QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection::execSqlPrivate( const QString &sql, bool resolveTypes, QgsFeedback *feedback, std::shared_ptr pgconn ) const +QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection::execSqlPrivate( const QString &sql, bool resolveTypes, QgsFeedback *feedback, std::shared_ptr pgconn ) const { - if ( ! pgconn ) - { - pgconn = std::make_shared( QgsDataSourceUri( uri() ).connectionInfo( false ) ); - } std::shared_ptr iterator = std::make_shared( resolveTypes ); QueryResult results( iterator ); @@ -282,9 +278,9 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection return results; } - QgsPostgresConn *conn = pgconn->get(); + pgconn = QgsPostgresConnPool::getConnectionFromInstance( QgsDataSourceUri( uri() ).connectionInfo( false ) ); - if ( ! conn ) + if ( ! pgconn ) { throw QgsProviderConnectionException( QObject::tr( "Connection failed: %1" ).arg( uri() ) ); } @@ -303,12 +299,12 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection qtConnection = QObject::connect( feedback, &QgsFeedback::canceled, [ &pgconn ] { if ( pgconn ) - pgconn->get()->PQCancel(); + pgconn->PQCancel(); } ); } std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - std::unique_ptr res = std::make_unique( conn->LoggedPQexec( "QgsPostgresProviderConnection", sql ) ); + std::unique_ptr res = std::make_unique( pgconn->LoggedPQexec( "QgsPostgresProviderConnection", sql ) ); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); results.setQueryExecutionTime( std::chrono::duration_cast( end - begin ).count() ); @@ -318,20 +314,20 @@ QgsAbstractDatabaseProviderConnection::QueryResult QgsPostgresProviderConnection } QString errCause; - if ( conn->PQstatus() != CONNECTION_OK || ! res->result() ) + if ( pgconn->PQstatus() != CONNECTION_OK || ! res->result() ) { errCause = QObject::tr( "Connection error: %1 returned %2 [%3]" ) - .arg( sql ).arg( conn->PQstatus() ) - .arg( conn->PQerrorMessage() ); + .arg( sql ).arg( pgconn->PQstatus() ) + .arg( pgconn->PQerrorMessage() ); } else { - const QString err { conn->PQerrorMessage() }; + const QString err { pgconn->PQerrorMessage() }; if ( ! err.isEmpty() ) { errCause = QObject::tr( "SQL error: %1 returned %2 [%3]" ) .arg( sql ) - .arg( conn->PQstatus() ) + .arg( pgconn->PQstatus() ) .arg( err ); } } diff --git a/src/providers/postgres/qgspostgresproviderconnection.h b/src/providers/postgres/qgspostgresproviderconnection.h index e8a3a116c163..c3bbb551c765 100644 --- a/src/providers/postgres/qgspostgresproviderconnection.h +++ b/src/providers/postgres/qgspostgresproviderconnection.h @@ -86,8 +86,8 @@ class QgsPostgresProviderConnection : public QgsAbstractDatabaseProviderConnecti private: - QList executeSqlPrivate( const QString &sql, bool resolveTypes = true, QgsFeedback *feedback = nullptr, std::shared_ptr< class QgsPoolPostgresConn > pgconn = nullptr ) const; - QgsAbstractDatabaseProviderConnection::QueryResult execSqlPrivate( const QString &sql, bool resolveTypes = true, QgsFeedback *feedback = nullptr, std::shared_ptr< class QgsPoolPostgresConn > pgconn = nullptr ) const; + QList executeSqlPrivate( const QString &sql, bool resolveTypes = true, QgsFeedback *feedback = nullptr, std::shared_ptr< class QgsPostgresConn > pgconn = nullptr ) const; + QgsAbstractDatabaseProviderConnection::QueryResult execSqlPrivate( const QString &sql, bool resolveTypes = true, QgsFeedback *feedback = nullptr, std::shared_ptr< class QgsPostgresConn > pgconn = nullptr ) const; void setDefaultCapabilities(); void dropTablePrivate( const QString &schema, const QString &name ) const; void renameTablePrivate( const QString &schema, const QString &name, const QString &newName ) const;