1 增加数据核心执行类支持多线程

2 增加参数设置窗口
3 设计参数设置的基本选择控件类
This commit is contained in:
work-zym\zhangyiming 2024-11-08 14:04:55 +08:00
parent 8dc3d18f96
commit e96f28a706
4 changed files with 263 additions and 0 deletions

View File

@ -0,0 +1,202 @@
#include "CSqlCore.h"
#include <QThread>
#include <QDebug>
#include <QSqlError>
#include <QFile>
#include "global_log.h"
using namespace UiFramework;
QMap<QString, QMap<QString, QMutex*>> CSqlCore::mutexMap;
QString CSqlCore::msDriverName;
QString CSqlCore::msPasswd;
QString CSqlCore::msUserName;
QString CSqlCore::msDBFile;
QMutex CSqlCore::mWriteMutex;
void CSqlCore::init(QString sDriver, QString sUser, QString sPasswd, QString sDBFile)
{
QByteArray base64User(sUser.toUtf8());
QByteArray base64Passwd(sPasswd.toUtf8());
msDriverName = sDriver;
msUserName = base64User.toBase64();
msPasswd = base64Passwd.toBase64();
msDBFile = sDBFile;
}
bool CSqlCore::setKey(QString sDriver,QString sConnect, QString sUser, QString sPasswd, QString sdbFile)
{
bool ok = false;
QSqlDatabase dataBase = QSqlDatabase::addDatabase(sDriver, sConnect);
if (QFile::exists(sdbFile))
{
QByteArray base64User(sUser.toUtf8());
QByteArray base64Passwd(sPasswd.toUtf8());
dataBase.setUserName(base64User.toBase64());
dataBase.setDatabaseName(sdbFile);//
dataBase.setPassword(base64Passwd.toBase64());
if (sPasswd.isEmpty())
{
dataBase.setConnectOptions("QSQLITE_REMOVE_KEY");
logInfo() << QString::fromLocal8Bit("解密") << endl;
}
else
{
dataBase.setConnectOptions("QSQLITE_CREATE_KEY");
logInfo() << QString::fromLocal8Bit("加密") << endl;
}
if (!dataBase.open())
{
logError() << QString::fromLocal8Bit("密码错误") << endl;
ok = false;
}
else
{
ok = true;
}
}
dataBase.close();
return ok;
}
bool CSqlCore::updateKey(QString NewsPasswd, QString oldPasswd)
{
bool ok = false;
getSqlDataBase().setPassword(oldPasswd);
getSqlDataBase().setConnectOptions("QSQLITE_UPDATE_KEY=" + NewsPasswd);
ok = getSqlDataBase().open();
if (!ok)
{
logError() << "updatePasswd: " << getSqlDataBase().lastError().driverText();
ok = false;
}
return ok;
}
bool CSqlCore::execute(QString sql )
{
QMutexLocker lockTemp(&mWriteMutex);
QString connName = QString("%1(%2)").arg(msDBFile).arg(QString::number(qint64(QThread::currentThread()), 16));//文件名 + 线程
//qDebug() << "execute:" << connName << endl;
QSqlDatabase t = getSqlDataBase( );
mutexMap[msDBFile][connName]->lock();
if (!t.isOpen())
t.open(msUserName,msPasswd);
QSqlQuery sqlQuery(t);
bool flag = sqlQuery.exec(sql);
if (!flag)
{
logError() << connName << sqlQuery.lastError().text() << endl;
}
mutexMap[msDBFile][connName]->unlock();
return flag;
}
QSharedPointer<QSqlQuery> CSqlCore::select(QString sql)
{
//QMutexLocker lockTemp(&mWriteMutex);
QString connName = QString("%1(%2)").arg(msDBFile).arg(QString::number(qint64(QThread::currentThread()), 16));//文件名 + 线程
//qDebug() << "select:" << connName << endl;
QSqlDatabase t = getSqlDataBase();
mutexMap[msDBFile][connName]->lock();
if (!t.isOpen())
t.open(msUserName,msPasswd);
// QSqlQuery *sqlQuery = new QSqlQuery(t);
//QSharedPointer<QSqlQuery> sqlQuery = new QSharedPointer<QSqlQuery(t)>;
QSharedPointer<QSqlQuery> sqlQuery = QSharedPointer<QSqlQuery>(new QSqlQuery(t));
if (!sqlQuery->exec(sql)) {
logError() << "CSqlCore::select() sql = " << sql << sqlQuery->lastError().text() << " failed!" << endl;
}
mutexMap[msDBFile][connName]->unlock();
return sqlQuery;
}
QSharedPointer<QSqlQuery> CSqlCore::select(QString sql, bool& ok)
{
//QMutexLocker lockTemp(&mWriteMutex);
QString connName = QString("%1(%2)").arg(msDBFile).arg(QString::number(qint64(QThread::currentThread()), 16));//文件名 + 线程
//qDebug() << "select:" << connName << endl;
QSqlDatabase t = getSqlDataBase();
mutexMap[msDBFile][connName]->lock();
if (!t.isOpen())
t.open(msUserName, msPasswd);
// QSqlQuery *sqlQuery = new QSqlQuery(t);
//QSharedPointer<QSqlQuery> sqlQuery = new QSharedPointer<QSqlQuery(t)>;
QSharedPointer<QSqlQuery> sqlQuery = QSharedPointer<QSqlQuery>(new QSqlQuery(t));
ok = sqlQuery->exec(sql);
if (!ok)
{
logError() << "CSqlCore::select() sql = " << sql << sqlQuery->lastError().text() << " failed!" << endl;
}
mutexMap[msDBFile][connName]->unlock();
return sqlQuery;
}
void CSqlCore::destroyConn()
{
QString connName = QString("%1(%2)").arg(msDBFile).arg(QString::number(qint64(QThread::currentThread()), 16));//文件名 + 线程
//qDebug() << "destroyConn:" << connName << endl;
if (!QSqlDatabase::contains( connName))
return;
QSqlDatabase t = QSqlDatabase::database(connName);
if (t.isOpen())
t.close();
QSqlDatabase::removeDatabase( connName);
delete mutexMap[msDBFile][connName];
mutexMap[msDBFile].remove(connName);
if (mutexMap[msDBFile].keys().length() == 0)
mutexMap.remove(msDBFile);
}
void CSqlCore::destroyOneDBConn()
{
// foreach (QString i, mutexMap[msDBFile].keys())
{
destroyConn();
}
}
void CSqlCore::destroyAllDBConn()
{
// foreach (QString i, mutexMap.keys())
// {
destroyOneDBConn();
// }
}
QSqlDatabase CSqlCore::getSqlDataBase()
{
QString connName = QString("%1(%2)").arg(msDBFile).arg(QString::number(qint64(QThread::currentThread()), 16));//文件名 + 线程
if (!QSqlDatabase::contains(connName))
{
QSqlDatabase database = QSqlDatabase::addDatabase(msDriverName, connName);
database.setDatabaseName(msDBFile);
database.setUserName(msUserName);
database.setPassword(msPasswd);
if (!mutexMap.contains(msDBFile))
{
QMap<QString, QMutex*> tMap;
mutexMap.insert(msDBFile, tMap);
}
if (database.isOpen() || database.open())
{
QSqlQuery query(database);
query.exec("PRAGMA journal_mode=WAL;"); // 设置WAL模式
query.finish();
query.clear();
}
else
{
logWarning() << "DB open failed! " << database.lastError().text() << endl;
}
QMutex *mutex = new QMutex();
mutexMap[msDBFile].insert(connName, mutex);
}
return QSqlDatabase::database( connName);
}

