浏览代码

Wrapper für MySql-Info hinzugefügt.

Rind 4 年之前
父节点
当前提交
40cab97b1f
共有 8 个文件被更改,包括 1125 次插入67 次删除
  1. 5 2
      README.md
  2. 3 0
      gfaqt.pro
  3. 52 0
      src/helpers.cpp
  4. 25 0
      src/helpers.h
  5. 70 2
      src/qappctrl.cpp
  6. 183 2
      src/qappctrl.h
  7. 782 0
      src/qmysqlinfo.cpp
  8. 5 61
      src/qsysinfo.cpp

+ 5 - 2
README.md

@@ -22,6 +22,8 @@ libgfaqt.so (-lgfaqt)
 **Implementiert:**
 **Implementiert:**
 
 
 * QML-Wrapper für App-Control.
 * QML-Wrapper für App-Control.
+* QML-Wrapper für Hotplug-Events.
+* QML-Wrapper für MySql-Info.
 
 
 ---
 ---
 
 
@@ -33,5 +35,6 @@ libgfaqt.so (-lgfaqt)
 
 
 **History:**
 **History:**
 
 
-* **1.1.0**<br>
-	Q-App-Control-Funktion zum Beenden eines Prozesses im Zombie-State hinzugefügt.
+* **1.1.0**
+	* Q-App-Control-Funktion zum Beenden eines Prozesses im Zombie-State hinzugefügt.
+	* MySql-Info implementiert.

+ 3 - 0
gfaqt.pro

@@ -7,11 +7,14 @@ CONFIG += c++11 shared thread
 ####################################################################################
 ####################################################################################
 
 
 SOURCES += \
 SOURCES += \
+    src/helpers.cpp \
     src/qappctrl.cpp \
     src/qappctrl.cpp \
     src/qappinfo.cpp \
     src/qappinfo.cpp \
+    src/qmysqlinfo.cpp \
     src/qsysinfo.cpp
     src/qsysinfo.cpp
 
 
 HEADERS += \
 HEADERS += \
+    src/helpers.h \
     src/qappctrl.h
     src/qappctrl.h
 
 
 ####################################################################################
 ####################################################################################

+ 52 - 0
src/helpers.cpp

@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include "helpers.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+const char *FormatByteSize(unsigned long long nCb, char *pszBuf, size_t nCChBuf, bool bShortUnits, int nPrec)
+{
+	if(pszBuf && nCChBuf)
+	{
+		double val = nCb;
+		
+		if(nCb < _BYTE_SIZE_KIB)
+		{
+			snprintf(pszBuf, nCChBuf, "%llu %s", nCb, bShortUnits ? "B" : "Byte"); // Byte
+		}
+		else if(nCb < _BYTE_SIZE_MIB)
+		{
+			val /= _BYTE_SIZE_KIB;
+			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "K" : "KiB"); // KiB
+		}
+		else if(nCb < _BYTE_SIZE_GIB)
+		{
+			val /= _BYTE_SIZE_MIB;
+			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "M" : "MiB"); // MiB
+		}
+		else if(nCb < _BYTE_SIZE_TIB)
+		{
+			val /= _BYTE_SIZE_GIB;
+			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "G" : "GiB"); // GiB
+		}
+		else if(nCb < _BYTE_SIZE_PIB)
+		{
+			val /= _BYTE_SIZE_TIB;
+			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "T" : "TiB"); // TiB
+		}
+		else if(nCb < _BYTE_SIZE_EIB)
+		{
+			val /= _BYTE_SIZE_PIB;
+			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "P" : "PiB"); // PiB
+		}
+		
+		return pszBuf;
+	}
+	
+	return NULL;
+}
+
+QString FormatByteSize(unsigned long long nCb, bool bShortUnits, int nPrec)
+{
+	char szBuf[128];
+	return FormatByteSize(nCb, szBuf, sizeof(szBuf), bShortUnits, nPrec);
+}

+ 25 - 0
src/helpers.h

@@ -0,0 +1,25 @@
+// helpers.h :
+//
+
+#if !defined(AGD_HELPERS_H__0DC08E7C_D3AE_4E62_867E_0DB7C3F0EBAC__INCLUDED_)
+#define AGD_HELPERS_H__0DC08E7C_D3AE_4E62_867E_0DB7C3F0EBAC__INCLUDED_
+
+#include <QObject>
+
+/////////////////////////////////////////////////////////////////////////////
+// helpers.h - Declarations:
+
+#define _BYTE_SIZE_KIB						(1ULL << 10) // Kibibyte
+#define _BYTE_SIZE_MIB						(1ULL << 20) // Mebibyte
+#define _BYTE_SIZE_GIB						(1ULL << 30) // Gibibyte
+#define _BYTE_SIZE_TIB						(1ULL << 40) // Tebibyte
+#define _BYTE_SIZE_PIB						(1ULL << 50) // Pebibyte
+#define _BYTE_SIZE_EIB						(1ULL << 60) // Exbibyte
+
+/////////////////////////////////////////////////////////////////////////////
+
+const char *FormatByteSize(unsigned long long nCb, char *pszBuf, size_t nCChBuf, bool bShortUnits = true, int nPrec = 1);
+QString FormatByteSize(unsigned long long nCb, bool bShortUnits = true, int nPrec = 1);
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_HELPERS_H__0DC08E7C_D3AE_4E62_867E_0DB7C3F0EBAC__INCLUDED_)

+ 70 - 2
src/qappctrl.cpp

