稳定版本备份
This commit is contained in:
+153
-160
@@ -24,16 +24,20 @@
|
||||
#include <fstream>
|
||||
#include <qelapsedtimer.h>
|
||||
#include <QQueue>
|
||||
#include <quuid.h>
|
||||
#include <global.h>
|
||||
#include <qthread.h>
|
||||
class SQLiteDB {
|
||||
public:
|
||||
SQLiteDB(const QString& dbPath, const QString& dbName)
|
||||
: m_dbName(dbName), m_dbPath(dbPath) {
|
||||
QSqlDatabase db;
|
||||
SQLiteDB(const QString& dbPath)
|
||||
: dbPath(dbPath){
|
||||
connect();
|
||||
}
|
||||
~SQLiteDB() { disconnect(); };
|
||||
// 执行无返回值的SQL语句(如插入、删除、更新)
|
||||
bool execute(const QString& queryStr, const QVariantList& args = {}) {
|
||||
QSqlQuery query;
|
||||
QSqlQuery query(db);
|
||||
query.prepare(queryStr);
|
||||
|
||||
for (int i = 0; i < args.size(); ++i) {
|
||||
@@ -50,7 +54,7 @@ public:
|
||||
// 查询数据,返回结果集
|
||||
QList<QMap<QString, QVariant>> query(const QString& queryStr, const QVariantList& args = {}) {
|
||||
QList<QMap<QString, QVariant>> results;
|
||||
QSqlQuery query;
|
||||
QSqlQuery query(db);
|
||||
query.prepare(queryStr);
|
||||
|
||||
for (int i = 0; i < args.size(); ++i) {
|
||||
@@ -75,7 +79,7 @@ public:
|
||||
}
|
||||
// 检查数据库是否已连接
|
||||
bool isConnected() const {
|
||||
return m_db.isOpen();
|
||||
return db.isOpen();
|
||||
}
|
||||
////////////////BASE//////////////////////
|
||||
bool createTable(const QString& tableName, const QList<std::pair<QString, QString>>& columns) {
|
||||
@@ -93,7 +97,7 @@ public:
|
||||
QString sql = QString("CREATE TABLE IF NOT EXISTS \"%1\" (%2)")
|
||||
.arg(tableName)
|
||||
.arg(columnDefinitions.join(", "));
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
bool res = query.exec(sql);
|
||||
return res;
|
||||
}
|
||||
@@ -101,7 +105,7 @@ public:
|
||||
std::vector<QString> tables;
|
||||
// 查询所有表名,排除sqlite系统表
|
||||
QString sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';";
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
if (!query.exec(sql)) {
|
||||
qDebug() << "getTables failed:" << query.lastError().text();
|
||||
return tables;
|
||||
@@ -126,7 +130,7 @@ public:
|
||||
// 构造 SQL 语句
|
||||
QString sql = QString("ALTER TABLE \"%1\" ADD COLUMN \"%2\" %3").arg(tableName, columnName, columnType);
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
query.prepare(sql);
|
||||
|
||||
// 执行 SQL 语句
|
||||
@@ -177,10 +181,10 @@ public:
|
||||
|
||||
qDebug() << "Generated SQL: " << sql;
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
|
||||
// 检查数据库连接
|
||||
if (!m_db.isOpen()) {
|
||||
if (!db.isOpen()) {
|
||||
qDebug() << "Database is not open!";
|
||||
return false;
|
||||
}
|
||||
@@ -222,10 +226,10 @@ public:
|
||||
|
||||
qDebug() << "Generated SQL: " << sql;
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
|
||||
// 检查数据库连接
|
||||
if (!m_db.isOpen()) {
|
||||
if (!db.isOpen()) {
|
||||
qDebug() << "Database is not open!";
|
||||
return false;
|
||||
}
|
||||
@@ -256,7 +260,7 @@ public:
|
||||
.arg(tableName)
|
||||
.arg(whereClauses.join(" AND "));
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
query.prepare(sql);
|
||||
|
||||
// 绑定条件参数
|
||||
@@ -293,10 +297,10 @@ public:
|
||||
|
||||
qDebug() << "Generated SQL: " << sql;
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
|
||||
// 检查数据库连接
|
||||
if (!m_db.isOpen()) {
|
||||
if (!db.isOpen()) {
|
||||
qDebug() << "Database is not open!";
|
||||
return {};
|
||||
}
|
||||
@@ -332,7 +336,7 @@ public:
|
||||
// 查询表中的所有数据
|
||||
QString csvFileName = filePath;
|
||||
QString sql = QString("SELECT * FROM \"%1\"").arg(tableName);
|
||||
QSqlQuery query(m_db);
|
||||
QSqlQuery query(db);
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
qCritical() << "Query execution failed: " << query.lastError().text();
|
||||
@@ -386,23 +390,23 @@ public:
|
||||
|
||||
private:
|
||||
bool connect() {
|
||||
m_connectionName = QUuid::createUuid().toString();
|
||||
// 检查数据库文件是否存在
|
||||
if (!QFile::exists(m_dbPath + m_dbName + ".db")) {
|
||||
QDir().mkpath(m_dbPath);
|
||||
qDebug() << "Database file does not exist. Creating a new database:" << m_dbName;
|
||||
if (!QFile::exists(dbPath)) {
|
||||
QFileInfo fi(dbPath);
|
||||
QDir().mkpath(fi.absolutePath());
|
||||
qDebug() << "Database file does not exist. Creating a new database:" << dbPath;
|
||||
}
|
||||
QCoreApplication::addLibraryPath("./");
|
||||
// 添加 SQLite 数据库驱动
|
||||
m_db = QSqlDatabase::addDatabase("QSQLITE");
|
||||
m_db.setDatabaseName(m_dbPath + m_dbName + ".db");
|
||||
|
||||
db = QSqlDatabase::addDatabase("QSQLITE", m_connectionName);
|
||||
db.setDatabaseName(dbPath);
|
||||
|
||||
// 打开数据库
|
||||
if (!m_db.open()) {
|
||||
qCritical() << "Failed to open or create database:" << m_db.lastError().text();
|
||||
if (!db.open()) {
|
||||
qCritical() << "Failed to open or create database:" << db.lastError().text();
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "Connected to SQLite database:" << m_dbPath + m_dbName;
|
||||
qDebug() << "Connected to SQLite database:" << dbPath;
|
||||
createTable("setting",
|
||||
{
|
||||
{"id","INTEGER PRIMARY KEY AUTOINCREMENT"} ,
|
||||
@@ -411,23 +415,20 @@ private:
|
||||
}
|
||||
// 关闭数据库连接
|
||||
void disconnect() {
|
||||
if (m_db.isOpen()) {
|
||||
m_db.close();
|
||||
QSqlDatabase::removeDatabase(m_connectionName);
|
||||
if (db.isOpen()) {
|
||||
db.close();
|
||||
qDebug() << "Database closed.";
|
||||
}
|
||||
}
|
||||
QString m_dbName;
|
||||
QString m_dbPath;
|
||||
QSqlDatabase m_db;
|
||||
QString m_connectionName;
|
||||
QString dbPath;
|
||||
};
|
||||
|
||||
class CsvWriter
|
||||
{
|
||||
class CsvWriter : public QThread{
|
||||
public:
|
||||
CsvWriter(SQLiteDB* database_ptr = nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
CsvWriter(){
|
||||
try{
|
||||
m_json = readJsonFromPath("./sqldrivers/sqliteCfg.json");
|
||||
for (auto& data : m_json["数据列表"]) {
|
||||
db_InitColumns.append({ QString::fromStdString(data),"TEXT" });
|
||||
@@ -446,115 +447,36 @@ public:
|
||||
isNgDepends.push_back(QString::fromStdString(data));
|
||||
}
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
catch (const std::exception&){
|
||||
std::cerr << "readJsonFromPath error" << std::endl;
|
||||
}
|
||||
init(database_ptr);
|
||||
init();
|
||||
}
|
||||
~CsvWriter()
|
||||
{
|
||||
~CsvWriter(){
|
||||
//stopAutoExport();
|
||||
}
|
||||
std::map<QString, QString>csvAndChartLink;
|
||||
bool addtData(const QString& snCode, const std::map<QString, QVariant>& data) {
|
||||
try {
|
||||
if (snCode.isEmpty()) {
|
||||
qWarning() << "addtData: snCode is empty.";
|
||||
return false;
|
||||
}
|
||||
if (data.empty()) {
|
||||
qWarning() << "addtData: data is empty.";
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
QString currentProcessCsvName = getCurrentProcessCsvName();
|
||||
if (currentProcessCsvName != currentProcessCsvNameCache) {
|
||||
if (!_db->createTable(currentProcessCsvName, db_InitColumns)) {
|
||||
qWarning() << "addtData: Failed to create table:" << currentProcessCsvName;
|
||||
return false;
|
||||
}
|
||||
currentProcessCsvNameCache = currentProcessCsvName;
|
||||
}
|
||||
|
||||
// 获取当前表的所有列名
|
||||
QSqlQuery colQuery;
|
||||
QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName);
|
||||
QList<QString> tableColumns;
|
||||
if (colQuery.exec(colSql)) {
|
||||
while (colQuery.next()) {
|
||||
tableColumns.append(colQuery.value(1).toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 data 中的 key 是否在表结构中,不在则新增列
|
||||
for (const auto& kv : data) {
|
||||
if (!tableColumns.contains(kv.first)) {
|
||||
// 默认新增为 TEXT 类型
|
||||
if (!_db->addColumn(currentProcessCsvName, kv.first, "TEXT")) {
|
||||
qWarning() << "addtData: Failed to add column:" << kv.first << "to table:" << currentProcessCsvName;
|
||||
// 可选择 return false 或继续
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto res = _db->_search(currentProcessCsvName, {}, { {"条码",snCode} });
|
||||
|
||||
QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); // 精度提升到毫秒
|
||||
bool opResult = false;
|
||||
|
||||
if (res.empty()) {
|
||||
auto lastRes = _db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} });
|
||||
if (lastRes.empty()) {
|
||||
// 插入新数据
|
||||
std::map<QString, QVariant> insertData = data;
|
||||
insertData["条码"] = snCode;
|
||||
insertData["创建时间"] = nowTime;
|
||||
insertData["修改时间"] = nowTime;
|
||||
opResult = _db->_insert(currentProcessCsvName, insertData);
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode;
|
||||
}
|
||||
} else {
|
||||
// 更新过去的数据
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = nowTime;
|
||||
opResult = _db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 更新当前数据
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = nowTime;
|
||||
opResult = _db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
|
||||
if (timer.elapsed() > m_intervalMs) {
|
||||
exportCsv();
|
||||
timer.start();
|
||||
}
|
||||
return opResult;
|
||||
} catch (const std::exception& ex) {
|
||||
qCritical() << "addtData: Exception caught:" << ex.what();
|
||||
return false;
|
||||
} catch (...) {
|
||||
qCritical() << "addtData: Unknown exception caught.";
|
||||
return false;
|
||||
void addData(QString snCode, std::map<QString, QVariant> data) {
|
||||
|
||||
if (snCode.isEmpty()) {
|
||||
qWarning() << "addtData: snCode is empty.";
|
||||
return;
|
||||
}
|
||||
if (data.empty()) {
|
||||
qWarning() << "addtData: data is empty.";
|
||||
return;
|
||||
}
|
||||
queue.enqueue(std::make_pair(snCode, data));
|
||||
this->start();
|
||||
}
|
||||
bool isNewData(const QString& snCode) {
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
auto res = _db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} });
|
||||
auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} });
|
||||
return res.empty();
|
||||
}
|
||||
bool isNgData(const QString& snCode) {
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
auto res = _db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} });
|
||||
auto res = db->_search(getCurrentProcessCsvName(), {}, { {"条码",snCode} });
|
||||
if (res.empty() == true)
|
||||
return false;
|
||||
for (auto& data : isNgDepends) {
|
||||
@@ -563,11 +485,99 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void run() override{
|
||||
while (queue.size() > 0) {
|
||||
auto val = queue.dequeue();
|
||||
try {
|
||||
auto snCode = val.first;
|
||||
auto data = val.second;
|
||||
QString currentProcessCsvName = getCurrentProcessCsvName();
|
||||
if (currentProcessCsvName != currentProcessCsvNameCache) {
|
||||
if (!db->createTable(currentProcessCsvName, db_InitColumns)) {
|
||||
qWarning() << "addtData: Failed to create table:" << currentProcessCsvName;
|
||||
return;
|
||||
}
|
||||
currentProcessCsvNameCache = currentProcessCsvName;
|
||||
}
|
||||
// 获取当前表的所有列名
|
||||
QSqlQuery colQuery(db->db);
|
||||
QString colSql = QString("PRAGMA table_info(\"%1\")").arg(currentProcessCsvName);
|
||||
QList<QString> tableColumns;
|
||||
if (colQuery.exec(colSql)) {
|
||||
while (colQuery.next()) {
|
||||
tableColumns.append(colQuery.value(1).toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 data 中的 key 是否在表结构中,不在则新增列
|
||||
for (const auto& kv : data) {
|
||||
if (!tableColumns.contains(kv.first)) {
|
||||
// 默认新增为 TEXT 类型
|
||||
if (!db->addColumn(currentProcessCsvName, kv.first, "TEXT")) {
|
||||
qWarning() << "addtData: Failed to add column:" << kv.first << "to table:" << currentProcessCsvName;
|
||||
// 可选择 return false 或继续
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto res = db->_search(currentProcessCsvName, {}, { {"条码",snCode} });
|
||||
|
||||
QString nowTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); // 精度提升到毫秒
|
||||
bool opResult = false;
|
||||
|
||||
if (res.empty()) {
|
||||
auto lastRes = db->_search(getLastProcessCsvName(), {}, { {"条码",snCode} });
|
||||
if (lastRes.empty()) {
|
||||
// 插入新数据
|
||||
std::map<QString, QVariant> insertData = data;
|
||||
insertData["条码"] = snCode;
|
||||
insertData["创建时间"] = nowTime;
|
||||
insertData["修改时间"] = nowTime;
|
||||
opResult = db->_insert(currentProcessCsvName, insertData);
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Insert failed for table:" << currentProcessCsvName << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 更新过去的数据
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = nowTime;
|
||||
opResult = db->_update(getLastProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Update failed for table:" << getLastProcessCsvName() << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 更新当前数据
|
||||
std::map<QString, QVariant> updateData = data;
|
||||
updateData["修改时间"] = nowTime;
|
||||
opResult = db->_update(getCurrentProcessCsvName(), updateData, { {"条码",snCode} });
|
||||
if (!opResult) {
|
||||
qWarning() << "addtData: Update failed for table:" << getCurrentProcessCsvName() << "snCode:" << snCode;
|
||||
}
|
||||
}
|
||||
|
||||
//if (timer.elapsed() > m_intervalMs) {
|
||||
// exportCsv();
|
||||
// timer.start();
|
||||
//}
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
qCritical() << "addtData: Exception caught:" << ex.what();
|
||||
}
|
||||
catch (...) {
|
||||
qCritical() << "addtData: Unknown exception caught.";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
private:
|
||||
QQueue<std::pair<QString,std::map<QString, QVariant>>> queue;
|
||||
std::vector<QString> isNgDepends;
|
||||
QQueue<std::pair< QString, std::map<QString, QVariant>> > addDataCacheQueue;
|
||||
std::mutex _mutex;
|
||||
SQLiteDB* _db;
|
||||
SQLiteDB* db;
|
||||
int m_intervalMs = 10000;
|
||||
QElapsedTimer timer;
|
||||
QString currentProcessCsvNameCache;
|
||||
@@ -579,36 +589,19 @@ private:
|
||||
{"修改时间", "TEXT"},
|
||||
{"CT", "TEXT"},
|
||||
};
|
||||
//void run()
|
||||
//{
|
||||
// init();
|
||||
// while (m_running == true) {
|
||||
// QThread::msleep(m_intervalMs);
|
||||
// while (addDataCacheQueue.empty() == false)
|
||||
// {
|
||||
// auto data = addDataCacheQueue.dequeue();
|
||||
// addtData(data.first, data.second);
|
||||
// }
|
||||
// exportCsv();
|
||||
// }
|
||||
// delete _db;
|
||||
//}
|
||||
void init(SQLiteDB* database_ptr = nullptr){
|
||||
void init(){
|
||||
std::lock_guard<std::mutex> locker(_mutex);
|
||||
if (database_ptr == nullptr)
|
||||
_db = new SQLiteDB("./sqlDatabse/", "database");
|
||||
else
|
||||
_db = database_ptr;
|
||||
if (!_db->createTable(getLastProcessCsvName(), db_InitColumns)) {
|
||||
db = new SQLiteDB(globalDatabasePth);
|
||||
if (!db->createTable(getLastProcessCsvName(), db_InitColumns)) {
|
||||
qDebug() << "Failed to create table " << getLastProcessCsvName();
|
||||
}
|
||||
currentProcessCsvNameCache = getCurrentProcessCsvName();
|
||||
if (!_db->createTable(currentProcessCsvNameCache, db_InitColumns)) {
|
||||
if (!db->createTable(currentProcessCsvNameCache, db_InitColumns)) {
|
||||
qDebug() << "Failed to create table " << currentProcessCsvNameCache;
|
||||
}
|
||||
for (auto& data : db_newCol) {
|
||||
_db->addColumn(getLastProcessCsvName(), data.first, data.second);
|
||||
_db->addColumn(getCurrentProcessCsvName(), data.first, data.second);
|
||||
db->addColumn(getLastProcessCsvName(), data.first, data.second);
|
||||
db->addColumn(getCurrentProcessCsvName(), data.first, data.second);
|
||||
}
|
||||
timer.start();
|
||||
}
|
||||
@@ -676,12 +669,12 @@ private:
|
||||
void exportCsv(){
|
||||
//std::lock_guard<std::mutex> locker(_mutex);
|
||||
QString name = getLastProcessCsvName();
|
||||
_db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex);
|
||||
db->exportTableToCSV(name, "./csv/"+ name +".csv", _mutex);
|
||||
name = getCurrentProcessCsvName();
|
||||
_db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex);
|
||||
db->exportTableToCSV(name, "./csv/" + name + ".csv", _mutex);
|
||||
QString currentProcessCsvName = getCurrentProcessCsvName();
|
||||
if (currentProcessCsvName != currentProcessCsvNameCache)
|
||||
if (!_db->createTable(currentProcessCsvName, db_InitColumns)) {
|
||||
if (!db->createTable(currentProcessCsvName, db_InitColumns)) {
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user