#ifndef LICENSEMANAGER_LICENSEMODEL_H #define LICENSEMANAGER_LICENSEMODEL_H /** * @file LicenseModel.h * @brief Модель данных клиентов и операции с базой SQLite. * * @details * Класс инкапсулирует структуру таблицы клиентов и обеспечивает * асинхронные операции чтения/добавления/редактирования/удаления. */ // Qt #include #include #include /** * @brief Табличная модель клиентов и лицензий. * * @details * Хранит данные в памяти, синхронизируясь с SQLite. Все операции, * требующие доступа к БД, выполняются в отдельных потоках. */ class LicenseModel : public QAbstractItemModel { Q_OBJECT public: /** * @brief Состояние модели и базы данных. */ enum class Status { None = 0, //!< Состояние не определено. Ok, //!< База данных готова. DbStructError, //!< Ошибка структуры или запроса к БД. DbExistError, //!< Ошибка открытия базы данных. Working, //!< Выполняется операция с БД. }; /** * @brief Запись клиента в базе. */ struct LicenseItem { QString id; //!< Идентификатор строки в БД. QString city; //!< Город. QString email; //!< Электронная почта. QString firstName; //!< Имя. QString hardwareHash; //!< Аппаратный хеш (machine id). QString lastName; //!< Фамилия. QString patronymic; //!< Отчество. QString phone; //!< Телефон. QString yourCompany; //!< Название компании. QString licenseTime; //!< Срок лицензии (пусто = бессрочно). QString comment; //!< Комментарий. }; /** * @brief Результат асинхронной операции с БД. */ struct Result { QList data; //!< Данные, полученные из БД. QStringList ids; //!< Список id, над которыми выполнялась операция. Status status = Status::Ok; //!< Итоговый статус операции. QString error; //!< Текст ошибки (если есть). }; /** * @brief Создаёт модель и выполняет первичную проверку БД. */ explicit LicenseModel(QObject* parent = nullptr); /** * @brief Возвращает количество строк модели. */ int rowCount(const QModelIndex &parent = QModelIndex()) const override; /** * @brief Возвращает количество столбцов модели. */ int columnCount(const QModelIndex &parent = QModelIndex()) const override; /** * @brief Возвращает отображаемые данные для ячейки. */ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; /** * @brief Возвращает заголовки строк/столбцов. */ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; /** * @brief Табличная модель не имеет иерархии. */ QModelIndex parent(const QModelIndex &index) const override; /** * @brief Возвращает индекс ячейки по координатам. */ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; /** * @brief Возвращает текущий статус модели. */ Status getStatus(); /** * @brief Возвращает текст ошибок, накопленных моделью. */ QString getStatusText(); /** * @brief Создаёт таблицы БД из ресурса `tables.ddl`. */ bool prepareDatabase(); /** * @brief Добавляет клиента в БД и обновляет модель. */ void addClient(const LicenseItem &item); /** * @brief Удаляет клиентов по индексам строк. */ void deleteClient(const QList &rows); /** * @brief Обновляет клиента по индексу строки. */ void editClient(const LicenseItem &item, int index); /** * @brief Перезагружает модель из базы данных. */ void updateModel(); /** * @brief Возвращает запись клиента по индексу строки. */ LicenseItem getItem(int index) const; signals: /** * @brief Сигнал изменения статуса модели. */ void statusChanged(); private: /** * @brief Проверяет наличие таблиц БД. */ bool checkTables(); private: QList m_data; //!< Кэш данных для отображения. Status m_status = Status::None; //!< Текущий статус модели. QStringList m_errors; //!< Список ошибок работы с БД. }; #endif // LICENSEMANAGER_LICENSEMODEL_H