MythTV  master
mythdbcon.h
Go to the documentation of this file.
1 #ifndef MYTHDBCON_H_
2 #define MYTHDBCON_H_
3 
4 #include <QSqlDatabase>
5 #include <QSqlRecord>
6 #include <QSqlError>
7 #include <QVariant>
8 #include <QSqlQuery>
9 #include <QDateTime>
10 #include <QMutex>
11 #include <QList>
12 
13 #include "mythbaseexp.h"
14 #include "mythdbparams.h"
15 
16 #define REUSE_CONNECTION 1 // NOLINT(cppcoreguidelines-macro-usage)
17 
18 MBASE_PUBLIC bool TestDatabase(const QString& dbHostName,
19  const QString& dbUserName,
20  QString dbPassword,
21  QString dbName = "mythconverg",
22  int dbPort = 3306);
23 
26 {
27  friend class MDBManager;
28  friend class MSqlQuery;
29  public:
30  explicit MSqlDatabase(QString name, QString driver = "QMYSQL");
31  ~MSqlDatabase(void);
32 
33  bool OpenDatabase(bool skipdb = false);
34  void SetDBParams(const DatabaseParams &params) { m_dbparms = params; };
35 
36  private:
37  Q_DISABLE_COPY_MOVE(MSqlDatabase)
38  bool isOpen(void);
39  bool KickDatabase(void);
40  QString GetConnectionName(void) const { return m_name; }
41  QSqlDatabase db(void) const { return m_db; }
42  bool Reconnect(void);
43  void InitSessionVars(void);
44 
45  private:
46  QString m_name;
47  QString m_driver;
48  QSqlDatabase m_db;
49  QDateTime m_lastDBKick;
51 };
52 
55 {
56  friend class MSqlQuery;
57  public:
58  MDBManager(void) = default;
59  ~MDBManager(void);
60 
61  void CloseDatabases(void);
62  void PurgeIdleConnections(bool leaveOne = false);
63 
64  protected:
65  MSqlDatabase *popConnection(bool reuse);
66  void pushConnection(MSqlDatabase *db);
67 
68  MSqlDatabase *getSchedCon(void);
69  MSqlDatabase *getChannelCon(void);
70 
71  private:
72  Q_DISABLE_COPY_MOVE(MDBManager)
73  MSqlDatabase *getStaticCon(MSqlDatabase **dbcon, const QString& name);
74 
75  QMutex m_lock;
76  using DBList = QList<MSqlDatabase*>;
77  QHash<QThread*, DBList> m_pool; // protected by m_lock
78 #if REUSE_CONNECTION
79  QHash<QThread*, MSqlDatabase*> m_inuse; // protected by m_lock
80  QHash<QThread*, int> m_inuseCount; // protected by m_lock
81 #endif
82 
83  int m_nextConnID {0};
84  int m_connCount {0};
85 
86  MSqlDatabase *m_schedCon {nullptr};
87  MSqlDatabase *m_channelCon {nullptr};
88  QHash<QThread*, DBList> m_staticPool;
89 };
90 
93 {
94  MSqlDatabase *db {nullptr};
95  QSqlDatabase qsqldb;
96  bool returnConnection {false};
97 };
98 
100 using MSqlBindings = QMap<QString, QVariant>;
101 
104 
106  MBASE_PUBLIC void MSqlEscapeAsAQuery(QString &query, const MSqlBindings &bindings);
107 
127 class MBASE_PUBLIC MSqlQuery : private QSqlQuery
128 {
129  MBASE_PUBLIC friend void MSqlEscapeAsAQuery(QString& query, MSqlBindings& bindings);
130  public:
132  explicit MSqlQuery(const MSqlQueryInfo &qi);
134  ~MSqlQuery();
135 
137  bool isConnected(void) const { return m_isConnected; }
138 
140  bool exec(void);
141 
143  bool next(void);
144 
146  bool previous(void);
147 
149  bool first(void);
150 
152  bool last(void);
153 
155  // so we can display the query results
156  bool seek(int where, bool relative = false);
157 
159  bool exec(const QString &query);
160 
162  bool prepare(const QString &query);
163 
165  void bindValue(const QString &placeholder, const QVariant &val);
166 
180  void bindValueNoNull(const QString &placeholder, const QVariant &val);
181 
183  void bindValues(const MSqlBindings &bindings);
184 
193  QVariant lastInsertId();
194 
197  bool Reconnect(void);
198 
201  bool lostConnectionCheck(void);
202 
203  // Thunks that allow us to make QSqlQuery private
204  QVariant value(int i) const { return QSqlQuery::value(i); }
205  QString executedQuery(void) const { return QSqlQuery::executedQuery(); }
206 
207 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
208  QMap<QString, QVariant> boundValues(void) const
209  { return QSqlQuery::boundValues(); }
210 #else
211  QVariantList boundValues(void) const { return QSqlQuery::boundValues(); }
212 #endif
213  QSqlError lastError(void) const { return QSqlQuery::lastError(); }
214  int size(void) const { return QSqlQuery::size();}
215  bool isActive(void) const { return QSqlQuery::isActive(); }
216  QSqlRecord record(void) const { return QSqlQuery::record(); }
217  int numRowsAffected() const { return QSqlQuery::numRowsAffected(); }
218  void setForwardOnly(bool f) { QSqlQuery::setForwardOnly(f); }
219  bool isNull(int field) const { return QSqlQuery::isNull(field); }
220  const QSqlDriver *driver(void) const { return QSqlQuery::driver(); }
221  int at(void) const { return QSqlQuery::at(); }
222 
224  static bool testDBConnection();
225 
226  enum ConnectionReuse : std::uint8_t
227  {
230  };
232  static MSqlQueryInfo InitCon(ConnectionReuse _reuse = kNormalConnection);
233 
235  static MSqlQueryInfo SchedCon();
236 
238  static MSqlQueryInfo ChannelCon();
239 
240  private:
241  Q_DISABLE_COPY_MOVE(MSqlQuery)
242 
243  // Only QSql::In is supported as a param type and only named params...
244  void bindValue(const QString&, const QVariant&, QSql::ParamType);
245  void bindValue(int, const QVariant&, QSql::ParamType);
246  void addBindValue(const QVariant&, QSql::ParamType = QSql::In);
247 
248  bool seekDebug(const char *type, bool result,
249  int where, bool relative) const;
250 
251  MSqlDatabase *m_db {nullptr};
252  bool m_isConnected {false};
253  bool m_returnConnection {false};
254  QString m_lastPreparedQuery; // holds a copy of the last prepared query
255 };
256 
257 #endif
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:100
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
MDBManager::m_lock
QMutex m_lock
Definition: mythdbcon.h:75
MSqlQuery::isNull
bool isNull(int field) const
Definition: mythdbcon.h:219
MSqlDatabase::InitSessionVars
void InitSessionVars(void)
Definition: mythdbcon.cpp:279
MSqlQuery::kNormalConnection
@ kNormalConnection
Definition: mythdbcon.h:229
MSqlQuery::ConnectionReuse
ConnectionReuse
Definition: mythdbcon.h:226
DatabaseParams
Structure containing the basic Database parameters.
Definition: mythdbparams.h:10
mythbaseexp.h
MDBManager::m_inuseCount
QHash< QThread *, int > m_inuseCount
Definition: mythdbcon.h:80
MSqlQuery::record
QSqlRecord record(void) const
Definition: mythdbcon.h:216
MDBManager
DB connection pool, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:54
MSqlDatabase::KickDatabase
bool KickDatabase(void)
Definition: mythdbcon.cpp:254
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MSqlDatabase::db
QSqlDatabase db(void) const
Definition: mythdbcon.h:41
TestDatabase
MBASE_PUBLIC bool TestDatabase(const QString &dbHostName, const QString &dbUserName, QString dbPassword, QString dbName="mythconverg", int dbPort=3306)
Definition: mythdbcon.cpp:41
MSqlEscapeAsAQuery
MBASE_PUBLIC void MSqlEscapeAsAQuery(QString &query, const MSqlBindings &bindings)
Given a partial query string and a bindings object, escape the string.
Definition: mythdbcon.cpp:1004
MSqlDatabase::isOpen
bool isOpen(void)
Definition: mythdbcon.cpp:122
MDBManager::DBList
QList< MSqlDatabase * > DBList
Definition: mythdbcon.h:76
MBASE_PUBLIC
#define MBASE_PUBLIC
Definition: mythbaseexp.h:15
MSqlDatabase::MSqlDatabase
MSqlDatabase(QString name, QString driver="QMYSQL")
Definition: mythdbcon.cpp:84
MSqlQueryInfo
MSqlDatabase Info, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:92
MDBManager::m_pool
QHash< QThread *, DBList > m_pool
Definition: mythdbcon.h:77
MSqlDatabase::m_driver
QString m_driver
Definition: mythdbcon.h:47
MSqlDatabase::Reconnect
bool Reconnect(void)
Definition: mythdbcon.cpp:264
MDBManager::m_inuse
QHash< QThread *, MSqlDatabase * > m_inuse
Definition: mythdbcon.h:79
MDBManager::m_staticPool
QHash< QThread *, DBList > m_staticPool
Definition: mythdbcon.h:88
MSqlQueryInfo::db
MSqlDatabase * db
Definition: mythdbcon.h:94
MSqlQuery::boundValues
QVariantList boundValues(void) const
Definition: mythdbcon.h:211
MSqlDatabase::m_db
QSqlDatabase m_db
Definition: mythdbcon.h:48
MSqlQuery::setForwardOnly
void setForwardOnly(bool f)
Definition: mythdbcon.h:218
MSqlDatabase::~MSqlDatabase
~MSqlDatabase(void)
Definition: mythdbcon.cpp:109
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:137
MSqlAddMoreBindings
MBASE_PUBLIC void MSqlAddMoreBindings(MSqlBindings &output, MSqlBindings &addfrom)
Add the entries in addfrom to the map in output.
Definition: mythdbcon.cpp:983
MSqlQuery::m_lastPreparedQuery
QString m_lastPreparedQuery
Definition: mythdbcon.h:254
MSqlDatabase
QSqlDatabase wrapper, used by MSqlQuery. Do not use directly.
Definition: mythdbcon.h:25
MSqlQuery::lastError
QSqlError lastError(void) const
Definition: mythdbcon.h:213
MSqlQueryInfo::returnConnection
bool returnConnection
Definition: mythdbcon.h:96
MSqlDatabase::m_lastDBKick
QDateTime m_lastDBKick
Definition: mythdbcon.h:49
MSqlQuery::executedQuery
QString executedQuery(void) const
Definition: mythdbcon.h:205
MSqlQuery::kDedicatedConnection
@ kDedicatedConnection
Definition: mythdbcon.h:228
MSqlDatabase::GetConnectionName
QString GetConnectionName(void) const
Definition: mythdbcon.h:40
Reconnect
Definition: backendconnectionmanager.cpp:28
MSqlQuery::numRowsAffected
int numRowsAffected() const
Definition: mythdbcon.h:217
MSqlDatabase::m_name
QString m_name
Definition: mythdbcon.h:46
MSqlQueryInfo::qsqldb
QSqlDatabase qsqldb
Definition: mythdbcon.h:95
output
#define output
Definition: synaesthesia.cpp:223
MSqlDatabase::SetDBParams
void SetDBParams(const DatabaseParams &params)
Definition: mythdbcon.h:34
MSqlDatabase::OpenDatabase
bool OpenDatabase(bool skipdb=false)
Definition: mythdbcon.cpp:132
MSqlQuery::at
int at(void) const
Definition: mythdbcon.h:221
mythdbparams.h
MSqlQuery::driver
const QSqlDriver * driver(void) const
Definition: mythdbcon.h:220
MSqlDatabase::m_dbparms
DatabaseParams m_dbparms
Definition: mythdbcon.h:50