@@ -68,7 +68,7 @@ bool QGfaAppCtrl::Create(appid_t nAppID, const char *pszDisplayName, int nTimerI
 		{
 		{
 			m_nAppID = nAppID;
 			m_nAppID = nAppID;
 			m_nHeavyLoadUpdateIntervalUs = nHeavyLoadUpdateIntervalMs * 1000;
 			m_nHeavyLoadUpdateIntervalUs = nHeavyLoadUpdateIntervalMs * 1000;
-			::GfaIpcAppCtrlSubscribeSysEvents(m_hAC, GFA_APPCTRL_SYSEVENT_ALL_STG_DEV);
+			::GfaIpcAppCtrlSubscribeSysEvents(m_hAC, GFA_APPCTRL_SYSEVENT_ALL_STG_DEV | GFA_APPCTRL_SYSEVENT_ALL_MYSQL);
 			m_nTimerID = startTimer(nTimerIntMs, Qt::CoarseTimer);
 			m_nTimerID = startTimer(nTimerIntMs, Qt::CoarseTimer);
 			
 			
 			bool bBootFromEmmc;
 			bool bBootFromEmmc;
@@ -102,6 +102,10 @@ void QGfaAppCtrl::RegisterQmlTypes(QQmlEngine &rEng, int nVerMajor, int nVerMino
 	qmlRegisterUncreatableType<QGfaSysInfo>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaSysInfo", QStringLiteral("class not creatable in QML"));
 	qmlRegisterUncreatableType<QGfaSysInfo>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaSysInfo", QStringLiteral("class not creatable in QML"));
 	qmlRegisterUncreatableType<QGfaAppInfo>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaAppInfo", QStringLiteral("class not creatable in QML"));
 	qmlRegisterUncreatableType<QGfaAppInfo>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaAppInfo", QStringLiteral("class not creatable in QML"));
 	qmlRegisterUncreatableType<QGfaAppCtrl>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaAppCtrl", QStringLiteral("class not creatable in QML"));
 	qmlRegisterUncreatableType<QGfaAppCtrl>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaAppCtrl", QStringLiteral("class not creatable in QML"));
+//	qmlRegisterUncreatableType<QGfaMySqlSchemaTreeItem>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaStgDevList", QStringLiteral("class not creatable in QML"));
+	qmlRegisterUncreatableType<QGfaMySqlSchemaModel>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaStgDevList", QStringLiteral("class not creatable in QML"));
+	qmlRegisterUncreatableType<QGfaMySqlInfo>("com.gfa.ipc.appctrl", nVerMajor, nVerMinor, "QGfaStgDevList", QStringLiteral("class not creatable in QML"));
+
 	rEng.rootContext()->setContextProperty(QStringLiteral("qGfaAppCtrl"), this);
 	rEng.rootContext()->setContextProperty(QStringLiteral("qGfaAppCtrl"), this);
 }
 }
 
 
@@ -143,8 +147,9 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 		if((hAI = ::GfaIpcAppCtrlInfoUpdate(m_hAC, nCurPass)))
 		if((hAI = ::GfaIpcAppCtrlInfoUpdate(m_hAC, nCurPass)))
 		{
 		{
 			int b;
 			int b;
+			bool bSysInfoStateTransition = false;
 		    appid_t app, nAppIdSrc;
 		    appid_t app, nAppIdSrc;
-		    sysevt_t nSysEvt;
+		    sysevt_t nSysEvt, nMySqlNotProcessed;
 			GFA_APPCTRL_APPTIMES at;
 			GFA_APPCTRL_APPTIMES at;
 			GFA_APPCTRL_APPMEM am;
 			GFA_APPCTRL_APPMEM am;
 			GFA_SYSINFO_DISK disk;
 			GFA_SYSINFO_DISK disk;
@@ -171,7 +176,9 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 					if(nAppIdSrc == GFA_APPCTRL_APPID_SYSINFO)
 					if(nAppIdSrc == GFA_APPCTRL_APPID_SYSINFO)
 					{
 					{
 						m_bSysInfoRunning = (state == GIAS_Running);
 						m_bSysInfoRunning = (state == GIAS_Running);
+						emit sysInfoRunningChanged(m_bSysInfoRunning);
 						m_sysInfo.setSysInfoRunning(m_bSysInfoRunning);
 						m_sysInfo.setSysInfoRunning(m_bSysInfoRunning);
+						bSysInfoStateTransition = true;
 					}
 					}
 				}
 				}
 
 
@@ -186,6 +193,9 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 			
 			
 			if(m_bSysInfoRunning)
 			if(m_bSysInfoRunning)
 			{
 			{
+				GFA_SYSINFO_DATABASE sdb;
+				nMySqlNotProcessed = GFA_APPCTRL_SYSEVENT_ALL_MYSQL;
+				
 				while((nSysEvt = ::GfaIpcAppCtrlGetNextSysEvt(hAI)))
 				while((nSysEvt = ::GfaIpcAppCtrlGetNextSysEvt(hAI)))
 				{
 				{
 					int nIndex;
 					int nIndex;
@@ -222,9 +232,57 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 							m_sysInfo.mountAdded(nIndex, part);
 							m_sysInfo.mountAdded(nIndex, part);
 						}
 						}
 						break;
 						break;
+
+					/////////////////////////////////////////////////////////
+
+					case GFA_APPCTRL_SYSEVENT_MYSQL_INIT_EVT:
+						if(::GfaIpcAppCtrlGetDbInfo(m_hAC, &sdb))
+						{
+							m_mySqlInfo.onMySqlInitEvent(sdb.bIsInit);
+							nMySqlNotProcessed &= ~GFA_APPCTRL_SYSEVENT_MYSQL_INIT_EVT;
+						}
+						break;
+					case GFA_APPCTRL_SYSEVENT_MYSQL_SERVER_EVT:
+						if(::GfaIpcAppCtrlGetDbInfo(m_hAC, &sdb))
+						{
+							m_mySqlInfo.onMySqlServerEvent(sdb.svr);
+							nMySqlNotProcessed &= ~GFA_APPCTRL_SYSEVENT_MYSQL_SERVER_EVT;
+						}
+						break;
+					case GFA_APPCTRL_SYSEVENT_MYSQL_RESOURCE_EVT:
+						if(::GfaIpcAppCtrlGetDbInfo(m_hAC, &sdb))
+						{
+							m_mySqlInfo.onMySqlResourceEvent(sdb.res);
+							nMySqlNotProcessed &= ~GFA_APPCTRL_SYSEVENT_MYSQL_RESOURCE_EVT;
+						}
+						break;
+					case GFA_APPCTRL_SYSEVENT_MYSQL_DATABASE_EVT:
+						if(::GfaIpcAppCtrlGetDbInfo(m_hAC, &sdb))
+						{
+							m_mySqlInfo.onMySqlDatabaseEvent(sdb.nNumDatabases, sdb.dbs);
+							nMySqlNotProcessed &= ~GFA_APPCTRL_SYSEVENT_MYSQL_DATABASE_EVT;
+						}
+						break;
+					}
+				}
+				
+				if(bSysInfoStateTransition)
+				{
+					bSysInfoStateTransition = false;
+
+					if(nMySqlNotProcessed && ::GfaIpcAppCtrlGetDbInfo(m_hAC, &sdb))
+					{
+						m_mySqlInfo.onMySqlInitEvent(sdb.bIsInit);
+						m_mySqlInfo.onMySqlServerEvent(sdb.svr);
+						m_mySqlInfo.onMySqlResourceEvent(sdb.res);
+						m_mySqlInfo.onMySqlDatabaseEvent(sdb.nNumDatabases, sdb.dbs);
 					}
 					}
 				}
 				}
 			}
 			}
+			else
+			{
+				m_mySqlInfo.onMySqlInitEvent(false);
+			}
 
 
 			nAppIdSrc = m_nEvtSrcs;
 			nAppIdSrc = m_nEvtSrcs;
 			bool bDontSaveLast = false;
 			bool bDontSaveLast = false;
@@ -356,11 +414,21 @@ quint64 QGfaAppCtrl::avgPass(void) const
 	return m_avgPass;
 	return m_avgPass;
 }
 }
 
 
+bool QGfaAppCtrl::sysInfoRunning(void) const
+{
+	return m_bSysInfoRunning;
+}
+
 QGfaSysInfo* QGfaAppCtrl::sysInfo(void)
 QGfaSysInfo* QGfaAppCtrl::sysInfo(void)
 {
 {
 	return &m_sysInfo;
 	return &m_sysInfo;
 }
 }
 
 
