00001 #ifndef MYTHDBCON_H_
00002 #define MYTHDBCON_H_
00003
00004 #include <QSqlDatabase>
00005 #include <QSqlRecord>
00006 #include <QSqlError>
00007 #include <QVariant>
00008 #include <QSqlQuery>
00009 #include <QRegExp>
00010 #include <QDateTime>
00011 #include <QMutex>
00012 #include <QList>
00013
00014 #include "mythbaseexp.h"
00015 #include "mythdbparams.h"
00016
00017 #define REUSE_CONNECTION 1
00018
00019 MBASE_PUBLIC bool TestDatabase(QString dbHostName,
00020 QString dbUserName,
00021 QString dbPassword,
00022 QString dbName = "mythconverg",
00023 int dbPort = 3306);
00024
00026 class MSqlDatabase
00027 {
00028 friend class MDBManager;
00029 friend class MSqlQuery;
00030 public:
00031 MSqlDatabase(const QString &name);
00032 ~MSqlDatabase(void);
00033
00034 bool OpenDatabase(bool skipdb = false);
00035 void SetDBParams(DatabaseParams params) { m_dbparms = params; };
00036
00037 private:
00038 bool isOpen(void);
00039 bool KickDatabase(void);
00040 QString GetConnectionName(void) const { return m_name; }
00041 QSqlDatabase db(void) const { return m_db; }
00042 bool Reconnect(void);
00043
00044 private:
00045 QString m_name;
00046 QSqlDatabase m_db;
00047 QDateTime m_lastDBKick;
00048 DatabaseParams m_dbparms;
00049 };
00050
00052 class MBASE_PUBLIC MDBManager
00053 {
00054 friend class MSqlQuery;
00055 public:
00056 MDBManager(void);
00057 ~MDBManager(void);
00058
00059 void CloseDatabases(void);
00060 void PurgeIdleConnections(bool leaveOne = false);
00061
00062 protected:
00063 MSqlDatabase *popConnection(bool reuse);
00064 void pushConnection(MSqlDatabase *db);
00065
00066 MSqlDatabase *getSchedCon(void);
00067 MSqlDatabase *getDDCon(void);
00068
00069 private:
00070 MSqlDatabase *getStaticCon(MSqlDatabase **dbcon, QString name);
00071
00072 QMutex m_lock;
00073 typedef QList<MSqlDatabase*> DBList;
00074 QHash<QThread*, DBList> m_pool;
00075 #if REUSE_CONNECTION
00076 QHash<QThread*, MSqlDatabase*> m_inuse;
00077 QHash<QThread*, int> m_inuse_count;
00078 #endif
00079
00080 int m_nextConnID;
00081 int m_connCount;
00082
00083 MSqlDatabase *m_schedCon;
00084 MSqlDatabase *m_DDCon;
00085 QHash<QThread*, DBList> m_static_pool;
00086 };
00087
00089 typedef struct _MSqlQueryInfo
00090 {
00091 MSqlDatabase *db;
00092 QSqlDatabase qsqldb;
00093 bool returnConnection;
00094 } MSqlQueryInfo;
00095
00097 typedef QMap<QString, QVariant> MSqlBindings;
00098
00100 MBASE_PUBLIC void MSqlAddMoreBindings(MSqlBindings &output, MSqlBindings &addfrom);
00101
00103 MBASE_PUBLIC void MSqlEscapeAsAQuery(QString &query, MSqlBindings &bindings);
00104
00124 class MBASE_PUBLIC MSqlQuery : private QSqlQuery
00125 {
00126 MBASE_PUBLIC friend void MSqlEscapeAsAQuery(QString&, MSqlBindings&);
00127 public:
00129 MSqlQuery(const MSqlQueryInfo &qi);
00131 ~MSqlQuery();
00132
00134 bool isConnected(void) { return m_isConnected; }
00135
00137 bool exec(void);
00138
00140 bool next(void);
00141
00143 bool previous(void);
00144
00146 bool first(void);
00147
00149 bool last(void);
00150
00152
00153 bool seek(int, bool relative = false);
00154
00156 bool exec(const QString &query);
00157
00159 bool prepare(const QString &query);
00160
00161 void bindValue(const QString &placeholder, const QVariant &val);
00162
00164 void bindValues(const MSqlBindings &bindings);
00165
00174 QVariant lastInsertId();
00175
00178 bool Reconnect(void);
00179
00180
00181 QVariant value(int i) const { return QSqlQuery::value(i); }
00182 QString executedQuery(void) const { return QSqlQuery::executedQuery(); }
00183 QMap<QString, QVariant> boundValues(void) const
00184 { return QSqlQuery::boundValues(); }
00185 QSqlError lastError(void) const { return QSqlQuery::lastError(); }
00186 int size(void) const { return QSqlQuery::size();}
00187 bool isActive(void) const { return QSqlQuery::isActive(); }
00188 QSqlRecord record(void) const { return QSqlQuery::record(); }
00189 int numRowsAffected() const { return QSqlQuery::numRowsAffected(); }
00190 void setForwardOnly(bool f) { QSqlQuery::setForwardOnly(f); }
00191 bool isNull(int field) const { return QSqlQuery::isNull(field); }
00192 const QSqlDriver *driver(void) const { return QSqlQuery::driver(); }
00193 int at(void) const { return QSqlQuery::at(); }
00194
00196 static bool testDBConnection();
00197
00198 typedef enum
00199 {
00200 kDedicatedConnection,
00201 kNormalConnection,
00202 } ConnectionReuse;
00204 static MSqlQueryInfo InitCon(ConnectionReuse = kNormalConnection);
00205
00207 static MSqlQueryInfo SchedCon();
00208
00210 static MSqlQueryInfo DDCon();
00211
00212 private:
00213
00214 void bindValue(const QString&, const QVariant&, QSql::ParamType);
00215 void bindValue(int, const QVariant&, QSql::ParamType);
00216 void addBindValue(const QVariant&, QSql::ParamType = QSql::In);
00217
00218 bool seekDebug(const char *type, bool result,
00219 int where, bool relative) const;
00220
00221 MSqlDatabase *m_db;
00222 bool m_isConnected;
00223 bool m_returnConnection;
00224 QString m_last_prepared_query;
00225 #ifdef DEBUG_QT4_PORT
00226 QRegExp m_testbindings;
00227 #endif
00228 };
00229
00230 #endif