12#include <QLoggingCategory>
13#include "RecentDatabase.h"
15#include "RabbitCommonDir.h"
17static Q_LOGGING_CATEGORY(log,
"App.Recent.Db")
22int CRecentDatabase::RecentItem::SetFile(
const QString& file) {
27QString CRecentDatabase::RecentItem::GetFile() {
31CRecentDatabase::CRecentDatabase(QObject *parent)
34 qDebug(log) << Q_FUNC_INFO;
37CRecentDatabase::~CRecentDatabase()
39 qDebug(log) << Q_FUNC_INFO;
46 if(!bRet)
return false;
49 bRet = m_IconDB.
SetDatabase(GetDatabase(), m_pPara);
50 if(!bRet)
return bRet;
51 bRet = m_FileDB.
SetDatabase(GetDatabase(), m_pPara);
55bool CRecentDatabase::OnInitializeSqliteDatabase()
57 QSqlQuery query(GetDatabase());
61 "CREATE TABLE IF NOT EXISTS recent ("
62 " id INTEGER PRIMARY KEY AUTOINCREMENT,"
63 " operate_id TEXT NOT NULL,"
64 " icon INTEGER DEFAULT 0,"
65 " name TEXT NOT NULL,"
68 " file TEXT UNIQUE NOT NULL,"
69 " time DATETIME DEFAULT CURRENT_TIMESTAMP,"
72 bool success = query.exec(szSql);
75 SetError(
"Failed to create recent table: " + query.lastError().text()
77 qCritical(log) << GetError();
82 success = query.exec(
"CREATE INDEX IF NOT EXISTS idx_recent_file ON recent(file)");
84 qWarning(log) <<
"Failed to drop index idx_recent_file:"
85 << query.lastError().text()
86 <<
"Sql:" << query.executedQuery();
89 if (!query.exec(
"DROP TRIGGER IF EXISTS delete_icon_after_recent")) {
90 qDebug(log) <<
"Failed to drop trigger delete_icon_after_recent:"
91 << query.lastError().text()
92 <<
"Sql:" << query.executedQuery();
96 CREATE TRIGGER delete_icon_after_recent
97 AFTER DELETE ON recent
104 SELECT 1 FROM favorite WHERE icon = OLD.icon
107 SELECT 1 FROM recent WHERE icon = OLD.icon
111 success = query.exec(szSql);
113 qWarning(log) <<
"Failed to create trigger delete_icon_after_recent."
114 << query.lastError().text()
115 <<
"Sql:" << query.executedQuery();
121bool CRecentDatabase::OnInitializeMySqlDatabase()
123 bool success =
false;
124 QSqlQuery query(GetDatabase());
128 "CREATE TABLE IF NOT EXISTS recent ("
129 " id INTEGER PRIMARY KEY AUTO_INCREMENT,"
130 " operate_id TEXT NOT NULL,"
131 " icon INTEGER DEFAULT 0,"
132 " name TEXT NOT NULL,"
134 " operate_type TEXT,"
135 " file TEXT NOT NULL,"
136 " time DATETIME DEFAULT CURRENT_TIMESTAMP,"
138 " UNIQUE KEY uk_recent_file (file(255))"
140 success = query.exec(szSql);
142 SetError(
"Failed to create recent table: " + query.lastError().text()
143 +
"; Sql: " + szSql);
144 qCritical(log) << GetError();
149 if (!query.exec(
"DROP TRIGGER IF EXISTS delete_icon_after_recent")) {
150 qDebug(log) <<
"Failed to drop trigger delete_icon_after_recent:"
151 << query.lastError().text()
152 <<
"Sql:" << query.executedQuery();
156 CREATE TRIGGER delete_icon_after_recent
157 AFTER DELETE ON recent
160 DECLARE favorite_count INT DEFAULT 0;
161 DECLARE recent_count INT DEFAULT 0;
163 IF OLD.icon != 0 THEN
164 -- 统计favorite表中引用该icon的数量
165 SELECT COUNT(*) INTO favorite_count
167 WHERE icon = OLD.icon;
169 -- 统计recent表中引用该icon的数量
170 SELECT COUNT(*) INTO recent_count
172 WHERE icon = OLD.icon;
175 IF favorite_count = 0 AND recent_count = 0 THEN
176 DELETE FROM icon WHERE id = OLD.icon;
181 success = query.exec(szSql);
183 qWarning(log) <<
"Failed to create trigger delete_icon_after_recent."
184 << query.lastError().text()
185 <<
"Sql:" << query.executedQuery();
191int CRecentDatabase::AddRecent(
const RecentItem &item)
193 QSqlQuery query(GetDatabase());
194 if(item.szFile.isEmpty())
197 "SELECT id FROM recent "
200 query.bindValue(
":file", item.szFile);
201 if (query.exec() && query.next()) {
203 int id = query.value(0).toInt();
209 "description=:description "
212 query.bindValue(
":name", item.szName);
213 query.bindValue(
":time", item.time);
214 query.bindValue(
":description", item.szDescription);
215 query.bindValue(
":id",
id);
218 "INSERT INTO recent (operate_id, icon, name, protocol, operate_type, file, time, description)"
219 "VALUES (:operate_id, :icon, :name, :protocol, :type, :file, :time, :description)"
221 query.bindValue(
":operate_id", item.szOperateId);
222 query.bindValue(
":icon", m_IconDB.
GetIcon(item.icon));
223 query.bindValue(
":name", item.szName);
224 query.bindValue(
":protocol", item.szProtocol);
225 query.bindValue(
":type", item.szType);
226 query.bindValue(
":file", item.szFile);
227 query.bindValue(
":time", item.time);
228 query.bindValue(
":description", item.szDescription);
230 bool success = query.exec();
232 SetError(
"Failed to add recent: " + query.lastError().text()
233 +
"; Sql: " + query.executedQuery());
234 qCritical(log) << GetError();
238 qDebug(log) <<
"Insert recent id:" << query.lastInsertId().toInt();
240 return query.lastInsertId().toInt();
243bool CRecentDatabase::UpdateRecent(
const RecentItem& item)
245 return UpdateRecent(item.szFile, item.szName, item.szDescription);
248bool CRecentDatabase::UpdateRecent(
249 const QString &szFile,
const QString& szName,
const QString& szDescription)
251 QSqlQuery query(GetDatabase());
256 "description=:description "
259 query.bindValue(
":name", szName);
260 query.bindValue(
":file", szFile);
261 query.bindValue(
":description", szDescription);
263 bool success = query.exec();
265 SetError(
"Failed to update recent: " + query.lastError().text()
266 +
"; Sql: " + query.executedQuery());
267 qCritical(log) << GetError();
273bool CRecentDatabase::DeleteRecent(
int id)
275 if(0 >=
id)
return false;
276 QSqlQuery query(GetDatabase());
277 query.prepare(
"DELETE FROM recent WHERE id=:id");
278 query.bindValue(
":id",
id);
279 bool success = query.exec();
281 SetError(
"Failed to delete recent: " + query.lastError().text()
282 +
"; Sql: " + query.executedQuery()
283 +
"; id: " + QString::number(
id));
284 qCritical(log) << GetError();
289QList<CRecentDatabase::RecentItem> CRecentDatabase::GetRecents(
int limit,
int offset)
291 QList<RecentItem> items;
293 QSqlQuery query(GetDatabase());
296 "SELECT id, operate_id, icon, name, protocol, operate_type, file, time, description "
298 "ORDER BY time DESC "
302 "SELECT id, operate_id, icon, name, protocol, operate_type, file, time, description "
304 "ORDER BY time DESC "
305 "LIMIT :limit OFFSET :offset"
307 query.bindValue(
":limit", limit);
308 query.bindValue(
":offset", offset);
311 while (query.next()) {
313 item.id = query.value(0).toInt();
314 item.szOperateId = query.value(1).toString();
315 item.icon = m_IconDB.
GetIcon(query.value(2).toInt());
316 item.szName = query.value(3).toString();
317 item.szProtocol = query.value(4).toString();
318 item.szType = query.value(5).toString();
319 item.szFile = query.value(6).toString();
320 item.time = query.value(7).toDateTime();
321 item.szDescription = query.value(8).toString();
325 SetError(
"Failed to get recents: " + query.lastError().text()
326 +
"; Sql: " + query.executedQuery());
327 qCritical(log) << GetError();
333bool CRecentDatabase::HasFileContents(
const RecentItem &item)
335 return m_FileDB.IsExist(item.szFile);
338bool CRecentDatabase::ExportToJson(QJsonObject &obj)
341 auto items = GetRecents();
342 foreach(
auto it, items) {
348 itemObj.insert(
"OperateId", it.szOperateId);
350 bRet = CDatabaseIcon::ExportIconToJson(it.icon, itemObj);
353 itemObj.insert(
"Name", it.szName);
354 itemObj.insert(
"Protocol", it.szProtocol);
355 itemObj.insert(
"Type", it.szType);
356 itemObj.insert(
"Time", it.time.toString());
357 itemObj.insert(
"Description", it.szDescription);
359 recents.append(itemObj);
361 if(recents.isEmpty())
363 obj.insert(
"Recent", recents);
367bool CRecentDatabase::ImportFromJson(
const QJsonObject &obj)
369 QJsonArray recents = obj[
"Recent"].toArray();
370 if(recents.isEmpty()){
371 SetError(tr(
"The file format is error. Don't find \"recents\""));
372 qCritical(log) << GetError();
376 for(
auto it = recents.begin(); it != recents.end(); it++) {
377 QJsonObject itemObj = it->toObject();
384 item.SetFile(szFile);
386 QSqlQuery query(GetDatabase());
388 "SELECT id FROM recent "
391 query.bindValue(
":file", item.szFile);
392 if (query.exec() && query.next()) {
396 bRet = CDatabaseIcon::ImportIconFromJson(itemObj, item.icon);
399 item.szOperateId = itemObj[
"OperateId"].toString();
400 item.szName = itemObj[
"Name"].toString();
401 item.szProtocol = itemObj[
"Protocol"].toString();
402 item.szType = itemObj[
"Type"].toString();
404 item.time = QDateTime::fromString(itemObj[
"Time"].toString());
405 if(!item.time.isValid())
406 item.time = QDateTime::currentDateTime();
408 item.szDescription = itemObj[
"Description"].toString();
bool ImportFileToDatabaseFromJson(const QJsonObject &obj, QString &szFile)
Import file to database from JSON
static bool ExportFileToJson(const QString &szFile, QJsonObject &obj)
ExportFileToJson
static QString SetFile(const QString &szFile)
Set the file with file system to the file in database
static QString GetFile(const QString &szFile)
Get the file with file system from the file in database
int GetIcon(const QIcon &icon)
Get icon id
virtual bool OnInitializeDatabase()
Initialize database
bool SetDatabase(const CDatabase *db)
Share an existing database
The CRecentDatabase class
bool OnInitializeDatabase() override
Initialize database