fort/src/ui/db/databasemanager.cpp

266 lines
7.4 KiB
C++
Raw Normal View History

2017-12-01 14:13:06 +00:00
#include "databasemanager.h"
#include <QDateTime>
#include "../util/fileutil.h"
2017-12-04 13:55:03 +00:00
#include "databasesql.h"
2017-12-01 14:13:06 +00:00
#include "sqlite/sqliteengine.h"
#include "sqlite/sqlitedb.h"
#include "sqlite/sqlitestmt.h"
DatabaseManager::DatabaseManager(const QString &filePath,
QObject *parent) :
QObject(parent),
2017-12-04 13:55:03 +00:00
m_lastUnixHour(0),
m_lastUnixDay(0),
m_lastUnixMonth(0),
2017-12-01 14:13:06 +00:00
m_filePath(filePath),
m_sqliteDb(new SqliteDb())
{
SqliteEngine::initialize();
}
DatabaseManager::~DatabaseManager()
{
qDeleteAll(m_sqliteStmts.values());
delete m_sqliteDb;
SqliteEngine::shutdown();
}
bool DatabaseManager::initialize()
{
const bool fileExists = FileUtil::fileExists(m_filePath);
if (!m_sqliteDb->open(m_filePath))
return false;
2017-12-04 13:55:03 +00:00
m_sqliteDb->execute(DatabaseSql::sqlPragmas);
2017-12-01 14:13:06 +00:00
return fileExists || createTables();
}
void DatabaseManager::handleProcNew(const QString &appPath)
{
const qint64 appId = getAppId(appPath);
m_appPaths.append(appPath);
m_appIds.append(appId);
}
void DatabaseManager::handleStatTraf(quint16 procCount, const quint8 *procBits,
const quint32 *trafBytes)
{
QVector<quint16> delProcIndexes;
2017-12-04 13:55:03 +00:00
const qint64 unixTime = QDateTime::currentSecsSinceEpoch();
const qint32 unixHour = qint32(unixTime / 3600);
const bool isNewHour = (unixHour != m_lastUnixHour);
const qint32 unixDay = isNewHour ? getUnixDay(unixTime)
: m_lastUnixDay;
const bool isNewDay = (unixDay != m_lastUnixDay);
const qint32 unixMonth = isNewDay ? getUnixMonth(unixTime)
: m_lastUnixMonth;
const bool isNewMonth = (unixMonth != m_lastUnixMonth);
SqliteStmt *stmtInsertAppHour = nullptr;
SqliteStmt *stmtInsertAppDay = nullptr;
SqliteStmt *stmtInsertAppMonth = nullptr;
SqliteStmt *stmtInsertHour = nullptr;
SqliteStmt *stmtInsertDay = nullptr;
SqliteStmt *stmtInsertMonth = nullptr;
if (isNewHour) {
m_lastUnixHour = unixHour;
stmtInsertAppHour = getSqliteStmt(DatabaseSql::sqlInsertTrafficAppHour);
stmtInsertHour = getSqliteStmt(DatabaseSql::sqlInsertTrafficHour);
stmtInsertAppHour->bindInt(1, unixHour);
stmtInsertHour->bindInt(1, unixHour);
if (isNewDay) {
m_lastUnixDay = unixDay;
stmtInsertAppDay = getSqliteStmt(DatabaseSql::sqlInsertTrafficAppDay);
stmtInsertDay = getSqliteStmt(DatabaseSql::sqlInsertTrafficDay);
2017-12-01 14:13:06 +00:00
2017-12-04 13:55:03 +00:00
stmtInsertAppDay->bindInt(1, unixDay);
stmtInsertDay->bindInt(1, unixDay);
2017-12-01 14:13:06 +00:00
2017-12-04 13:55:03 +00:00
if (isNewMonth) {
m_lastUnixMonth = unixMonth;
stmtInsertAppMonth = getSqliteStmt(DatabaseSql::sqlInsertTrafficAppMonth);
stmtInsertMonth = getSqliteStmt(DatabaseSql::sqlInsertTrafficMonth);
stmtInsertAppMonth->bindInt(1, unixMonth);
stmtInsertMonth->bindInt(1, unixMonth);
}
}
}
SqliteStmt *stmtUpdateAppHour = getSqliteStmt(DatabaseSql::sqlUpdateTrafficAppHour);
SqliteStmt *stmtUpdateAppDay = getSqliteStmt(DatabaseSql::sqlUpdateTrafficAppDay);
SqliteStmt *stmtUpdateAppMonth = getSqliteStmt(DatabaseSql::sqlUpdateTrafficAppMonth);
SqliteStmt *stmtUpdateHour = getSqliteStmt(DatabaseSql::sqlUpdateTrafficHour);
SqliteStmt *stmtUpdateDay = getSqliteStmt(DatabaseSql::sqlUpdateTrafficDay);
SqliteStmt *stmtUpdateMonth = getSqliteStmt(DatabaseSql::sqlUpdateTrafficMonth);
stmtUpdateAppHour->bindInt(1, unixHour);
stmtUpdateAppDay->bindInt(1, unixDay);
stmtUpdateAppMonth->bindInt(1, unixMonth);
stmtUpdateHour->bindInt(1, unixHour);
stmtUpdateDay->bindInt(1, unixDay);
stmtUpdateMonth->bindInt(1, unixMonth);
2017-12-01 14:13:06 +00:00
m_sqliteDb->beginTransaction();
for (quint16 procIndex = 0; procIndex < procCount; ++procIndex) {
const bool active = procBits[procIndex / 8] & (1 << (procIndex & 7));
if (!active) {
delProcIndexes.append(procIndex);
}
const quint32 *procTrafBytes = &trafBytes[procIndex * 2];
const quint32 inBytes = procTrafBytes[0];
const quint32 outBytes = procTrafBytes[1];
2017-12-04 13:55:03 +00:00
if (!(isNewHour || inBytes || outBytes))
continue;
const qint64 appId = m_appIds.at(procIndex);
// Insert zero bytes
if (isNewHour) {
insertTraffic(stmtInsertAppHour, appId);
insertTraffic(stmtInsertHour);
2017-12-01 14:13:06 +00:00
2017-12-04 13:55:03 +00:00
if (isNewDay) {
insertTraffic(stmtInsertAppDay, appId);
insertTraffic(stmtInsertDay);
2017-12-01 14:13:06 +00:00
2017-12-04 13:55:03 +00:00
if (isNewMonth) {
insertTraffic(stmtInsertAppMonth, appId);
insertTraffic(stmtInsertMonth);
}
}
2017-12-01 14:13:06 +00:00
}
2017-12-04 13:55:03 +00:00
// Update bytes
updateTraffic(stmtUpdateAppHour, inBytes, outBytes, appId);
updateTraffic(stmtUpdateAppDay, inBytes, outBytes, appId);
updateTraffic(stmtUpdateAppMonth, inBytes, outBytes, appId);
updateTraffic(stmtUpdateHour, inBytes, outBytes);
updateTraffic(stmtUpdateDay, inBytes, outBytes);
updateTraffic(stmtUpdateMonth, inBytes, outBytes);
2017-12-01 14:13:06 +00:00
}
m_sqliteDb->commitTransaction();
// Delete inactive processes
{
int i = delProcIndexes.size();
while (--i >= 0) {
const quint16 procIndex = delProcIndexes.at(i);
m_appPaths.removeAt(procIndex);
m_appIds.removeAt(procIndex);
}
}
}
bool DatabaseManager::createTables()
{
2017-12-04 13:55:03 +00:00
return m_sqliteDb->execute(DatabaseSql::sqlCreateTables);
2017-12-01 14:13:06 +00:00
}
qint64 DatabaseManager::getAppId(const QString &appPath)
{
qint64 appId = 0;
// Check existing
{
2017-12-04 13:55:03 +00:00
SqliteStmt *stmt = getSqliteStmt(DatabaseSql::sqlSelectAppId);
2017-12-01 14:13:06 +00:00
stmt->bindText(1, appPath);
if (stmt->step() == SqliteStmt::StepRow) {
appId = stmt->columnInt64();
}
stmt->reset();
}
// Create new one
if (!appId) {
2017-12-04 13:55:03 +00:00
SqliteStmt *stmt = getSqliteStmt(DatabaseSql::sqlInsertAppId);
2017-12-01 14:13:06 +00:00
stmt->bindText(1, appPath);
if (stmt->step() == SqliteStmt::StepDone) {
appId = m_sqliteDb->lastInsertRowid();
}
stmt->reset();
}
return appId;
}
SqliteStmt *DatabaseManager::getSqliteStmt(const char *sql)
{
SqliteStmt *stmt = m_sqliteStmts.value(sql);
if (stmt == nullptr) {
stmt = new SqliteStmt();
stmt->prepare(m_sqliteDb->db(), sql, SqliteStmt::PreparePersistent);
m_sqliteStmts.insert(sql, stmt);
}
return stmt;
}
2017-12-04 13:55:03 +00:00
void DatabaseManager::insertTraffic(SqliteStmt *stmt, qint64 appId)
{
if (appId != 0) {
stmt->bindInt64(2, appId);
}
stmt->step();
stmt->reset();
}
void DatabaseManager::updateTraffic(SqliteStmt *stmt, quint32 inBytes,
quint32 outBytes, qint64 appId)
{
stmt->bindInt64(2, inBytes);
stmt->bindInt64(3, outBytes);
if (appId != 0) {
stmt->bindInt64(4, appId);
}
stmt->step();
stmt->reset();
}
qint32 DatabaseManager::getUnixDay(qint64 unixTime)
{
const QDate date = QDateTime::fromSecsSinceEpoch(unixTime).date();
return qint32(QDateTime(date).toSecsSinceEpoch() / 3600);
}
qint32 DatabaseManager::getUnixMonth(qint64 unixTime)
{
const QDate date = QDateTime::fromSecsSinceEpoch(unixTime).date();
return qint32(QDateTime(QDate(date.year(), date.month(), 1))
.toSecsSinceEpoch() / 3600);
}