Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "ConcurrentSqlDatabaseFactory.h"
- #include "../Exceptions/OpenDatabase.h"
- #include <QReadWriteLock>
- #include <QThread>
- Q_LOGGING_CATEGORY( sqlDatabaseFactory, "sqlDatabaseFactory" )
- namespace Atm { namespace DbProvider { namespace Concurrent {
- SqlDatabaseFactory::SqlDatabaseFactory( QObject * parent )
- : SqlDatabaseFactory( ConnectionParameters(), parent )
- {}
- SqlDatabaseFactory::SqlDatabaseFactory( const ConnectionParameters & connectionParameters, QObject * parent )
- : QObject( parent )
- , m_connectionParameters( connectionParameters )
- , m_lock( std::make_unique<QReadWriteLock>() )
- {}
- SqlDatabaseFactory::~SqlDatabaseFactory() = default;
- const ConnectionParameters & SqlDatabaseFactory::connectionParameters() const
- {
- return m_connectionParameters;
- }
- void SqlDatabaseFactory::setConnectionParameters( const ConnectionParameters & connectionParameters )
- {
- m_connectionParameters = connectionParameters;
- }
- QSqlDatabase SqlDatabaseFactory::getSqlDatabase()
- {
- Qt::HANDLE threadId = QThread::currentThreadId();
- bool isExists = false;
- QSqlDatabase sqlDatabase;
- m_lock->lockForRead();
- bool isThreadInitialized = m_threadConnections.contains( threadId );
- if ( m_connectionNames.contains( threadId ) ) {
- isExists = true;
- sqlDatabase = QSqlDatabase::database( m_connectionNames[threadId], false );
- }
- m_lock->unlock();
- if ( isExists ) {
- bool connectionWasClosed = !sqlDatabase.isOpen();
- bool connectionParametersWasChanged =
- m_connectionParameters != ConnectionParameters::fromSqlDatabase( sqlDatabase );
- if ( connectionWasClosed || connectionParametersWasChanged ) {
- if ( connectionParametersWasChanged ) {
- if ( !connectionWasClosed ) {
- sqlDatabase.close();
- }
- sqlDatabase = m_connectionParameters.createSqlDatabase( getConnectionName( threadId ) );
- }
- if ( sqlDatabase.open() ) {
- qCDebug( sqlDatabaseFactory ).noquote()
- << reconnectionComment( threadId, connectionWasClosed, connectionParametersWasChanged );
- } else {
- throw Exceptions::OpenDatabase( sqlDatabase.lastError() );
- }
- } else {
- qCDebug( sqlDatabaseFactory ) << "Exists database connection was returned for thread " << threadId;
- }
- return sqlDatabase;
- } else {
- const QString connectionName = getConnectionName( threadId );
- sqlDatabase = m_connectionParameters.createSqlDatabase( connectionName );
- if ( !sqlDatabase.open() ) {
- throw Exceptions::OpenDatabase( sqlDatabase.lastError() );
- }
- m_lock->lockForWrite();
- m_connectionNames.insert( threadId, connectionName );
- if ( !isThreadInitialized ) {
- QMetaObject::Connection connection =
- QObject::connect( QThread::currentThread(), &QThread::finished, [threadId, this]() {
- m_lock->lockForRead();
- QString connectionName = m_connectionNames.value( threadId );
- QMetaObject::Connection connection = m_threadConnections.value( threadId );
- m_lock->unlock();
- if ( !connectionName.isNull() ) {
- QSqlDatabase sqlDatabase = QSqlDatabase::database( connectionName );
- if ( sqlDatabase.isOpen() ) {
- sqlDatabase.close();
- sqlDatabase = QSqlDatabase();
- qCDebug( sqlDatabaseFactory ).noquote()
- << QString( "Thread %1 was finished, close database connection \"%2\"" )
- .arg( threadIdToString( threadId ) )
- .arg( connectionName );
- } else {
- qCDebug( sqlDatabaseFactory ).noquote()
- << QString( "Thread %1 was finished, database connection \"%2\" is closed already." )
- .arg( threadIdToString( threadId ) )
- .arg( connectionName );
- }
- QSqlDatabase::removeDatabase( connectionName );
- m_lock->lockForWrite();
- m_connectionNames.remove( threadId );
- m_threadConnections.remove( threadId );
- m_lock->unlock();
- QObject::disconnect( connection );
- }
- } );
- m_threadConnections.insert( threadId, connection );
- }
- m_lock->unlock();
- qCDebug( sqlDatabaseFactory ) << "New database connection was created for thread " << threadId;
- }
- return sqlDatabase;
- }
- void SqlDatabaseFactory::removeSqlDatabase()
- {}
- QString SqlDatabaseFactory::threadIdToString( Qt::HANDLE threadId ) const
- {
- return QString( "0x%1" ).arg( ulong( threadId ), 0, 16 );
- }
- QString SqlDatabaseFactory::getConnectionName( Qt::HANDLE threadId ) const
- {
- return QString( "SqlDatabaseFactory_%1" ).arg( ulong( threadId ), 0, 16 );
- }
- QString SqlDatabaseFactory::reconnectionComment( Qt::HANDLE threadId,
- bool connectionWasClosed,
- bool connectionParametersWasChanged ) const
- {
- QString cause;
- if ( connectionWasClosed ) {
- cause.append( "connection was closed" );
- }
- if ( connectionWasClosed && connectionParametersWasChanged ) {
- cause.append( " and " );
- }
- if ( connectionParametersWasChanged ) {
- cause.append( "database parameters was changed" );
- }
- return QString( "Old database connection for thread %1 was created reopened, because %2" )
- .arg( threadIdToString( threadId ) )
- .arg( cause );
- }
- }}} // namespace Atm::DbProvider::Concurrent
Add Comment
Please, Sign In to add comment