View File

@ -0,0 +1,57 @@
#pragma execution_character_set("utf-8")
#ifndef CSqlCore_H
#define CSqlCore_H
/*
\author: zym
\brief :
\version 1.0
\note
\CopyRight:zym
*/
#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMutex>
#include <QMap>
#include <QSharedPointer>
//数据库操作类
//使用QMutex 对 连接 加锁,适用于多线程
//但建议经常同时操作同一数据库的线程 使用 不同的连接名,因为锁的互斥等待会增大处理时间
//(数据库中实际的连接名是"dbFile+connName",但若使用此类的封装则不用关心实际的连接名)
namespace UiFramework
{
class CSqlCore : public QObject
{
Q_OBJECT
public:
//以connName连接对数据库dbFile执行sql语句该sql语句无返回值函数返回执行成功/失败
//若该连接已存在则则获取,不存在则创建再获取
static bool execute(QString sql);
static QSharedPointer<QSqlQuery>select(QString sql, bool& ok);
//以connName连接对数据库dbFile执行sql语句该sql语句有返回值通过QSqlQuery::next()不断获取数据行
//若该连接已存在则则获取,不存在则创建再获取
static QSharedPointer<QSqlQuery>select(QString sql);
//删除db文件dbFile的connName连接和其对应的锁
static void destroyConn();
//删除db文件dbFile的所有连接和锁
static void destroyOneDBConn();
//删除所有db文件的所有连接和锁
static void destroyAllDBConn();
static QSqlDatabase getSqlDataBase();
static void init(QString sDriver, QString sUser, QString sPasswd, QString sDBFile);
static bool setKey(QString sDriver, QString sConnect, QString sUser, QString sPasswd, QString sdbFile);
static bool updateKey(QString NewsPasswd, QString oldPasswd);
private:
//获取对于dbFile文件的数据库连接connName
//有则返回,没有则创建再返回
//同步锁外层key是db文件名内层key是该db文件的数据库连接名
static QMap<QString, QMap<QString, QMutex*>> mutexMap;
static QString msDriverName;
static QString msUserName;
static QString msPasswd;
static QString msDBFile;
static QMutex mWriteMutex;
};
}
#endif // CSqlCore_H

View File

@ -0,0 +1,4 @@
#ifndef PARAMETERSETTINGSWIDGET_H
#define PARAMETERSETTINGSWIDGET_H
#endif // PARAMETERSETTINGSWIDGET_H