Skip to content

Commit c8eb66b

Browse files
Add Support for multiple Database Connections to CWF::SqlDatabaseStorage
with the old implementation there was a issue where you could really only use one database with CWF::SqlDatabaseStorage in you're application. This was due to the fact that CWF::SqlDatabaseStorage::getDatabase would always return the first database connection created on the executing thread. It would possibly ignore Configuration given to CWF::SqlDatabaseStorage which a user might not expect. This patch fixes that. It replaces the internal pointer to QSqldatabase with two maps. One maps the application-database-connection names to unique-database-connection-names. The second map maps unique-database-connection-names to pointers to QSqldatabase objects. Also logic was added to to return the correct database-connection as well as cleanup code when the thread would exit.
1 parent 485f051 commit c8eb66b

File tree

1 file changed

+75
-63
lines changed

1 file changed

+75
-63
lines changed

CPPWebFramework/cwf/sqldatabasestorage.h

Lines changed: 75 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,38 @@ class CPPWEBFRAMEWORKSHARED_EXPORT SqlDatabaseStorage
3131
class Database
3232
{
3333
friend class SqlDatabaseStorage;
34-
//Map database connection names the library user uses to database connection names
35-
//which are valid for this thread
36-
std::map<QString, QString> trivialNameToUniqueID;
37-
#if __cplusplus == 201402L
38-
std::experimental::optional<QSqlDatabase> DBConnection; //C++ 14 Compatablity
39-
#endif
40-
#if __cplusplus >= 201703L
41-
std::optional<QSqlDatabase> DBConnection;
42-
#endif
34+
// Map database connection names the library user uses to database connection names
35+
// which are valid for this thread
36+
std::map<QString, QSqlDatabase*> DatabaseConnections; //Unique Name to Heap allocated Connection
37+
std::map<QString, QString> trivialNameToUniqueID; //Names given by User to Unique Name
38+
//#if __cplusplus == 201402L
39+
// std::experimental::optional<QSqlDatabase> DBConnection; //C++ 14 Compatablity
40+
//#endif
41+
//#if __cplusplus >= 201703L
42+
// std::optional<QSqlDatabase> DBConnection;
43+
//#endif
4344
public:
4445
Database() = default;
4546
Database(Database &other)
4647
{
47-
DBConnection = other.DBConnection;
48+
DatabaseConnections = other.DatabaseConnections;
4849
trivialNameToUniqueID = other.trivialNameToUniqueID;
4950
qDebug() << "Database Constructed";
5051
}
5152
~Database()
5253
{
5354
qDebug() << "Database Destructed";
54-
if(DBConnection)
55-
{
56-
const QString conName(DBConnection->connectionName());
57-
58-
DBConnection->close();
59-
//Remove all Database connnections this thread has and which will become invalid
60-
for (auto const & ConnectionNamePair : trivialNameToUniqueID) {
61-
DBConnection = QSqlDatabase::database(ConnectionNamePair.second, false);
55+
if (!DatabaseConnections.empty()) {
56+
// const QString conName(DBConnection->connectionName());
57+
58+
// Remove all Database connnections this thread has and which will become invalid
59+
for (auto const & ConnectionNamePair : DatabaseConnections) {
60+
auto DBConnection = ConnectionNamePair.second;
6261
DBConnection->close();
63-
qDebug() << ConnectionNamePair.first << ConnectionNamePair.second;
64-
QSqlDatabase::removeDatabase(ConnectionNamePair.second);
62+
delete DBConnection;
63+
qDebug() << "" << ConnectionNamePair.first
64+
<< "" << ConnectionNamePair.second;
65+
QSqlDatabase::removeDatabase(ConnectionNamePair.first);
6566
}
6667
}
6768
}
@@ -131,64 +132,75 @@ class CPPWEBFRAMEWORKSHARED_EXPORT SqlDatabaseStorage
131132
{
132133
Database database;
133134
QString UniqueID = QUuid::createUuid().toString();
134-
database.DBConnection = QSqlDatabase(QSqlDatabase::addDatabase(type, UniqueID));
135-
database.DBConnection->setHostName(hostName);
136-
database.DBConnection->setDatabaseName(databaseName);
137-
database.DBConnection->setPort(port);
138-
database.DBConnection->setUserName(userName);
139-
database.DBConnection->setPassword(password);
140-
if (!database.DBConnection->open()) {
141-
qDebug() << database.DBConnection->lastError().text();
135+
auto DBConnection = new QSqlDatabase(QSqlDatabase::addDatabase(type, UniqueID));
136+
DBConnection->setHostName(hostName);
137+
DBConnection->setDatabaseName(databaseName);
138+
DBConnection->setPort(port);
139+
DBConnection->setUserName(userName);
140+
DBConnection->setPassword(password);
141+
if (!DBConnection->open()) {
142+
qDebug() << DBConnection->lastError().text();
143+
std::cout << "Database not openable \t"
144+
<< databaseName.toStdString()
145+
<< "\n";
142146
}
147+
143148
pool.setLocalData(database);
149+
pool.localData().DatabaseConnections.insert({UniqueID, DBConnection});
144150
pool.localData().trivialNameToUniqueID.insert({databaseName, UniqueID});
145151
} else { //Pool has Local Data
146-
auto PublicDBName = pool.localData().trivialNameToUniqueID.find(databaseName);
152+
auto IteratorToUserDatabaseName = pool.localData().trivialNameToUniqueID.find(databaseName);
147153
QString NameOfDBConnectionToThread;
148154
QString UniqueConnectionName;
149155

150-
if (PublicDBName != pool.localData().trivialNameToUniqueID.end()) {
156+
if (IteratorToUserDatabaseName != pool.localData().trivialNameToUniqueID.end()) {
151157
// this thread has a Connection to the Database
152-
if (PublicDBName->second == pool.localData().DBConnection->connectionName()) {
153-
//already right connection
154-
} else {
155-
//set the right connection
156-
NameOfDBConnectionToThread = PublicDBName->first;
157-
UniqueConnectionName = PublicDBName->second;
158-
//pool.localData().DBConnection->close();
159-
pool.localData().DBConnection = QSqlDatabase::database(UniqueConnectionName, false);
160-
pool.localData().DBConnection->setHostName(hostName);
161-
pool.localData().DBConnection->setDatabaseName(databaseName);
162-
pool.localData().DBConnection->setPort(port);
163-
pool.localData().DBConnection->setUserName(userName);
164-
pool.localData().DBConnection->setPassword(password);
165-
if(!pool.localData().DBConnection->open()) {
166-
qDebug() << pool.localData().DBConnection->lastError().text();
167-
}
168-
}
158+
// if (PublicDBName->second == pool.localData().DBConnection->connectionName()) {
159+
// //already right connection
160+
// } else {
161+
// //set the right connection
162+
// NameOfDBConnectionToThread = IteratorToUserDatabaseName->first;
163+
// UniqueConnectionName = IteratorToUserDatabaseName->second;
164+
// //pool.localData().DBConnection->close();
165+
// pool.localData().DBConnection = QSqlDatabase::database(UniqueConnectionName, false);
166+
// pool.localData().DBConnection->setHostName(hostName);
167+
// pool.localData().DBConnection->setDatabaseName(databaseName);
168+
// pool.localData().DBConnection->setPort(port);
169+
// pool.localData().DBConnection->setUserName(userName);
170+
// pool.localData().DBConnection->setPassword(password);
171+
// if(!pool.localData().DBConnection->open()) {
172+
// qDebug() << pool.localData().DBConnection->lastError().text();
173+
// }
174+
// }
169175
} else {
170176
//make new Database connection for this thread
171177
QString UniqueID = QUuid::createUuid().toString();
172-
pool.localData().DBConnection->close();
173-
pool.localData().DBConnection = QSqlDatabase(QSqlDatabase::addDatabase(type, UniqueID));
174-
pool.localData().DBConnection->setHostName(hostName);
175-
pool.localData().DBConnection->setDatabaseName(databaseName);
176-
pool.localData().DBConnection->setPort(port);
177-
pool.localData().DBConnection->setUserName(userName);
178-
pool.localData().DBConnection->setPassword(password);
179-
if (!pool.localData().DBConnection->open()) {
180-
qDebug() << pool.localData().DBConnection->lastError().text();
178+
179+
auto DBConnection =new QSqlDatabase(QSqlDatabase::addDatabase(type, UniqueID));
180+
DBConnection->setHostName(hostName);
181+
DBConnection->setDatabaseName(databaseName);
182+
DBConnection->setPort(port);
183+
DBConnection->setUserName(userName);
184+
DBConnection->setPassword(password);
185+
if (!DBConnection->open()) {
186+
qDebug() << DBConnection->lastError().text();
187+
std::cout << "Database not openable \t"
188+
<< databaseName.toStdString()
189+
<< "\n";
181190
}
191+
pool.localData().DatabaseConnections.insert({UniqueID, DBConnection});
182192
pool.localData().trivialNameToUniqueID.insert({databaseName, UniqueID});
183193
}
184194
}
185-
std::cerr << "Name To ID Mapping";
186-
for ( auto const & foo : pool.localData().trivialNameToUniqueID) {
187-
std::cerr << "Name " << foo.first.toStdString()
188-
<< "\tID " << foo.second.toStdString()
189-
<< "\n";
190-
}
191-
return pool.localData().DBConnection.value();
195+
// std::cerr << "Name To ID Mapping";
196+
// for ( auto const & foo : pool.localData().trivialNameToUniqueID) {
197+
// std::cerr << "Name " << foo.first.toStdString()
198+
// << "\tID " << foo.second.toStdString()
199+
// << "\n";
200+
// }
201+
auto UniqueName = pool.localData().trivialNameToUniqueID.at(databaseName);
202+
return *pool.localData().DatabaseConnections.at(UniqueName);
203+
//
192204
}
193205
};
194206

0 commit comments

Comments
 (0)