77
88#ifndef  SQLDATABASESTORAGE_H
99#define  SQLDATABASESTORAGE_H 
10- 
10+ # include   < iostream > 
1111#include  < QUuid> 
1212#include  < QDebug> 
1313#include  < QSqlError> 
1414#include  < QSqlDatabase> 
1515#include  < QThreadStorage> 
1616#include  " cppwebframework_global.h" 
1717
18+ #if  __cplusplus >= 201703L
19+ #include  < optional> 
20+ #endif 
21+ #if  __cplusplus == 201402L
22+ #include  < experimental/optional> 
23+ #endif 
1824CWF_BEGIN_NAMESPACE
1925/* *
2026 * @brief The SqlDatabaseStorage class allows you to reuse connections made to the database through the QSqlDatabase class within QThreadPool. 
2127 */  
28+ 
2229class  CPPWEBFRAMEWORKSHARED_EXPORT  SqlDatabaseStorage
2330{    
2431    class  Database 
2532    {
2633        friend  class  SqlDatabaseStorage ;
27-         QSqlDatabase *db = nullptr ;
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
2844    public: 
2945        Database () = default ;
3046        Database (Database &other)
3147        {
32-             db = other.db ;
33-             other.db  = nullptr ;
48+             DatabaseConnections = other.DatabaseConnections ;
49+             trivialNameToUniqueID = other.trivialNameToUniqueID ;
50+             qDebug () << " Database Constructed"  ;
3451        }
3552        ~Database ()
3653        {
37-             if (db)
38-             {
39-                 const  QString conName (db->connectionName ());
40-                 db->close ();
41-                 delete  db;
42-                 QSqlDatabase::removeDatabase (conName);
54+             qDebug () << " Database Destructed"  ;
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 ;
61+                     DBConnection->close ();
62+                     delete  DBConnection;
63+                     qDebug () << " "   << ConnectionNamePair.first 
64+                              << " "   << ConnectionNamePair.second ;
65+                     QSqlDatabase::removeDatabase (ConnectionNamePair.first );
66+                 }
4367            }
4468        }
4569    };
@@ -50,6 +74,7 @@ class CPPWEBFRAMEWORKSHARED_EXPORT SqlDatabaseStorage
5074    QString password;
5175    int  port;
5276    QThreadStorage<Database> pool;
77+ 
5378public: 
5479    /* *
5580     * @brief This constructor receives informations to create a connection to the database. 
@@ -103,20 +128,79 @@ class CPPWEBFRAMEWORKSHARED_EXPORT SqlDatabaseStorage
103128     */  
104129    QSqlDatabase &getDatabase ()
105130    {
106-         if (!pool.hasLocalData ())
131+         if (!pool.hasLocalData ())  // Pool has no Local Data -> create DataBaseConnection 
107132        {
108133            Database database;
109-             database.db  = new  QSqlDatabase (QSqlDatabase::addDatabase (type, QUuid::createUuid ().toString ()));
110-             database.db ->setHostName (hostName);
111-             database.db ->setDatabaseName (databaseName);
112-             database.db ->setPort (port);
113-             database.db ->setUserName (userName);
114-             database.db ->setPassword (password);
115-             if (!database.db ->open ())
116-                 qDebug () << database.db ->lastError ().text ();
134+             QString UniqueID = QUuid::createUuid ().toString ();
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 "  ;
146+             }
147+ 
117148            pool.setLocalData (database);
149+             pool.localData ().DatabaseConnections .insert ({UniqueID, DBConnection});
150+             pool.localData ().trivialNameToUniqueID .insert ({databaseName, UniqueID});
151+         } else  { // Pool has Local Data
152+             auto  IteratorToUserDatabaseName = pool.localData ().trivialNameToUniqueID .find (databaseName);
153+             QString NameOfDBConnectionToThread;
154+             QString UniqueConnectionName;
155+ 
156+             if  (IteratorToUserDatabaseName != pool.localData ().trivialNameToUniqueID .end ()) {
157+                 //  this thread has a Connection to the Database
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+ //                 }
175+             } else  {
176+                 // make new Database connection for this thread
177+                 QString UniqueID = QUuid::createUuid ().toString ();
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 "  ;
190+                 }
191+                 pool.localData ().DatabaseConnections .insert ({UniqueID, DBConnection});
192+                 pool.localData ().trivialNameToUniqueID .insert ({databaseName, UniqueID});
193+             }
118194        }
119-         return  *pool.localData ().db ;
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+         // 
120204    }
121205};
122206
0 commit comments