+QGfaMySqlInfo* QGfaAppCtrl::mySqlInfo(void)
+{
+	return &m_mySqlInfo;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
 int QGfaAppCtrl::appIndexFromAppID(quint64 nAppID)
 int QGfaAppCtrl::appIndexFromAppID(quint64 nAppID)

+ 183 - 2
src/qappctrl.h

@@ -7,7 +7,9 @@
 #include <QObject>
 #include <QObject>
 #include <QQmlEngine>
 #include <QQmlEngine>
 #include <QQmlContext>
 #include <QQmlContext>
-#include <QAbstractTableModel>
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QVector>
 #include <vector>
 #include <vector>
 #include <gfa/gfaipc.h>
 #include <gfa/gfaipc.h>
 #include <gfa/ipcpriv.h>
 #include <gfa/ipcpriv.h>
@@ -63,6 +65,179 @@ private:
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
+class QGfaMySqlSchemaTreeItem
+{
+public:
+	explicit QGfaMySqlSchemaTreeItem(QGfaMySqlSchemaTreeItem *pParentItem = NULL);
+	QGfaMySqlSchemaTreeItem(const QVariant &name, const QVariant &data, const QVariant &dataF, QGfaMySqlSchemaTreeItem *parentItem);
+	~QGfaMySqlSchemaTreeItem(void);
+
+	void appendChild(QGfaMySqlSchemaTreeItem *child);
+	void clear(void);
+
+	QGfaMySqlSchemaTreeItem *child(int row);
+	QGfaMySqlSchemaTreeItem *getChildItemByName(const char *pszName);
+	int childCount() const;
+	int columnCount() const;
+	QVariant data(int column) const;
+	int row() const;
+	QGfaMySqlSchemaTreeItem *parentItem();
+	int compareValue(const QVariant &val) const;
+	bool updateValue(const QVariant &val, const QVariant &valF = QVariant());
+
+private:
+	QVector<QGfaMySqlSchemaTreeItem*> m_childItems;
+	QVector<QVariant> m_itemData;
+	QGfaMySqlSchemaTreeItem *m_parentItem;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class QGfaMySqlSchemaModel : public QAbstractItemModel
+{
+    Q_OBJECT
+
+public:
+	typedef enum
+	{
+	    SMR_Name = Qt::UserRole,
+	    SMR_Info,
+	    SMR_InfoFormatted,
+	    SMR_Invalid
+	}SchemaModelRoles;
+
+public:
+	explicit QGfaMySqlSchemaModel(QObject *pParent = NULL);
+	~QGfaMySqlSchemaModel(void);
+
+	QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
+	Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
+	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
+	QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+	QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
+	int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+	int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+	QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
+
+    void setModelData(unsigned int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs);
+	void clearAll(void);
+
+private:
+	bool getDatabaseLayoutChanged(int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs) const;
+	void updateDatabaseValues(int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs);
+
+private:
+    QGfaMySqlSchemaTreeItem *m_pRootItem;
+    QHash<int, QByteArray> m_roleNameMapping;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+class QGfaMySqlInfo : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(bool isInit READ isInit NOTIFY isInitChanged)
+    Q_PROPERTY(bool svrRunning READ svrRunning NOTIFY svrRunningChanged)
+    Q_PROPERTY(bool svrInnoDbFilePerTableSpace READ svrInnoDbFilePerTableSpace NOTIFY svrInnoDbFilePerTableSpaceChanged)
+    Q_PROPERTY(qint32 svrPid READ svrPid NOTIFY svrPidChanged)
+	Q_PROPERTY(quint64 svrUpTime READ svrUpTime NOTIFY svrUpTimeChanged)
+	Q_PROPERTY(quint64 svrDiscUsage READ svrDiscUsage NOTIFY svrDiscUsageChanged)
+	Q_PROPERTY(QString svrVersion READ svrVersion NOTIFY svrVersionChanged)
+	Q_PROPERTY(QString svrDataDir READ svrDataDir NOTIFY svrDataDirChanged)
+    Q_PROPERTY(quint32 svrNumDataBases READ svrNumDataBases NOTIFY svrNumDataBasesChanged)
+	Q_PROPERTY(double cpuTime READ cpuTime NOTIFY cpuTimeChanged)
+	Q_PROPERTY(double cpuCur READ cpuCur NOTIFY cpuCurChanged)
+	Q_PROPERTY(double cpuAvg READ cpuAvg NOTIFY cpuAvgChanged)
+	Q_PROPERTY(quint32 vmPeak READ vmPeak NOTIFY vmPeakChanged)
+	Q_PROPERTY(quint32 vmSize READ vmSize NOTIFY vmSizeChanged)
+	Q_PROPERTY(quint32 vmHWM READ vmHWM NOTIFY vmHWMChanged)
+	Q_PROPERTY(quint32 vmRSS READ vmRSS NOTIFY vmRSSChanged)
+    Q_PROPERTY(QGfaMySqlSchemaModel *schemaModel READ schemaModel CONSTANT)
+
+public:
+	explicit QGfaMySqlInfo(QObject *pParent = NULL);
+	virtual ~QGfaMySqlInfo(void);
+	
+	void onMySqlInitEvent(bool bInit);
+	void onMySqlServerEvent(const GFA_MYSQL_SERVER &svr);
+	void onMySqlResourceEvent(const GFA_MYSQL_RESOURCE &res);
+	void onMySqlDatabaseEvent(unsigned int nNumDatabases, LPCGFA_MYSQL_SCHEMA pdbs);
+
+signals:
+	void isInitChanged(bool val);
+	void svrRunningChanged(bool val);
+	void svrInnoDbFilePerTableSpaceChanged(bool val);
+	void svrPidChanged(qint32 val);
+	void svrUpTimeChanged(quint64 val);
+	void svrDiscUsageChanged(quint64 val);
+	void svrVersionChanged(QString val);
+	void svrDataDirChanged(QString val);
+	void cpuTimeChanged(double val);
+	void cpuCurChanged(double val);
+	void cpuAvgChanged(double val);
+	void vmPeakChanged(quint32 val);
+	void vmSizeChanged(quint32 val);
+	void vmHWMChanged(quint32 val);
+	void vmRSSChanged(quint32 val);
+	void svrNumDataBasesChanged(quint32 val);
+
+private:
+	bool isInit(void) const;
+
+	bool svrRunning(void) const;
+	void setSvrRunning(bool val);
+
+	bool svrInnoDbFilePerTableSpace(void) const;
+	void setSvrInnoDbFilePerTableSpace(bool val);
+	
+	qint32 svrPid(void) const;
+	void setSvrPid(pid_t val);
+	
+	quint64 svrUpTime(void) const;
+	void setSvrUpTime(time_t val);
+	
+	quint64 svrDiscUsage(void) const;
+	void setSvrDiscUsage(size_t val);
+	
+	QString svrVersion(void) const;
+	void setSvrVersion(const char *val);
+	
+	QString svrDataDir(void) const;
+	void setSvrDataDir(const char *val);
+
+	double cpuTime(void) const;
+	void setCpuTime(double val);
+
+	double cpuCur(void) const;
+	void setCpuCur(double val);
+
+	double cpuAvg(void) const;
+	void setCpuAvg(double val);
+
+	quint32 vmPeak(void) const;
+	void setVmPeak(size_t val);
+
+	quint32 vmSize(void) const;
+	void setVmSize(size_t val);
+
+	quint32 vmHWM(void) const;
+	void setVmHWM(size_t val);
+
+	quint32 vmRSS(void) const;
+	void setVmRSS(size_t val);
+
+	quint32 svrNumDataBases(void) const;
+	void setSvrNumDataBases(unsigned int val);
+	
+	QGfaMySqlSchemaModel* schemaModel(void);
+
+private:
+	GFA_SYSINFO_DATABASE m_sysInfoDbShadow;
+	QGfaMySqlSchemaModel m_mySqlSchemaModel;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
 class QGfaSysInfo : public QObject
 class QGfaSysInfo : public QObject
 {
 {
     Q_OBJECT
     Q_OBJECT
@@ -259,7 +434,9 @@ class QGfaAppCtrl : public QObject
 	Q_PROPERTY(quint64 minPass READ minPass NOTIFY minPassChanged)
 	Q_PROPERTY(quint64 minPass READ minPass NOTIFY minPassChanged)
 	Q_PROPERTY(quint64 maxPass READ maxPass NOTIFY maxPassChanged)
 	Q_PROPERTY(quint64 maxPass READ maxPass NOTIFY maxPassChanged)
 	Q_PROPERTY(quint64 avgPass READ avgPass NOTIFY avgPassChanged)
 	Q_PROPERTY(quint64 avgPass READ avgPass NOTIFY avgPassChanged)
+	Q_PROPERTY(bool sysInfoRunning READ sysInfoRunning NOTIFY sysInfoRunningChanged)
     Q_PROPERTY(QGfaSysInfo *sysInfo READ sysInfo CONSTANT)
     Q_PROPERTY(QGfaSysInfo *sysInfo READ sysInfo CONSTANT)
+    Q_PROPERTY(QGfaMySqlInfo *mySqlInfo READ mySqlInfo CONSTANT)
 
 
 public:
 public:
 	enum AppStates
 	enum AppStates
@@ -292,6 +469,7 @@ signals:
 	void minPassChanged(quint64 val);
 	void minPassChanged(quint64 val);
 	void maxPassChanged(quint64 val);
 	void maxPassChanged(quint64 val);
 	void avgPassChanged(quint64 val);
 	void avgPassChanged(quint64 val);
+	void sysInfoRunningChanged(bool val);
 
 
 public:
 public:
 	explicit QGfaAppCtrl(QObject *pParent = NULL);
 	explicit QGfaAppCtrl(QObject *pParent = NULL);
@@ -312,12 +490,14 @@ public:
 	quint64 minPass(void) const;
 	quint64 minPass(void) const;
 	quint64 maxPass(void) const;
 	quint64 maxPass(void) const;
 	quint64 avgPass(void) const;
 	quint64 avgPass(void) const;
+	bool sysInfoRunning(void) const;
 	QGfaSysInfo* sysInfo(void);
 	QGfaSysInfo* sysInfo(void);
+	QGfaMySqlInfo* mySqlInfo(void);
 
 
 private slots:
 private slots:
 	void onSendControlMessage(appid_t nAppID, ctrlmsg_t msg);
 	void onSendControlMessage(appid_t nAppID, ctrlmsg_t msg);
 	void onKillApp(appid_t nAppID);
 	void onKillApp(appid_t nAppID);
-	void timerEvent(QTimerEvent *event) override;
+	void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
 
 
 private:
 private:
 	bool m_bSysInfoRunning;
 	bool m_bSysInfoRunning;
@@ -326,6 +506,7 @@ private:
 	int m_nTimerID;
 	int m_nTimerID;
 	QGfaSysInfo m_sysInfo;
 	QGfaSysInfo m_sysInfo;
 	QList<QGfaAppInfo*> m_appInfo;
 	QList<QGfaAppInfo*> m_appInfo;
+	QGfaMySqlInfo m_mySqlInfo;
 	clock64_t m_curPass;
 	clock64_t m_curPass;
 	clock64_t m_minPass;
 	clock64_t m_minPass;
 	clock64_t m_maxPass;
 	clock64_t m_maxPass;

+ 782 - 0
src/qmysqlinfo.cpp

@@ -0,0 +1,782 @@
+#include <QDateTime>
+#include "qappctrl.h"
+#include "helpers.h"
+#include "defines.h"
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+#define _countof(a)							(sizeof(a) / sizeof(*a))
+
+/////////////////////////////////////////////////////////////////////////////
+
+typedef struct _SCHEMA_MODEL_ROLES
+{
+	int nRole;
+	const char *pszRoleName;
+}SCHEMA_MODEL_ROLES, *LPSCHEMA_MODEL_ROLES;
+typedef const SCHEMA_MODEL_ROLES *LPCSCHEMA_MODEL_ROLES;
+
+static const SCHEMA_MODEL_ROLES g_roles[] =
+{
+	{QGfaMySqlSchemaModel::SMR_Name,			"name"},
+	{QGfaMySqlSchemaModel::SMR_Info,			"infoRaw"},
+	{QGfaMySqlSchemaModel::SMR_InfoFormatted,	"infoFormatted"}
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+QGfaMySqlSchemaTreeItem::QGfaMySqlSchemaTreeItem(QGfaMySqlSchemaTreeItem *pParentItem) : m_parentItem(pParentItem)
+{
+}
+
+QGfaMySqlSchemaTreeItem::QGfaMySqlSchemaTreeItem(const QVariant &name, const QVariant &data, const QVariant &dataF, QGfaMySqlSchemaTreeItem *pParentItem) : m_parentItem(pParentItem)
+{
+	m_itemData.append(name);
+	m_itemData.append(data);
+	m_itemData.append(dataF.isValid() ? dataF : data);
+}
+
+QGfaMySqlSchemaTreeItem::~QGfaMySqlSchemaTreeItem(void)
+{
+    qDeleteAll(m_childItems);
+}
+
+void QGfaMySqlSchemaTreeItem::appendChild(QGfaMySqlSchemaTreeItem *item)
+{
+    m_childItems.append(item);
+}
+
+void QGfaMySqlSchemaTreeItem::clear(void)
+{
+    qDeleteAll(m_childItems);
+    m_childItems.clear();
+    m_itemData.clear();
+    m_parentItem = NULL;
+}
+
+QGfaMySqlSchemaTreeItem *QGfaMySqlSchemaTreeItem::child(int row)
+{
+    if (row < 0 || row >= m_childItems.size())
+        return NULL;
+    return m_childItems.at(row);
+}
+
+int QGfaMySqlSchemaTreeItem::childCount() const
+{
+    return m_childItems.count();
+}
+
+int QGfaMySqlSchemaTreeItem::columnCount() const
+{
+    return _countof(g_roles);
+}
+
+QVariant QGfaMySqlSchemaTreeItem::data(int column) const
+{
+    if (column < 0 || column >= m_itemData.size())
+        return QVariant();
+    return m_itemData.at(column);
+}
+
+QGfaMySqlSchemaTreeItem *QGfaMySqlSchemaTreeItem::parentItem()
+{
+    return m_parentItem;
+}
+
+int QGfaMySqlSchemaTreeItem::row() const
+{
+    if (m_parentItem)
+        return m_parentItem->m_childItems.indexOf(const_cast<QGfaMySqlSchemaTreeItem*>(this));
+
+    return 0;
+}
+
+QGfaMySqlSchemaTreeItem* QGfaMySqlSchemaTreeItem::getChildItemByName(const char *pszName)
+{
+	for(QGfaMySqlSchemaTreeItem* pItem : m_childItems)
+	{
+		QVariant name = pItem->data(0);
+
+		if(name.isValid())
+		{
+			if(name == QVariant(pszName))
+				return pItem;
+		}
+	}
+
+	return NULL;
+}
+
+int QGfaMySqlSchemaTreeItem::compareValue(const QVariant &val) const
+{
+	if((m_itemData.size() >= 3) && val.isValid())
+	{
+		if(m_itemData[1].type() == val.type())
+			return !(m_itemData[1] == val);
+	}
+
+	return 1;
+}
+
+bool QGfaMySqlSchemaTreeItem::updateValue(const QVariant &val, const QVariant &valF)
+{
+	bool bUpdated = false;
+
+	if(m_itemData.size() >= 3)
+	{
+		if(val.isValid())
+		{
+			if(m_itemData[1] != val)
+			{
+				m_itemData[1] = val;
+				bUpdated = true;
+			}
+
+			if(valF.isValid())
+			{
+				if(m_itemData[2] != valF)
+				{
+					m_itemData[2] = valF;
+					bUpdated = true;
+				}
+			}
+			else if(m_itemData[2] != val)
+			{
+				m_itemData[2] = val;
+				bUpdated = true;
+			}
+		}
+		else if(m_itemData[1].isValid() || m_itemData[2].isValid())
+		{
+			m_itemData[1] = QVariant();
+			m_itemData[2] = QVariant();
+			bUpdated = true;
+		}
+	}
+
+	return bUpdated;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+QGfaMySqlSchemaModel::QGfaMySqlSchemaModel(QObject *pParent) : QAbstractItemModel(pParent)
+{
+	m_pRootItem = new QGfaMySqlSchemaTreeItem();
+
+	for(size_t i = 0; i < _countof(g_roles); ++i)
+	{
+		m_roleNameMapping[g_roles[i].nRole] = g_roles[i].pszRoleName;
+	}
+}
+
+QGfaMySqlSchemaModel::~QGfaMySqlSchemaModel(void)
+{
+	delete m_pRootItem;
+}
+
+void QGfaMySqlSchemaModel::clearAll(void)
+{
+	beginResetModel();
+	m_pRootItem->clear();
+	endResetModel();
+}
+
+QVariant QGfaMySqlSchemaModel::data(const QModelIndex &index, int role) const
+{
+	if(!index.isValid())
+		return QVariant();
+
+	if((role < SMR_Name) || (role >= SMR_Invalid))
+		return QVariant();
+
+	QGfaMySqlSchemaTreeItem *item = static_cast<QGfaMySqlSchemaTreeItem*>(index.internalPointer());
+	// Do not use index.column as shown in some examples!
+	return item->data(role - SMR_Name);
+}
+
+Qt::ItemFlags QGfaMySqlSchemaModel::flags(const QModelIndex &index) const
+{
+	if(!index.isValid())
+		return Qt::NoItemFlags;
+	return QAbstractItemModel::flags(index);
+}
+
+QVariant QGfaMySqlSchemaModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+	if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+		return m_pRootItem->data(section);
+	return QVariant();
+}
+
+QModelIndex QGfaMySqlSchemaModel::index(int row, int column, const QModelIndex &parentIndex) const
+{
+	if(!hasIndex(row, column, parentIndex))
+		return QModelIndex();
+
+	QGfaMySqlSchemaTreeItem *pParentItem;
+
+	if(!parentIndex.isValid())
+		pParentItem = m_pRootItem;
+	else
+		pParentItem = static_cast<QGfaMySqlSchemaTreeItem*>(parentIndex.internalPointer());
+
+	QGfaMySqlSchemaTreeItem *pChildItem = pParentItem->child(row);
+	if(pChildItem)
+		return createIndex(row, column, pChildItem);
+	return QModelIndex();
+}
+
+QModelIndex QGfaMySqlSchemaModel::parent(const QModelIndex &index) const
+{
+	if (!index.isValid())
+		return QModelIndex();
+
+	QGfaMySqlSchemaTreeItem *pChildItem = static_cast<QGfaMySqlSchemaTreeItem*>(index.internalPointer());
+	QGfaMySqlSchemaTreeItem *pParentItem = pChildItem->parentItem();
+
+	if (pParentItem == m_pRootItem)
+		return QModelIndex();
+
+	return createIndex(pParentItem->row(), 0, pParentItem);
+}
+
+int QGfaMySqlSchemaModel::rowCount(const QModelIndex &parentIndex) const
+{
+	QGfaMySqlSchemaTreeItem *pParentItem;
+	if (parentIndex.column() > 0)
+		return 0;
+
+	if (!parentIndex.isValid())
+		pParentItem = m_pRootItem;
+	else
+		pParentItem = static_cast<QGfaMySqlSchemaTreeItem*>(parentIndex.internalPointer());
+
+	return pParentItem->childCount();
+}
+
+int QGfaMySqlSchemaModel::columnCount(const QModelIndex &parentIndex) const
+{
+	if(parentIndex.isValid())
+		return static_cast<QGfaMySqlSchemaTreeItem*>(parentIndex.internalPointer())->columnCount();
+	return m_pRootItem->columnCount();
+}
+
+QHash<int, QByteArray> QGfaMySqlSchemaModel::roleNames() const
+{
+	return m_roleNameMapping;
+}
+
+#define MODEL_NAME_SCHEMA_TABLES					"Tables"
+#define MODEL_NAME_TABLE_ENGINE						"Engine"
+#define MODEL_NAME_TABLE_VERSION					"Version"
+#define MODEL_NAME_TABLE_CREATE_TIME				"Created"
+#define MODEL_NAME_TABLE_ROW_FORMAT					"Row format"
+#define MODEL_NAME_TABLE_COLLATION					"Collation"
+
+void QGfaMySqlSchemaModel::updateDatabaseValues(int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs)
+{
+	for(int i = 0; i < nCntDbs; ++i)
+	{
+		const GFA_MYSQL_SCHEMA &dbs = pdbs[i];
+		QGfaMySqlSchemaTreeItem *pDb, *pTbls, *pTbl, *pItem;
+
+		if(!(pDb = m_pRootItem->getChildItemByName(dbs.szName)))
+			return;
+		QModelIndex indDb = index(pDb->row(), 0);
+
+		if(pDb->updateValue((qint64)dbs.nSizeTotal, ::FormatByteSize(dbs.nSizeTotal, false)))
+			emit dataChanged(indDb, indDb, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+		if(!(pTbls = pDb->getChildItemByName(MODEL_NAME_SCHEMA_TABLES)))
+			return;
+		QModelIndex indTbls = index(pTbls->row(), 0, indDb);
+
+		if(pTbls->compareValue(dbs.nNumTables))
+			return;
+
+		for(int j = 0; j < (int)dbs.nNumTables; ++j)
+		{
+			QModelIndex indItem;
+			const GFA_MYSQL_TABLE &tbl = dbs.tables[j];
+
+			if(!(pTbl = pTbls->getChildItemByName(tbl.szName)))
+				return;
+			QModelIndex indTbl = index(pTbl->row(), 0, indTbls);
+			if(pTbl->updateValue((qint64)tbl.nSizeTotal, ::FormatByteSize(tbl.nSizeTotal, false)))
+				emit dataChanged(indTbl, indTbl, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+			if(!(pItem = pTbl->getChildItemByName(MODEL_NAME_TABLE_CREATE_TIME)))
+				return;
+			indItem = index(pItem->row(), 0, indTbl);
+			if(pItem->updateValue((qint64)tbl.nCreateTime, QDateTime::fromMSecsSinceEpoch((qint64)tbl.nCreateTime * 1000LL)))
+				emit dataChanged(indItem, indItem, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+			if(!(pItem = pTbl->getChildItemByName(MODEL_NAME_TABLE_ENGINE)))
+				return;
+			indItem = index(pItem->row(), 0, indTbl);
+			if(pItem->updateValue(tbl.szEngine))
+				emit dataChanged(indItem, indItem, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+			if(!(pItem = pTbl->getChildItemByName(MODEL_NAME_TABLE_VERSION)))
+				return;
+			indItem = index(pItem->row(), 0, indTbl);
+			if(pItem->updateValue(tbl.nVersion))
+				emit dataChanged(indItem, indItem, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+			if(!(pItem = pTbl->getChildItemByName(MODEL_NAME_TABLE_ROW_FORMAT)))
+				return;
+			indItem = index(pItem->row(), 0, indTbl);
+			if(pItem->updateValue(tbl.szRowFormat))
+				emit dataChanged(indItem, indItem, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+
+			if(!(pItem = pTbl->getChildItemByName(MODEL_NAME_TABLE_COLLATION)))
+				return;
+			indItem = index(pItem->row(), 0, indTbl);
+			if(pItem->updateValue(tbl.szCollation))
+				emit dataChanged(indItem, indItem, QVector<int>({SMR_Info, SMR_InfoFormatted}));
+		}
+	}
+}
+
+// checks if  a Database or Table has been removed or added
+bool QGfaMySqlSchemaModel::getDatabaseLayoutChanged(int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs) const
+{
+	if(m_pRootItem->childCount() != nCntDbs)
+		return true;
+
+	for(int i = 0; i < nCntDbs; ++i)
+	{
+		const GFA_MYSQL_SCHEMA &dbs = pdbs[i];
+		QGfaMySqlSchemaTreeItem *pDb, *pTbls;
+
+		if(!(pDb = m_pRootItem->getChildItemByName(dbs.szName)))
+			return true;
+
+		if(!(pTbls = pDb->getChildItemByName(MODEL_NAME_SCHEMA_TABLES)))
+			return true;
+
+		if(pTbls->compareValue(dbs.nNumTables))
+			return true;
+
+		for(int j = 0; j < (int)dbs.nNumTables; ++j)
+		{
+			const GFA_MYSQL_TABLE &tbl = dbs.tables[j];
+
+			if(!(pTbls->getChildItemByName(tbl.szName)))
+				return true;
+		}
+	}
+
+	return false;
+}
+
+void QGfaMySqlSchemaModel::setModelData(unsigned int nCntDbs, LPCGFA_MYSQL_SCHEMA pdbs)
+{
+	if(getDatabaseLayoutChanged(nCntDbs, pdbs))
+	{
+		// if not only values, but databases or tables have changed, completely reset the treeview control
+		beginResetModel();
+		m_pRootItem->clear();
+
+		for(unsigned int i = 0; i < nCntDbs; ++i)
+		{
+			QGfaMySqlSchemaTreeItem *pTiTmp, *pTiTbls;
+			const GFA_MYSQL_SCHEMA &dbs = pdbs[i];
+
+			QGfaMySqlSchemaTreeItem *pTiDb = new QGfaMySqlSchemaTreeItem(dbs.szName, dbs.nSizeTotal, ::FormatByteSize(dbs.nSizeTotal, false), m_pRootItem);
+
+			pTiTbls = new QGfaMySqlSchemaTreeItem(MODEL_NAME_SCHEMA_TABLES, dbs.nNumTables, QVariant(), pTiDb);
+
+			for(unsigned int j = 0; j < dbs.nNumTables; ++j)
+			{
+				const GFA_MYSQL_TABLE &tbl = dbs.tables[j];
+
+				QGfaMySqlSchemaTreeItem *pTiTbl = new QGfaMySqlSchemaTreeItem(tbl.szName, tbl.nSizeTotal, ::FormatByteSize(tbl.nSizeTotal, false), pTiTbls);
+
+				pTiTmp = new QGfaMySqlSchemaTreeItem(MODEL_NAME_TABLE_CREATE_TIME, (qint64)tbl.nCreateTime, QDateTime::fromMSecsSinceEpoch((qint64)tbl.nCreateTime * 1000LL), pTiTbl);
+				pTiTbl->appendChild(pTiTmp);
+				pTiTmp = new QGfaMySqlSchemaTreeItem(MODEL_NAME_TABLE_ENGINE, tbl.szEngine, QVariant(), pTiTbl);
+				pTiTbl->appendChild(pTiTmp);
+				pTiTmp = new QGfaMySqlSchemaTreeItem(MODEL_NAME_TABLE_VERSION, tbl.nVersion, QVariant(), pTiTbl);
+				pTiTbl->appendChild(pTiTmp);
+				pTiTmp = new QGfaMySqlSchemaTreeItem(MODEL_NAME_TABLE_ROW_FORMAT, tbl.szRowFormat, QVariant(), pTiTbl);
+				pTiTbl->appendChild(pTiTmp);
+				pTiTmp = new QGfaMySqlSchemaTreeItem(MODEL_NAME_TABLE_COLLATION, tbl.szCollation, QVariant(), pTiTbl);
+				pTiTbl->appendChild(pTiTmp);
+
+				pTiTbls->appendChild(pTiTbl);
+			}
+
+			pTiDb->appendChild(pTiTbls);
+			m_pRootItem->appendChild(pTiDb);
+		}
+		endResetModel();
+	}
+	else
+	{
+		updateDatabaseValues(nCntDbs, pdbs);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+QGfaMySqlInfo::QGfaMySqlInfo(QObject *pParent) : QObject(pParent)
+{
+	memset(&m_sysInfoDbShadow, 0, sizeof(m_sysInfoDbShadow));
+}
+
+QGfaMySqlInfo::~QGfaMySqlInfo(void)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool QGfaMySqlInfo::isInit(void) const
+{
+	return m_sysInfoDbShadow.bIsInit;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Server
+
+bool QGfaMySqlInfo::svrRunning(void) const
+{
+	return m_sysInfoDbShadow.svr.bRunning;
+}
+
+void QGfaMySqlInfo::setSvrRunning(bool val)
+{
+	if(m_sysInfoDbShadow.svr.bRunning != val)
+	{
+		m_sysInfoDbShadow.svr.bRunning = val;
+		emit svrRunningChanged(m_sysInfoDbShadow.svr.bRunning);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool QGfaMySqlInfo::svrInnoDbFilePerTableSpace(void) const
+{
+	return m_sysInfoDbShadow.svr.bInnoDbFilePerTable;
+}
+
+void QGfaMySqlInfo::setSvrInnoDbFilePerTableSpace(bool val)
+{
+	if(m_sysInfoDbShadow.svr.bInnoDbFilePerTable != val)
+	{
+		m_sysInfoDbShadow.svr.bInnoDbFilePerTable = val;
+		emit svrInnoDbFilePerTableSpaceChanged(m_sysInfoDbShadow.svr.bInnoDbFilePerTable);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+qint32 QGfaMySqlInfo::svrPid(void) const
+{
+	return m_sysInfoDbShadow.svr.pid;
+}
+
+void QGfaMySqlInfo::setSvrPid(pid_t val)
+{
+	if(m_sysInfoDbShadow.svr.pid != val)
+	{
+		m_sysInfoDbShadow.svr.pid = val;
+		emit svrPidChanged(m_sysInfoDbShadow.svr.pid);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint64 QGfaMySqlInfo::svrUpTime(void) const
+{
+	return m_sysInfoDbShadow.svr.nUptimeSec;
+}
+
+void QGfaMySqlInfo::setSvrUpTime(time_t val)
+{
+	if(m_sysInfoDbShadow.svr.nUptimeSec != val)
+	{
+		m_sysInfoDbShadow.svr.nUptimeSec = val;
+		emit svrUpTimeChanged(m_sysInfoDbShadow.svr.nUptimeSec);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint64 QGfaMySqlInfo::svrDiscUsage(void) const
+{
+	return m_sysInfoDbShadow.svr.nDiscUsageTotal;
+}
+
+void QGfaMySqlInfo::setSvrDiscUsage(size_t val)
+{
+	if(m_sysInfoDbShadow.svr.nDiscUsageTotal != val)
+	{
+		m_sysInfoDbShadow.svr.nDiscUsageTotal = val;
+		emit svrDiscUsageChanged(m_sysInfoDbShadow.svr.nDiscUsageTotal);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+QString QGfaMySqlInfo::svrVersion(void) const
+{
+	return m_sysInfoDbShadow.svr.szVersion;
+}
+
+void QGfaMySqlInfo::setSvrVersion(const char *val)
+{
+	if(val && *val)
+	{
+		if(strcmp(m_sysInfoDbShadow.svr.szVersion, val))
+		{
+			if(strlen(val) < GFA_MYSQL_MAX_SVR_VERSION_LENGTH)
+			{
+				strcpy(m_sysInfoDbShadow.svr.szVersion, val);
+				emit svrVersionChanged(m_sysInfoDbShadow.svr.szVersion);
+			}
+		}
+	}
+	else if(*m_sysInfoDbShadow.svr.szVersion)
+	{
+		memset(m_sysInfoDbShadow.svr.szVersion, 0, GFA_MYSQL_MAX_SVR_VERSION_LENGTH);
+		emit svrVersionChanged(m_sysInfoDbShadow.svr.szVersion);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+QString QGfaMySqlInfo::svrDataDir(void) const
+{
+	return m_sysInfoDbShadow.svr.szDataDir;
+}
+
+void QGfaMySqlInfo::setSvrDataDir(const char *val)
+{
+	if(val && *val)
+	{
+		if(strcmp(m_sysInfoDbShadow.svr.szDataDir, val))
+		{
+			if(strlen(val) < GFA_MYSQL_MAX_DATADIR_LENGTH)
+			{
+				strcpy(m_sysInfoDbShadow.svr.szDataDir, val);
+				emit svrDataDirChanged(m_sysInfoDbShadow.svr.szDataDir);
+			}
+		}
+	}
+	else if(*m_sysInfoDbShadow.svr.szDataDir)
+	{
+		memset(m_sysInfoDbShadow.svr.szDataDir, 0, GFA_MYSQL_MAX_DATADIR_LENGTH);
+		emit svrDataDirChanged(m_sysInfoDbShadow.svr.szDataDir);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint32 QGfaMySqlInfo::svrNumDataBases(void) const
+{
+	return m_sysInfoDbShadow.nNumDatabases;
+}
+
+void QGfaMySqlInfo::setSvrNumDataBases(unsigned int val)
+{
+	if(m_sysInfoDbShadow.nNumDatabases != val)
+	{
+		m_sysInfoDbShadow.nNumDatabases = val;
+		emit svrNumDataBasesChanged(m_sysInfoDbShadow.nNumDatabases);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+QGfaMySqlSchemaModel* QGfaMySqlInfo::schemaModel(void)
+{
+	return &m_mySqlSchemaModel;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// CPU
+
+double QGfaMySqlInfo::cpuTime(void) const
+{
+	return m_sysInfoDbShadow.res.at.fCpuTime;
+}
+
+void QGfaMySqlInfo::setCpuTime(double val)
+{
+	if(m_sysInfoDbShadow.res.at.fCpuTime != val)
+	{
+		m_sysInfoDbShadow.res.at.fCpuTime = val;
+		emit cpuTimeChanged(m_sysInfoDbShadow.res.at.fCpuTime);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+double QGfaMySqlInfo::cpuCur(void) const
+{
+	return m_sysInfoDbShadow.res.at.fCpuCur;
+}
+
+void QGfaMySqlInfo::setCpuCur(double val)
+{
+	if(m_sysInfoDbShadow.res.at.fCpuCur != val)
+	{
+		m_sysInfoDbShadow.res.at.fCpuCur = val;
+		emit cpuCurChanged(m_sysInfoDbShadow.res.at.fCpuCur);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+double QGfaMySqlInfo::cpuAvg(void) const
+{
+	return m_sysInfoDbShadow.res.at.fCpuAvg;
+}
+
+void QGfaMySqlInfo::setCpuAvg(double val)
+{
+	if(m_sysInfoDbShadow.res.at.fCpuAvg != val)
+	{
+		m_sysInfoDbShadow.res.at.fCpuAvg = val;
+		emit cpuAvgChanged(m_sysInfoDbShadow.res.at.fCpuAvg);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Memory
+
+quint32 QGfaMySqlInfo::vmPeak(void) const
+{
+	return m_sysInfoDbShadow.res.am.vmPeak;
+}
+
+void QGfaMySqlInfo::setVmPeak(size_t val)
+{
+	if(m_sysInfoDbShadow.res.am.vmPeak != val)
+	{
+		m_sysInfoDbShadow.res.am.vmPeak = val;
+		emit vmPeakChanged(m_sysInfoDbShadow.res.am.vmPeak);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint32 QGfaMySqlInfo::vmSize(void) const
+{
+	return m_sysInfoDbShadow.res.am.vmSize;
+}
+
+void QGfaMySqlInfo::setVmSize(size_t val)
+{
+	if(m_sysInfoDbShadow.res.am.vmSize != val)
+	{
+		m_sysInfoDbShadow.res.am.vmSize = val;
+		emit vmSizeChanged(m_sysInfoDbShadow.res.am.vmSize);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint32 QGfaMySqlInfo::vmHWM(void) const
+{
+	return m_sysInfoDbShadow.res.am.vmHWM;
+}
+
+void QGfaMySqlInfo::setVmHWM(size_t val)
+{
+	if(m_sysInfoDbShadow.res.am.vmHWM != val)
+	{
+		m_sysInfoDbShadow.res.am.vmHWM = val;
+		emit vmHWMChanged(m_sysInfoDbShadow.res.am.vmHWM);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+quint32 QGfaMySqlInfo::vmRSS(void) const
+{
+	return m_sysInfoDbShadow.res.am.vmRSS;
+}
+
+void QGfaMySqlInfo::setVmRSS(size_t val)
+{
+	if(m_sysInfoDbShadow.res.am.vmRSS != val)
+	{
+		m_sysInfoDbShadow.res.am.vmRSS = val;
+		emit vmRSSChanged(m_sysInfoDbShadow.res.am.vmRSS);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void QGfaMySqlInfo::onMySqlInitEvent(bool val)
+{
+	if(m_sysInfoDbShadow.bIsInit != val)
+	{
+		m_sysInfoDbShadow.bIsInit = val;
+		emit isInitChanged(m_sysInfoDbShadow.bIsInit);
+
+		if(!m_sysInfoDbShadow.bIsInit)
+		{
+			setSvrRunning(false);
+			setSvrInnoDbFilePerTableSpace(false);
+			setSvrPid(0);
+			setSvrUpTime(0);
+			setSvrDiscUsage(0);
+			setSvrVersion(NULL);
+			setSvrDataDir(NULL);
+			setSvrNumDataBases(0);
+
+			setCpuTime(0);
+			setCpuCur(0);
+			setCpuAvg(0);
+
+			setVmPeak(0);
+			setVmSize(0);
+			setVmHWM(0);
+			setVmRSS(0);
+
+			m_mySqlSchemaModel.clearAll();
+		}
+	}
+}
+
+void QGfaMySqlInfo::onMySqlServerEvent(const GFA_MYSQL_SERVER &svr)
+{
+	setSvrRunning(svr.bRunning);
+	setSvrInnoDbFilePerTableSpace(svr.bInnoDbFilePerTable);
+	setSvrPid(svr.pid);
+	setSvrUpTime(svr.nUptimeSec);
+	setSvrDiscUsage(svr.nDiscUsageTotal);
+	setSvrVersion(svr.szVersion);
+	setSvrDataDir(svr.szDataDir);
+}
+
+void QGfaMySqlInfo::onMySqlResourceEvent(const GFA_MYSQL_RESOURCE &res)
+{
+	setCpuTime(res.at.fCpuTime);
+	setCpuCur(res.at.fCpuCur);
+	setCpuAvg(res.at.fCpuAvg);
+
+	setVmPeak(res.am.vmPeak);
+	setVmSize(res.am.vmSize);
+	setVmHWM(res.am.vmHWM);
+	setVmRSS(res.am.vmRSS);
+}
+
+void QGfaMySqlInfo::onMySqlDatabaseEvent(unsigned int nNumDatabases, LPCGFA_MYSQL_SCHEMA pdbs)
+{
+	setSvrNumDataBases(nNumDatabases);
+	m_mySqlSchemaModel.setModelData(nNumDatabases, pdbs);
+}
+
+/////////////////////////////////////////////////////////////////////////////

+ 5 - 61
src/qsysinfo.cpp

@@ -1,4 +1,5 @@
 #include "qappctrl.h"
 #include "qappctrl.h"
+#include "helpers.h"
 #include "defines.h"
 #include "defines.h"
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
@@ -14,63 +15,6 @@
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
-#define _BYTE_SIZE_KIB						(1ULL << 10) // Kibibyte
-#define _BYTE_SIZE_MIB						(1ULL << 20) // Mebibyte
-#define _BYTE_SIZE_GIB						(1ULL << 30) // Gibibyte
-#define _BYTE_SIZE_TIB						(1ULL << 40) // Tebibyte
-#define _BYTE_SIZE_PIB						(1ULL << 50) // Pebibyte
-#define _BYTE_SIZE_EIB						(1ULL << 60) // Exbibyte
-
-/////////////////////////////////////////////////////////////////////////////
-
-static const char *_FormatByteSize(unsigned long long nCb, char *pszBuf, size_t nCChBuf, bool bShortUnits = true, int nPrec = 1);
-
-/////////////////////////////////////////////////////////////////////////////
-
-static const char *_FormatByteSize(unsigned long long nCb, char *pszBuf, size_t nCChBuf, bool bShortUnits, int nPrec)
-{
-	if(pszBuf && nCChBuf)
-	{
-		double val = nCb;
-		
-		if(nCb < _BYTE_SIZE_KIB)
-		{
-			snprintf(pszBuf, nCChBuf, "%llu %s", nCb, bShortUnits ? "B" : "Byte"); // Byte
-		}
-		else if(nCb < _BYTE_SIZE_MIB)
-		{
-			val /= _BYTE_SIZE_KIB;
-			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "K" : "KiB"); // KiB
-		}
-		else if(nCb < _BYTE_SIZE_GIB)
-		{
-			val /= _BYTE_SIZE_MIB;
-			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "M" : "MiB"); // MiB
-		}
-		else if(nCb < _BYTE_SIZE_TIB)
-		{
-			val /= _BYTE_SIZE_GIB;
-			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "G" : "GiB"); // GiB
-		}
-		else if(nCb < _BYTE_SIZE_PIB)
-		{
-			val /= _BYTE_SIZE_TIB;
-			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "T" : "TiB"); // TiB
-		}
-		else if(nCb < _BYTE_SIZE_EIB)
-		{
-			val /= _BYTE_SIZE_PIB;
-			snprintf(pszBuf, nCChBuf, "%.*f %s", nPrec, val, bShortUnits ? "P" : "PiB"); // PiB
-		}
-		
-		return pszBuf;
-	}
-	
-	return NULL;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
 typedef enum
 typedef enum
 {
 {
     SDR_DiskName = Qt::UserRole,
     SDR_DiskName = Qt::UserRole,
@@ -192,16 +136,16 @@ QVariant QGfaStgDevList::data(const QModelIndex &index, int role) const
 			val = _NA_STRING(part.szMntPoint);
 			val = _NA_STRING(part.szMntPoint);
 			break;
 			break;
 		case SDR_PartSize:
 		case SDR_PartSize:
-			val = _FormatByteSize(part.nKiBPartSize * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
+			val = FormatByteSize(part.nKiBPartSize * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
 			break;
 			break;
 		case SDR_PartFsSize:
 		case SDR_PartFsSize:
-			val = _FormatByteSize(part.nKiBSize * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
+			val = FormatByteSize(part.nKiBSize * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
 			break;
 			break;
 		case SDR_PartFsFree:
 		case SDR_PartFsFree:
-			val = _FormatByteSize(part.nKiBFree * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
+			val = FormatByteSize(part.nKiBFree * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
 			break;
 			break;
 		case SDR_PartFsUsed:
 		case SDR_PartFsUsed:
-			val = _FormatByteSize(part.nKiBUsed * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
+			val = FormatByteSize(part.nKiBUsed * _BYTE_SIZE_KIB, szBuf, _countof(szBuf));
 			break;
 			break;
 		default:
 		default:
 			break;
 			break;