2025-03-14 16:06:20 +08:00
|
|
|
|
#include "dbManager.h"
|
|
|
|
|
|
#include "logger.h"
|
|
|
|
|
|
|
|
|
|
|
|
DatabaseManager::DatabaseManager(QObject* parent)
|
|
|
|
|
|
: QObject(parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DatabaseManager::~DatabaseManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
/*for(auto i = m_connections.constBegin(); i != m_connections.constEnd(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlDatabase db = i.value();
|
|
|
|
|
|
db.close();
|
|
|
|
|
|
QSqlDatabase::removeDatabase(i.key());
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
//见disconnect注释
|
|
|
|
|
|
QList<QString> keys = m_connections.keys();
|
|
|
|
|
|
for(int i = 0; i < keys.count(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlDatabase db = m_connections.take(keys.at(i));
|
|
|
|
|
|
db.close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DatabaseManager::addDatabase(const DatabaseConfig& config)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_configs.contains(config.strConnectionName))
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlError error(QString::fromWCharArray(L"配置信息错误"),
|
|
|
|
|
|
//QString("Connection name '%1' already exists").arg(config.strConnectionName),
|
|
|
|
|
|
QString::fromWCharArray(L"已存在同名的链接: '%1'").arg(config.strConnectionName),
|
|
|
|
|
|
QSqlError::ConnectionError);
|
2025-04-02 18:29:56 +08:00
|
|
|
|
emit errorOccurred(config.strConnectionName, error.databaseText());
|
2025-03-14 16:06:20 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(auto i = m_configs.constBegin(); i != m_configs.constEnd(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
DatabaseConfig c = i.value();
|
2025-04-03 09:45:47 +08:00
|
|
|
|
if(config.strHost == c.strHost && config.nPort == c.nPort && config.strDBType == c.strDBType
|
|
|
|
|
|
&& config.strDBName == c.strDBName)
|
2025-03-14 16:06:20 +08:00
|
|
|
|
{
|
|
|
|
|
|
QSqlError error(QString::fromWCharArray(L"配置信息错误"),
|
|
|
|
|
|
QString::fromWCharArray(L"'%1' 具有相同配置信息").arg(c.strConnectionName),
|
|
|
|
|
|
QSqlError::ConnectionError);
|
2025-04-02 18:29:56 +08:00
|
|
|
|
emit errorOccurred(config.strConnectionName, error.databaseText());
|
2025-03-14 16:06:20 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_configs[config.strConnectionName] = config;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2025-04-16 16:37:32 +08:00
|
|
|
|
void DatabaseManager::removeDatabase(const QString& strConnectionName)
|
|
|
|
|
|
{
|
|
|
|
|
|
//先断开链接
|
|
|
|
|
|
disconnect(strConnectionName);
|
|
|
|
|
|
//从内存中删除
|
|
|
|
|
|
m_configs.remove(strConnectionName);
|
|
|
|
|
|
}
|
2025-05-26 16:50:46 +08:00
|
|
|
|
void DatabaseManager::updataDatabase(const DatabaseConfig& config)
|
|
|
|
|
|
{
|
2025-05-30 18:51:23 +08:00
|
|
|
|
// if(m_configs.contains(config.strConnectionName))
|
|
|
|
|
|
// m_configs[config.strConnectionName] = config;
|
|
|
|
|
|
bool isExist = false;
|
|
|
|
|
|
QString strConnectionName;
|
|
|
|
|
|
for(auto i = m_configs.begin(); i != m_configs.end(); ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(i.value().strID == config.strID)
|
|
|
|
|
|
{
|
|
|
|
|
|
isExist = true;
|
|
|
|
|
|
strConnectionName = i.key();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if(isExist)
|
|
|
|
|
|
{
|
|
|
|
|
|
//通过先删除之前存储的信息再添加新的信息完成信息刷新
|
|
|
|
|
|
if(strConnectionName != config.strConnectionName)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_configs.remove(strConnectionName);
|
|
|
|
|
|
emit updateConnectionName(strConnectionName, config.strConnectionName);
|
|
|
|
|
|
}
|
2025-05-26 16:50:46 +08:00
|
|
|
|
m_configs[config.strConnectionName] = config;
|
2025-05-30 18:51:23 +08:00
|
|
|
|
}
|
2025-05-26 16:50:46 +08:00
|
|
|
|
}
|
2025-03-14 16:06:20 +08:00
|
|
|
|
|
|
|
|
|
|
bool DatabaseManager::connect(const QString& strConnectionName)
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_INFO("DB", QString("Connect to %1").arg(strConnectionName));
|
|
|
|
|
|
if(!m_configs.contains(strConnectionName))
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlError error(QString::fromWCharArray(L"配置信息错误"),
|
|
|
|
|
|
QString::fromWCharArray(L"没有找到该链接的配置信息"),
|
|
|
|
|
|
QSqlError::ConnectionError);
|
2025-04-02 18:29:56 +08:00
|
|
|
|
emit errorOccurred(strConnectionName, error.databaseText());
|
2025-03-14 16:06:20 +08:00
|
|
|
|
LOG_ERROR("DB", QString("Connection failed: %1 due 2%").arg(strConnectionName).arg("no configuration information"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const DatabaseConfig& config = m_configs[strConnectionName];
|
|
|
|
|
|
QSqlDatabase db = QSqlDatabase::addDatabase(config.strDBType, strConnectionName);
|
|
|
|
|
|
db.setHostName(config.strHost);
|
|
|
|
|
|
db.setPort(config.nPort);
|
|
|
|
|
|
db.setDatabaseName(config.strDBName);
|
|
|
|
|
|
db.setUserName(config.strUserName);
|
|
|
|
|
|
db.setPassword(config.strPassword);
|
2025-07-18 10:22:29 +08:00
|
|
|
|
db.setConnectOptions("client_encoding=UTF8");
|
2025-03-14 16:06:20 +08:00
|
|
|
|
|
|
|
|
|
|
if(!db.open())
|
|
|
|
|
|
{
|
2025-04-03 09:45:47 +08:00
|
|
|
|
QString errorText = db.lastError().databaseText();
|
2025-04-02 18:29:56 +08:00
|
|
|
|
LOG_ERROR("DB", QString("DB: %1 open failed. connectionName: %2. error: %3")
|
2025-03-14 16:06:20 +08:00
|
|
|
|
.arg(config.strDBName)
|
|
|
|
|
|
.arg(strConnectionName)
|
2025-07-18 10:22:29 +08:00
|
|
|
|
.arg(errorText/*QString::fromUtf8(errorText.toUtf8())*/));
|
2025-04-02 18:29:56 +08:00
|
|
|
|
emit errorOccurred(strConnectionName, QString::fromWCharArray(L"数据库打开失败,详情可见日志文件"));
|
2025-06-16 15:02:16 +08:00
|
|
|
|
db.close();
|
|
|
|
|
|
db = QSqlDatabase();//重置为无效数据库对象,在下面remove的时候就不会出现"connection '***' is still in use, all queries will cease to work"的警告
|
2025-03-14 16:06:20 +08:00
|
|
|
|
QSqlDatabase::removeDatabase(strConnectionName);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_connections[strConnectionName] = db;
|
|
|
|
|
|
emit connectionStatusChanged(strConnectionName, true);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
void DatabaseManager::disconnect(const QString& strConnectionName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_connections.contains(strConnectionName))
|
|
|
|
|
|
{
|
|
|
|
|
|
LOG_INFO("DB", QString("Disconnect to %1").arg(strConnectionName));
|
|
|
|
|
|
//按照官方文档,如果数据库移除了对象,db就是一个"悬空的无效数据库链接"(is now a dangling invalid database connection),因为被remove了,但是并没有被delete
|
|
|
|
|
|
//加上括号变成局部变量,超出括号后就被自动删除(delete)了,不会再出现"connection '***' is still in use, all queries will cease to work"的警告
|
|
|
|
|
|
{
|
|
|
|
|
|
QSqlDatabase db = m_connections.take(strConnectionName);
|
|
|
|
|
|
}
|
|
|
|
|
|
QSqlDatabase::removeDatabase(strConnectionName);
|
|
|
|
|
|
emit connectionStatusChanged(strConnectionName, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QStringList DatabaseManager::conncetions()
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_connections.keys();
|
|
|
|
|
|
}
|