first commit
This commit is contained in:
+928
@@ -0,0 +1,928 @@
|
||||
#include "udatabase.h"
|
||||
#include <QMetaProperty>
|
||||
#include <QSqlRecord>
|
||||
#include <QDateTime>
|
||||
#include <QTableWidget>
|
||||
|
||||
#include "qlistwidget.h"
|
||||
|
||||
uDataBase::uDataBase(const QString& dbFileName, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_dbFileName(dbFileName)
|
||||
{
|
||||
// Создаем уникальное имя подключения
|
||||
QString connectionName = QString("settings_connection_%1").arg((quintptr)this);
|
||||
|
||||
// Открываем базу данных
|
||||
m_db = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
||||
m_db.setDatabaseName(m_dbFileName);
|
||||
|
||||
if (!m_db.open()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
qWarning() << "Failed to open database:" << m_lastError;
|
||||
return;
|
||||
}
|
||||
|
||||
// Инициализируем базу данных
|
||||
if (!initializeDatabase()) {
|
||||
qWarning() << "Failed to initialize database";
|
||||
}
|
||||
}
|
||||
|
||||
uDataBase::~uDataBase()
|
||||
{
|
||||
if (m_db.isOpen()) {
|
||||
QString connectionName = m_db.connectionName();
|
||||
m_db.close();
|
||||
m_db = QSqlDatabase(); // сбрасываем объект базы данных
|
||||
QSqlDatabase::removeDatabase(connectionName); // удаляем соединение
|
||||
}
|
||||
}
|
||||
|
||||
bool uDataBase::close()
|
||||
{
|
||||
if (!isConnected()) {
|
||||
return true; // Уже закрыто
|
||||
}
|
||||
|
||||
// Сохраняем имя соединения перед закрытием
|
||||
QString connectionName = m_db.connectionName();
|
||||
|
||||
// Закрываем базу данных
|
||||
m_db.close();
|
||||
|
||||
// Очищаем объект базы данных
|
||||
m_db = QSqlDatabase();
|
||||
|
||||
// Удаляем соединение из пула Qt
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::initializeDatabase()
|
||||
{
|
||||
// Создаем таблицу настроек, если она не существует
|
||||
QString createTableQuery =
|
||||
"CREATE TABLE IF NOT EXISTS params ("
|
||||
"name TEXT PRIMARY KEY,"
|
||||
"value TEXT"
|
||||
")";
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (!query.exec(createTableQuery)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to create table:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString uDataBase::readSetting(const QString& aName, const QString& aDefault)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
qWarning() << "Database is not open";
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("SELECT value FROM params WHERE name = :name");
|
||||
query.bindValue(":name", aName);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to read setting" << aName << ":" << m_lastError;
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
if (query.next()) {
|
||||
return query.value(0).toString();
|
||||
}
|
||||
|
||||
// Если настройка не найдена, возвращаем значение по умолчанию
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
bool uDataBase::writeSetting(const QString& aName, const QString& aValue)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
qWarning() << "Database is not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Используем INSERT OR REPLACE для обновления существующей записи или создания новой
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare(
|
||||
"INSERT OR REPLACE INTO params (name, value) "
|
||||
"VALUES (:name, :value)"
|
||||
);
|
||||
query.bindValue(":name", aName);
|
||||
query.bindValue(":value", aValue);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to write setting" << aName << ":" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// В классе uDataBase добавьте эти методы:
|
||||
|
||||
/**
|
||||
* @brief Специальная загрузка для таблицы таймеров с сохранением состояния
|
||||
* @param tableWidget Таблица для загрузки
|
||||
* @param timers Список таймеров для заполнения
|
||||
* @return true если успешно
|
||||
*/
|
||||
bool uDataBase::LoadTimers(QTableWidget *tableWidget, QList<TimerInfo> &timers)
|
||||
{
|
||||
if (!tableWidget) {
|
||||
m_lastError = "Table widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем имя таблицы из objectName виджета
|
||||
QString tableName = tableWidget->objectName();
|
||||
if (tableName.isEmpty()) {
|
||||
m_lastError = "Table widget has no object name";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Очищаем таблицу и список таймеров
|
||||
tableWidget->setRowCount(0);
|
||||
timers.clear();
|
||||
|
||||
// Выполняем SQL запрос
|
||||
QSqlQuery query(m_db);
|
||||
QString sql = QString("SELECT * FROM %1 ORDER BY id").arg(tableName);
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Query failed:" << m_lastError;
|
||||
qWarning() << "SQL:" << sql;
|
||||
return false;
|
||||
}
|
||||
|
||||
int rowCount = 0;
|
||||
while (query.next()) {
|
||||
// Создаем объект таймера
|
||||
TimerInfo timer;
|
||||
timer.id = query.value("id").toInt();
|
||||
timer.message = query.value("message").toString();
|
||||
timer.interval = query.value("interval").toInt();
|
||||
timer.isActive = query.value("is_active").toBool();
|
||||
timer.isAnnouncement = query.value("is_announcement").toBool();
|
||||
timer.timer = nullptr;
|
||||
|
||||
// Добавляем в список
|
||||
timers.append(timer);
|
||||
|
||||
// Добавляем строку в таблицу
|
||||
int row = tableWidget->rowCount();
|
||||
tableWidget->insertRow(row);
|
||||
|
||||
// Чекбокс "Вкл"
|
||||
QTableWidgetItem* enabledItem = new QTableWidgetItem();
|
||||
enabledItem->setCheckState(timer.isActive ? Qt::Checked : Qt::Unchecked);
|
||||
tableWidget->setItem(row, 0, enabledItem);
|
||||
|
||||
// Сообщение
|
||||
QTableWidgetItem* messageItem = new QTableWidgetItem(timer.message);
|
||||
tableWidget->setItem(row, 1, messageItem);
|
||||
|
||||
// Интервал
|
||||
QTableWidgetItem* intervalItem = new QTableWidgetItem(QString::number(timer.interval));
|
||||
tableWidget->setItem(row, 2, intervalItem);
|
||||
|
||||
// Чекбокс "О"
|
||||
QTableWidgetItem* announcementItem = new QTableWidgetItem();
|
||||
announcementItem->setCheckState(timer.isAnnouncement ? Qt::Checked : Qt::Unchecked);
|
||||
tableWidget->setItem(row, 3, announcementItem);
|
||||
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Специальное сохранение для таблицы таймеров
|
||||
* @param tableWidget Таблица для сохранения
|
||||
* @param timers Список таймеров
|
||||
* @return true если успешно
|
||||
*/
|
||||
bool uDataBase::SaveTimers(QTableWidget *tableWidget, const QList<TimerInfo> &timers)
|
||||
{
|
||||
if (!tableWidget) {
|
||||
m_lastError = "Table widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем имя таблицы из objectName виджета
|
||||
QString tableName = tableWidget->objectName();
|
||||
if (tableName.isEmpty()) {
|
||||
m_lastError = "Table widget has no object name";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Создаем таблицу если не существует
|
||||
QString createTableQuery = QString(
|
||||
"CREATE TABLE IF NOT EXISTS %1 ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
"message TEXT NOT NULL,"
|
||||
"interval INTEGER NOT NULL,"
|
||||
"is_active BOOLEAN DEFAULT 1,"
|
||||
"is_announcement BOOLEAN DEFAULT 0"
|
||||
")"
|
||||
).arg(tableName);
|
||||
|
||||
QSqlQuery createQuery(m_db);
|
||||
if (!createQuery.exec(createTableQuery)) {
|
||||
m_lastError = createQuery.lastError().text();
|
||||
qWarning() << "Failed to create table:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Начинаем транзакцию
|
||||
if (!m_db.transaction()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
qWarning() << "Failed to start transaction:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Очищаем таблицу
|
||||
QSqlQuery clearQuery(m_db);
|
||||
QString clearSql = QString("DELETE FROM %1").arg(tableName);
|
||||
if (!clearQuery.exec(clearSql)) {
|
||||
m_lastError = clearQuery.lastError().text();
|
||||
qWarning() << "Failed to clear table:" << m_lastError;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Сохраняем таймеры
|
||||
QSqlQuery insertQuery(m_db);
|
||||
insertQuery.prepare(QString(
|
||||
"INSERT INTO %1 (message, interval, is_active, is_announcement) "
|
||||
"VALUES (:message, :interval, :is_active, :is_announcement)"
|
||||
).arg(tableName));
|
||||
|
||||
int savedRows = 0;
|
||||
for (const TimerInfo &timer : timers) {
|
||||
insertQuery.bindValue(":message", timer.message);
|
||||
insertQuery.bindValue(":interval", timer.interval);
|
||||
insertQuery.bindValue(":is_active", timer.isActive);
|
||||
insertQuery.bindValue(":is_announcement", timer.isAnnouncement);
|
||||
|
||||
if (!insertQuery.exec()) {
|
||||
m_lastError = insertQuery.lastError().text();
|
||||
qWarning() << "Failed to insert timer:" << m_lastError;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
savedRows++;
|
||||
}
|
||||
|
||||
// Завершаем транзакцию
|
||||
if (!m_db.commit()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
qWarning() << "Failed to commit transaction:" << m_lastError;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "Saved" << savedRows << "timers to database";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::LoadTableWidget(QTableWidget *tableWidget)
|
||||
{
|
||||
if (!tableWidget) {
|
||||
m_lastError = "Table widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем имя таблицы из objectName виджета
|
||||
QString tableName = tableWidget->objectName();
|
||||
if (tableName.isEmpty()) {
|
||||
m_lastError = "Table widget has no object name";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Очищаем таблицу (но сохраняем заголовки)
|
||||
tableWidget->setRowCount(0);
|
||||
|
||||
// Выполняем SQL запрос
|
||||
QSqlQuery query(m_db);
|
||||
QString sql = QString("SELECT * FROM %1 ORDER BY id").arg(tableName);
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Query failed:" << m_lastError;
|
||||
qWarning() << "SQL:" << sql;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем информацию о колонках в результате запроса
|
||||
QSqlRecord record = query.record();
|
||||
int dbColumnCount = record.count();
|
||||
|
||||
// Определяем сколько колонок нам нужно в QTableWidget
|
||||
int widgetColumnCount = tableWidget->columnCount();
|
||||
int columnsToLoad = qMin(dbColumnCount - 1, widgetColumnCount); // -1 потому что пропускаем id
|
||||
|
||||
int rowCount = 0;
|
||||
while (query.next()) {
|
||||
// Добавляем новую строку
|
||||
int row = tableWidget->rowCount();
|
||||
tableWidget->insertRow(row);
|
||||
|
||||
// Заполняем ячейки (начиная с col0, пропускаем id)
|
||||
for (int col = 0; col < columnsToLoad; col++) {
|
||||
QString columnName = QString("col%1").arg(col);
|
||||
QVariant value = query.value(columnName);
|
||||
|
||||
QTableWidgetItem *item = new QTableWidgetItem();
|
||||
if (value.isNull()) {
|
||||
item->setText("");
|
||||
} else {
|
||||
item->setText(value.toString());
|
||||
}
|
||||
|
||||
// Устанавливаем выравнивание по умолчанию
|
||||
item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
tableWidget->setItem(row, col, item);
|
||||
}
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::SaveTableWidget(QTableWidget *tableWidget)
|
||||
{
|
||||
if (!tableWidget) {
|
||||
m_lastError = "Table widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем имя таблицы из objectName виджета
|
||||
QString tableName = tableWidget->objectName();
|
||||
if (tableName.isEmpty()) {
|
||||
m_lastError = "Table widget has no object name";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем существует ли таблица
|
||||
if (!tableExists(tableName)) {
|
||||
// Создаем таблицу с нужным количеством колонок
|
||||
if (!createTableForWidget(tableName, tableWidget->columnCount())) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Очищаем существующую таблицу
|
||||
if (!clearTable(tableName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем данные из таблицы
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
// Начинаем транзакцию для быстрой вставки
|
||||
if (!m_db.transaction()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
qWarning() << "Failed to start transaction:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
int rowCount = tableWidget->rowCount();
|
||||
int colCount = tableWidget->columnCount();
|
||||
|
||||
if (colCount == 0) {
|
||||
m_lastError = "Table widget has no columns";
|
||||
qWarning() << m_lastError;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Подготавливаем SQL запрос для вставки
|
||||
QStringList columnNames;
|
||||
QStringList valuePlaceholders;
|
||||
|
||||
// Добавляем id (автоинкремент)
|
||||
columnNames << "id";
|
||||
valuePlaceholders << "NULL";
|
||||
|
||||
// Добавляем col0, col1, col2 и т.д.
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
columnNames << QString("col%1").arg(col);
|
||||
valuePlaceholders << QString(":col%1").arg(col);
|
||||
}
|
||||
|
||||
QString sql = QString("INSERT INTO %1 (%2) VALUES (%3)")
|
||||
.arg(tableName)
|
||||
.arg(columnNames.join(", "))
|
||||
.arg(valuePlaceholders.join(", "));
|
||||
|
||||
query.prepare(sql);
|
||||
|
||||
int savedRows = 0;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
// Пропускаем пустые строки (если все ячейки пустые)
|
||||
bool isEmptyRow = true;
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
QTableWidgetItem *item = tableWidget->item(row, col);
|
||||
if (item && !item->text().trimmed().isEmpty()) {
|
||||
isEmptyRow = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmptyRow) {
|
||||
continue; // Пропускаем полностью пустые строки
|
||||
}
|
||||
|
||||
// Биндим значения для каждой колонки
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
QString paramName = QString(":col%1").arg(col);
|
||||
QTableWidgetItem *item = tableWidget->item(row, col);
|
||||
|
||||
if (item && !item->text().isEmpty()) {
|
||||
query.bindValue(paramName, item->text());
|
||||
} else {
|
||||
query.bindValue(paramName, QVariant(QVariant::String));
|
||||
}
|
||||
}
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to insert row:" << m_lastError;
|
||||
qWarning() << "SQL:" << sql;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
savedRows++;
|
||||
}
|
||||
|
||||
// Завершаем транзакцию
|
||||
if (!m_db.commit()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
qWarning() << "Failed to commit transaction:" << m_lastError;
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Вспомогательные методы
|
||||
bool uDataBase::tableExists(const QString &tableName)
|
||||
{
|
||||
QSqlQuery query(m_db);
|
||||
QString sql = QString("SELECT name FROM sqlite_master WHERE type='table' AND name='%1'")
|
||||
.arg(tableName);
|
||||
|
||||
if (query.exec(sql) && query.next()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool uDataBase::createTableForWidget(const QString &tableName, int columnCount)
|
||||
{
|
||||
if (columnCount <= 0) {
|
||||
m_lastError = "Invalid column count";
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
// Создаем SQL для создания таблицы
|
||||
QStringList columns;
|
||||
columns << "id INTEGER PRIMARY KEY AUTOINCREMENT";
|
||||
|
||||
for (int i = 0; i < columnCount; i++) {
|
||||
columns << QString("col%1 TEXT").arg(i);
|
||||
}
|
||||
|
||||
QString sql = QString("CREATE TABLE %1 (%2)").arg(tableName).arg(columns.join(", "));
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to create table:" << m_lastError;
|
||||
qWarning() << "SQL:" << sql;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::clearTable(const QString &tableName)
|
||||
{
|
||||
QSqlQuery query(m_db);
|
||||
QString sql = QString("DELETE FROM %1").arg(tableName);
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to clear table:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Сбрасываем автоинкремент
|
||||
sql = QString("DELETE FROM sqlite_sequence WHERE name='%1'").arg(tableName);
|
||||
query.exec(sql); // Игнорируем ошибки, т.к. может не быть sqlite_sequence
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool uDataBase::LoadRandomGroups(QListWidget *listWidget)
|
||||
{
|
||||
if (!listWidget) {
|
||||
m_lastError = "List widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
listWidget->clear();
|
||||
m_lastError.clear();
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем существование таблицы
|
||||
if (!tableExists("GroupResponse")) {
|
||||
qWarning() << "Table GroupResponse doesn't exist";
|
||||
// Можно создать таблицу автоматически
|
||||
if (!createGroupResponseTable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Выполняем SQL запрос для получения уникальных имен
|
||||
QSqlQuery query(m_db);
|
||||
QString sql = "SELECT DISTINCT Name FROM GroupResponse ORDER BY Name";
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Query failed:" << m_lastError;
|
||||
qWarning() << "SQL:" << sql;
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (query.next()) {
|
||||
QString groupName = query.value(0).toString();
|
||||
if (!groupName.isEmpty()) {
|
||||
listWidget->addItem(groupName);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Метод для загрузки ответов конкретной группы
|
||||
bool uDataBase::LoadRandomResponses(const QString &groupName, QListWidget *listWidget)
|
||||
{
|
||||
if (!listWidget) {
|
||||
m_lastError = "List widget is null";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (groupName.isEmpty()) {
|
||||
m_lastError = "Group name is empty";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
listWidget->clear();
|
||||
m_lastError.clear();
|
||||
|
||||
// Проверяем соединение с БД
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем существование таблицы
|
||||
if (!tableExists("GroupResponse")) {
|
||||
m_lastError = "Table GroupResponse doesn't exist";
|
||||
qWarning() << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Выполняем SQL запрос для получения ответов группы
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("SELECT Response FROM GroupResponse WHERE Name = :name ORDER BY id");
|
||||
query.bindValue(":name", groupName);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Query failed:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (query.next()) {
|
||||
QString response = query.value(0).toString();
|
||||
listWidget->addItem(response);
|
||||
count++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Метод для получения случайного ответа из группы
|
||||
QString uDataBase::GetRandomResponse(const QString &groupName)
|
||||
{
|
||||
if (groupName.isEmpty()) {
|
||||
qWarning() << "Group name is empty";
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
qWarning() << "Database is not open";
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!tableExists("GroupResponse")) {
|
||||
qWarning() << "Table GroupResponse doesn't exist";
|
||||
return QString();
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("SELECT Response FROM GroupResponse WHERE Name = :name ORDER BY RANDOM() LIMIT 1");
|
||||
query.bindValue(":name", groupName);
|
||||
|
||||
if (!query.exec()) {
|
||||
qWarning() << "Query failed for group:" << groupName << "Error:" << query.lastError().text();
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (!query.next()) {
|
||||
qWarning() << "No responses found for group:" << groupName;
|
||||
return QString();
|
||||
}
|
||||
|
||||
return query.value(0).toString();
|
||||
}
|
||||
// Метод для обработки текста с заменой {{grN}}
|
||||
QString uDataBase::ProcessResponseTemplate(const QString &templateText)
|
||||
{
|
||||
QRegularExpression re("\\{\\{(.+?)\\}\\}");
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(templateText);
|
||||
|
||||
QString result = templateText;
|
||||
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch match = i.next();
|
||||
QString fullMatch = match.captured(0); // {{ANY_GROUP_NAME}}
|
||||
QString groupName = match.captured(1).trimmed(); // ANY_GROUP_NAME
|
||||
|
||||
if (groupName.isEmpty()) {
|
||||
continue; // Пропускаем пустые имена групп
|
||||
}
|
||||
|
||||
QString replacement = GetRandomResponse(groupName);
|
||||
|
||||
if (replacement.isEmpty()) {
|
||||
qWarning() << "No response found for group:" << groupName;
|
||||
// Можно оставить оригинальный текст или заменить на что-то другое
|
||||
replacement = QString("[Группа '%1' не найдена]").arg(groupName);
|
||||
}
|
||||
|
||||
result.replace(fullMatch, replacement);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
// Методы для добавления/удаления групп и ответов
|
||||
bool uDataBase::AddGroupResponse(const QString &groupName, const QString &response)
|
||||
{
|
||||
if (groupName.isEmpty() || response.isEmpty()) {
|
||||
m_lastError = "Group name or response is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Создаем таблицу если она не существует
|
||||
if (!tableExists("GroupResponse")) {
|
||||
if (!createGroupResponseTable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("INSERT INTO GroupResponse (Name, Response) VALUES (:name, :response)");
|
||||
query.bindValue(":name", groupName);
|
||||
query.bindValue(":response", response);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to add response:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::DeleteGroup(const QString &groupName)
|
||||
{
|
||||
if (groupName.isEmpty()) {
|
||||
m_lastError = "Group name is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("DELETE FROM GroupResponse WHERE Name = :name");
|
||||
query.bindValue(":name", groupName);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to delete group:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::DeleteResponse(const QString &groupName, const QString &ResponseName)
|
||||
{
|
||||
if (groupName.isEmpty()) {
|
||||
m_lastError = "Group name is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Получаем ID ответа по индексу в группе
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
// Удаляем ответ по ID
|
||||
query.prepare("DELETE FROM GroupResponse WHERE Name = :name and Response = :response");
|
||||
query.bindValue(":name", groupName);
|
||||
query.bindValue(":response", ResponseName);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to delete response:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Вспомогательные методы
|
||||
bool uDataBase::createGroupResponseTable()
|
||||
{
|
||||
QSqlQuery query(m_db);
|
||||
QString sql =
|
||||
"CREATE TABLE IF NOT EXISTS GroupResponse ("
|
||||
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
" Name TEXT NOT NULL,"
|
||||
" Response TEXT NOT NULL"
|
||||
")";
|
||||
|
||||
if (!query.exec(sql)) {
|
||||
m_lastError = query.lastError().text();
|
||||
qWarning() << "Failed to create GroupResponse table:" << m_lastError;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Создаем индекс для быстрого поиска по имени группы
|
||||
sql = "CREATE INDEX IF NOT EXISTS idx_groupresponse_name ON GroupResponse (Name)";
|
||||
query.exec(sql); // Игнорируем ошибки, если индекс уже существует
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Метод для сохранения списка ответов группы (заменяет все существующие)
|
||||
bool uDataBase::SaveGroupResponses(const QString &groupName, const QStringList &responses)
|
||||
{
|
||||
if (groupName.isEmpty()) {
|
||||
m_lastError = "Group name is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
m_lastError = "Database is not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Начинаем транзакцию
|
||||
if (!m_db.transaction()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Удаляем старые ответы группы
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("DELETE FROM GroupResponse WHERE Name = :name");
|
||||
query.bindValue(":name", groupName);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Добавляем новые ответы
|
||||
query.prepare("INSERT INTO GroupResponse (Name, Response) VALUES (:name, :response)");
|
||||
|
||||
foreach (const QString &response, responses) {
|
||||
if (!response.trimmed().isEmpty()) {
|
||||
query.bindValue(":name", groupName);
|
||||
query.bindValue(":response", response);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_lastError = query.lastError().text();
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_db.commit()) {
|
||||
m_lastError = m_db.lastError().text();
|
||||
m_db.rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uDataBase::isConnected() const
|
||||
{
|
||||
return m_db.isOpen();
|
||||
}
|
||||
|
||||
QString uDataBase::lastError() const
|
||||
{
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user