diff --git a/libsearch/appdata/app-info-table-private.h b/libsearch/appdata/app-info-table-private.h index 6449993..b62ae45 100644 --- a/libsearch/appdata/app-info-table-private.h +++ b/libsearch/appdata/app-info-table-private.h @@ -16,14 +16,15 @@ public: AppInfoTablePrivate(AppInfoTablePrivate &) = delete; AppInfoTablePrivate &operator =(const AppInfoTablePrivate &) = delete; - bool setAppFavoritesState(QString &desktopfp, size_t num); - bool setAppTopState(QString &desktopfp, size_t num); + //设置应用的置顶和收藏 + void setAppFavoritesState(QString &desktopfp, int num); + void setAppTopState(QString &desktopfp, int num); - //拖动改变置顶和收藏应用位置 - bool changeFavoriteAppPos(const QString &desktopfp, size_t pos); - bool changeTopAppPos(const QString &desktopfp, size_t pos); + //改变置顶和收藏应用位置 + bool changeFavoriteAppPos(const QString &desktopfp, int pos); + bool changeTopAppPos(const QString &desktopfp, int pos); - //获取所有应用信息并存到一个结构体中 + //获取所有应用信息 bool getAppInfoResults(QVector &appInfoResults); //获取单个应用的某个状态(锁定,置顶,打开状态,收藏) @@ -62,7 +63,8 @@ private: bool openDataBase(); void closeDataBase(); - QDBusInterface *m_interface = nullptr; + QDBusInterface *m_signalTransInterface = nullptr; + QDBusInterface *m_appDBInterface = nullptr; AppInfoTable *q = nullptr; QSqlDatabase m_database; diff --git a/libsearch/appdata/app-info-table.cpp b/libsearch/appdata/app-info-table.cpp index d99b881..debe2e8 100644 --- a/libsearch/appdata/app-info-table.cpp +++ b/libsearch/appdata/app-info-table.cpp @@ -1,5 +1,6 @@ #include "app-info-table.h" #include "app-info-table-private.h" +#include "app-info-dbus-argument.h" #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,18 +21,31 @@ using namespace UkuiSearch; AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent), q(parent), m_database(QSqlDatabase()) { - m_interface = new QDBusInterface("com.ukui.search.appdb.service", - "/org/ukui/search/appDataBase", - "org.ukui.search.appdb"); + //dbus接收数据库信号 - if (!m_interface->isValid()) { + qRegisterMetaType("AppInfoResult"); + qRegisterMetaType>("QVector"); + + qDBusRegisterMetaType(); + qDBusRegisterMetaType>(); + m_signalTransInterface = new QDBusInterface("com.ukui.search.appdb.service", + "/org/ukui/search/appDataBase/signalTransformer", + "org.ukui.search.signalTransformer"); + + if (!m_signalTransInterface->isValid()) { qCritical() << "Create privateDirWatcher Interface Failed Because: " << QDBusConnection::sessionBus().lastError(); return; } else { - connect(m_interface, SIGNAL(appDBItemsAdd(QVector)), this, SLOT(sendAppDBItemsAdd(QVector))); - connect(m_interface, SIGNAL(appDBItemsUpdate(QVector)), this, SLOT(sendAppDBItemsUpdate(QVector))); - connect(m_interface, SIGNAL(appDBItemsDelete(QStringList)), this, SLOT(sendAppDBItemsDelete(QStringList))); + connect(m_signalTransInterface, SIGNAL(appDBItemsAdd(QVector)), this, SLOT(sendAppDBItemsAdd(QVector))); + connect(m_signalTransInterface, SIGNAL(appDBItemsUpdate(QVector)), this, SLOT(sendAppDBItemsUpdate(QVector))); + connect(m_signalTransInterface, SIGNAL(appDBItemsDelete(QStringList)), this, SLOT(sendAppDBItemsDelete(QStringList))); } + + //使用dbus操作数据库获取数据 + m_appDBInterface = new QDBusInterface("com.ukui.search.appdb.service", + "/org/ukui/search/appDataBase/dbManager", + "org.ukui.search.appDBManager"); + while(1) { srand(QTime(0,0,0).secsTo(QTime::currentTime())); m_ConnectionName = QString::fromStdString(std::to_string(rand()));//随机生产链接 @@ -44,388 +59,123 @@ AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent) } } -bool AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, size_t num) +void AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, int num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(num) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } else { - QVector results; - AppInfoResult info; - info.desktopPath = desktopfp; - info.favorite = num; - results.append(std::move(info)); - Q_EMIT q->appDBItems2BUpdate(results); - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; + m_appDBInterface->call("updateFavoritesState", desktopfp, num); } -bool AppInfoTablePrivate::setAppTopState(QString &desktopfp, size_t num) +void AppInfoTablePrivate::setAppTopState(QString &desktopfp, int num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(num) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } else { - QVector results; - AppInfoResult info; - info.desktopPath = desktopfp; - info.top = num; - results.append(std::move(info)); - Q_EMIT q->appDBItems2BUpdate(results); - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; + m_appDBInterface->call("updateTopState", desktopfp, num); } -bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, size_t pos) +bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, int pos) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); - int previousPos = 0; - - //记录应用原位置 - if (!sql.exec(cmd)) { - qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } else { - if (sql.next()) { - previousPos = sql.value(0).toInt(); - cmd = QString("UPDATE appInfo SET FAVORITES = FAVORITES + 1 WHRER FAVORITES > %1 AND FAVORITES < %2") - .arg(previousPos) - .arg(pos); - } else { - qWarning() << "Fail to change favorite-app pos when exec next, because: " << m_database.lastError(); - } - } - //更新范围内的应用的位置(原位置和新位置之间) - if (!sql.exec(cmd)) { - qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } else { - cmd = QString("UPDATE appInfo SET FAVORITES = %1 WHERE DESKTOP_FILE_PATH = %2") - .arg(pos) - .arg(desktopfp); - } - //更新应用位置 - if (!sql.exec(cmd)) { - qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } - - if (!m_database.commit()) { - qWarning() << "Failed to commit when exec: " << cmd; - m_database.rollback(); - res = false; - } else { - cmd = QString("SELECT DESKTOP_FILE_PATH, FAVORITES FROM appInfo WHERE FAVORITES > %1 AND FAVORITES < %2") - .arg(previousPos) - .arg(pos); - if (!sql.exec(cmd)) { - qWarning() << "I'm going to send update favorites signal but fail to exec" << cmd; - } else { - QVector results; - while (sql.next()) { - AppInfoResult info; - info.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); - info.favorite = sql.value("FAVORITES").toInt(); - results.append(std::move(info)); - } - Q_EMIT q->appDBItems2BUpdate(results); - } - } - + QDBusReply reply = m_appDBInterface->call("changeFavoriteAppPos", desktopfp, pos); + if (reply.isValid()) { + return reply.value(); } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + qDebug() << m_appDBInterface->lastError(); + return false; } - - return res; } -bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, size_t pos) +bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, int pos) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT TOP FROM appInfo WHERE DESKTOP_FILE_PATH = %0").arg(desktopfp); - int previousPos = 0; - - //记录应用原位置 - if (!sql.exec(cmd)) { - qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } else { - if (sql.next()) { - previousPos = sql.value(0).toInt(); - cmd = QString("UPDATE appInfo SET TOP = TOP + 1 WHRER TOP > %1 AND TOP < %2") - .arg(previousPos) - .arg(pos); - } else { - qWarning() << "Fail to change top-app pos when exec next, because: " << m_database.lastError(); - } - } - //更新范围内的应用的位置(原位置和新位置之间) - if (!sql.exec(cmd)) { - qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } else { - cmd = QString("UPDATE appInfo SET TOP = %1 WHERE DESKTOP_FILE_PATH = %2") - .arg(pos) - .arg(desktopfp); - } - //更新应用位置 - if (!sql.exec(cmd)) { - qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; - res = false; - } - - if (!m_database.commit()) { - qWarning() << "Failed to commit when exec: " << cmd; - m_database.rollback(); - res = false; - } else { - cmd = QString("SELECT DESKTOP_FILE_PATH, TOP FROM appInfo WHERE TOP > %1 AND TOP < %2") - .arg(previousPos) - .arg(pos); - if (!sql.exec(cmd)) { - qWarning() << "I'm going to send update top signal but fail to exec" << cmd; - } else { - QVector results; - while (sql.next()) { - AppInfoResult info; - info.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); - info.favorite = sql.value("TOP").toInt(); - results.append(std::move(info)); - } - Q_EMIT q->appDBItems2BUpdate(results); - } - } - + QDBusReply reply = m_appDBInterface->call("changeTopAppPos", desktopfp, pos); + if (reply.isValid()) { + return reply.value(); } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + qDebug() << m_appDBInterface->lastError(); + return false; } - - return res; -} - -bool AppInfoTablePrivate::getAppCategory(QString &desktopfp, QString &category) -{ - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT CATEGORY FROM appInfo WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - category = sql.value(0).toString(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; - } - return res; } bool AppInfoTablePrivate::getAppInfoResults(QVector &appInfoResults) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,CATEGORY,TOP,FAVORITES,LAUNCH_TIMES,LOCK,FIRST_LETTER_ALL FROM appInfo"); - if (sql.exec(cmd)) { - while (sql.next()) { - AppInfoResult result; - result.desktopPath = sql.value(0).toString(); - result.appLocalName = sql.value(1).toString(); - result.iconName = sql.value(2).toString(); - result.category = sql.value(3).toString(); - result.top = sql.value(4).toInt(); - result.favorite = sql.value(5).toInt(); - result.launchTimes = sql.value(6).toInt(); - result.lock = sql.value(7).toInt(); - result.firstLetter = sql.value(8).toString(); - appInfoResults.append(std::move(result)); - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } + QDBusReply> reply = m_appDBInterface->call("getAppInfoResults"); + if (reply.isValid()) { + appInfoResults = reply.value(); + return true; } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + return false; } - return res; } bool AppInfoTablePrivate::getAppLockState(QString &desktopfp, size_t &num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LOCK FROM appInfo WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - num = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } + QDBusReply reply = m_appDBInterface->call("getAppLockState", desktopfp); + if (!reply.isValid()) { + qWarning() << m_appDBInterface->lastError(); + return false; } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + num = reply.value(); + if (num == -1) { + qWarning() << "There's something wrong while using database"; + return false; + } + return true; } - return res; } bool AppInfoTablePrivate::getAppTopState(QString &desktopfp, size_t &num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT TOP FROM appInfo WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - num = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } + QDBusReply reply = m_appDBInterface->call("getAppTopState", desktopfp); + if (!reply.isValid()) { + qWarning() << m_appDBInterface->lastError(); + return false; } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + num = reply.value(); + if (num == -1) { + qWarning() << "There's something wrong while using database"; + return false; + } + return true; } - return res; } bool AppInfoTablePrivate::getAppLaunchedState(QString &desktopfp, size_t &num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCHED FROM appInfo WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - num = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } + QDBusReply reply = m_appDBInterface->call("getAppLaunchedState", desktopfp); + if (!reply.isValid()) { + qWarning() << m_appDBInterface->lastError(); + return false; } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + num = reply.value(); + if (num == -1) { + qWarning() << "There's something wrong while using database"; + return false; + } + return true; } - return res; } bool AppInfoTablePrivate::getAppFavoriteState(QString &desktopfp, size_t &num) { - bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES FROM appInfo WHERE DESKTOP_FILE_PATH='%0'") - .arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - num = sql.value(0).toInt(); - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - } else { - qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); - res = false; - } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } + QDBusReply reply = m_appDBInterface->call("getAppFavoriteState", desktopfp); + if (!reply.isValid()) { + qWarning() << m_appDBInterface->lastError(); + return false; } else { - qWarning() << "Failed to start transaction mode!!!"; - res = false; + num = reply.value(); + if (num == -1) { + qWarning() << "There's something wrong while using database"; + return false; + } + return true; + } +} + +bool AppInfoTablePrivate::getAppCategory(QString &desktopfp, QString &category) +{ + QDBusReply reply = m_appDBInterface->call("getAppCategory", desktopfp); + if (reply.isValid()) { + category = reply.value(); + return true; + } else { + qDebug() << m_appDBInterface->lastError(); + return false; } - return res; } bool AppInfoTablePrivate::addAppShortcut2Desktop(QString &desktopfp) @@ -478,10 +228,10 @@ bool AppInfoTablePrivate::searchInstallApp(QString &keyWord, QStringList &instal QSqlQuery sql(m_database); QString cmd; if (keyWord.size() < 2) { - cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON FROM appInfo WHERE LOCAL_NAME OR NAME_EN OR NAME_ZH OR FIRST_LETTER_OF_PINYIN LIKE '%%0%' ORDER BY FAVORITES DESC") + cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON FROM APPINFO WHERE LOCAL_NAME OR NAME_EN OR NAME_ZH OR FIRST_LETTER_OF_PINYIN LIKE '%%0%' ORDER BY FAVORITES DESC") .arg(keyWord); } else { - cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON FROM appInfo WHERE LOCAL_NAME OR NAME_EN OR NAME_ZH OR PINYIN_NAME OR FIRST_LETTER_OF_PINYIN LIKE '%%0%' ORDER BY FAVORITES DESC") + cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON FROM APPINFO WHERE LOCAL_NAME OR NAME_EN OR NAME_ZH OR PINYIN_NAME OR FIRST_LETTER_OF_PINYIN LIKE '%%0%' ORDER BY FAVORITES DESC") .arg(keyWord); } @@ -512,11 +262,11 @@ bool AppInfoTablePrivate::searchInstallApp(QStringList &keyWord, QStringList &in QSqlQuery sql(m_database); QString cmd; if (keyWord.at(0).size() < 2) { - cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,NAME_EN,NAME_ZH,FIRST_LETTER_OF_PINYIN FROM appInfo" + cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,NAME_EN,NAME_ZH,FIRST_LETTER_OF_PINYIN FROM APPINFO" " WHERE LOCAL_NAME LIKE '%%0%' OR NAME_EN LIKE '%%0%' OR NAME_ZH LIKE '%%0%' OR FIRST_LETTER_OF_PINYIN LIKE '%%0%'") .arg(keyWord.at(0)); } else { - cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,NAME_EN,NAME_ZH,FIRST_LETTER_OF_PINYIN FROM appInfo" + cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,NAME_EN,NAME_ZH,FIRST_LETTER_OF_PINYIN FROM APPINFO" " WHERE LOCAL_NAME LIKE '%%0%' OR NAME_EN LIKE '%%0%' OR NAME_ZH LIKE '%%0%' OR PINYIN_NAME LIKE '%%0%' OR FIRST_LETTER_OF_PINYIN LIKE '%%0%'") .arg(keyWord.at(0)); } @@ -628,7 +378,7 @@ bool AppInfoTablePrivate::updateAppLaunchTimes(QString &desktopfp) bool res(true); if (m_database.transaction()) { QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); + QString cmd = QString("SELECT LAUNCH_TIMES FROM APPINFO WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); if (sql.exec(cmd)) { if (sql.next()) { cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH='%3'") @@ -689,7 +439,7 @@ bool AppInfoTablePrivate::getAllAppDesktopList(QStringList &list) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO"); if (sql.exec(cmd)) { while (sql.next()) { @@ -707,7 +457,7 @@ bool AppInfoTablePrivate::getFavoritesAppList(QStringList &list) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE FAVORITES!=0 ORDER BY FAVORITES"); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO WHERE FAVORITES!=0 ORDER BY FAVORITES"); if (sql.exec(cmd)) { while (sql.next()) { list.append(sql.value(0).toString()); @@ -723,7 +473,7 @@ bool AppInfoTablePrivate::getTopAppList(QStringList &list) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo WHERE TOP!=0 ORDER BY TOP"); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO WHERE TOP!=0 ORDER BY TOP"); if (sql.exec(cmd)) { while (sql.next()) { @@ -743,7 +493,7 @@ bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list) if (m_database.transaction()) { QSqlQuery sql(m_database); QSqlQuery sqlque(m_database); - QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo ORDER BY LAUNCH_TIMES"); + QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO ORDER BY LAUNCH_TIMES"); int count = 0; if (sql.exec(cmd)) { while (sql.next()) { @@ -826,12 +576,12 @@ AppInfoTable::AppInfoTable(QObject *parent) : QObject(parent), d(new AppInfoTabl { } -bool AppInfoTable::setAppFavoritesState(QString &desktopfp, size_t num) +void AppInfoTable::setAppFavoritesState(QString &desktopfp, size_t num) { return d->setAppFavoritesState(desktopfp, num); } -bool AppInfoTable::setAppTopState(QString &desktopfp, size_t num) +void AppInfoTable::setAppTopState(QString &desktopfp, size_t num) { return d->setAppTopState(desktopfp, num); } diff --git a/libsearch/appdata/app-info-table.h b/libsearch/appdata/app-info-table.h index cc3eac4..dbfb3ae 100644 --- a/libsearch/appdata/app-info-table.h +++ b/libsearch/appdata/app-info-table.h @@ -20,25 +20,22 @@ public: * set the favorites state of the app * @param desktopfp: the desktop file path of app * @param num: the favorites app's order(from 1) - * @return bool: true if success, else false */ - bool setAppFavoritesState(QString &desktopfp, size_t num); + void setAppFavoritesState(QString &desktopfp, size_t num); /** * @brief AppInfoTable::setAppTopState * set the top state of the app * @param desktopfp: the desktop file path of app * @param num: the top app's order(from 1) - * @return bool: true if success, else false */ - bool setAppTopState(QString &desktopfp, size_t num); + void setAppTopState(QString &desktopfp, size_t num); /** * @brief AppInfoTable::changeFavoriteAppPos * change the position of the app which is one of the Favorites Apps * @param desktopfp: desktop file path of app * @param pos: the position which the app will be changed into - * @return bool: true if success, else false */ bool changeFavoriteAppPos(const QString &desktopfp, size_t pos); diff --git a/ukui-search-app-data-service/app-db-manager.cpp b/ukui-search-app-data-service/app-db-manager.cpp index 7fd4174..b5b267c 100644 --- a/ukui-search-app-data-service/app-db-manager.cpp +++ b/ukui-search-app-data-service/app-db-manager.cpp @@ -17,7 +17,7 @@ using namespace UkuiSearch; static AppDBManager *global_instance; -QMutex AppDBManager::s_installAppMapMutex; +QMutex AppDBManager::s_mutex; AppDBManager *AppDBManager::getInstance() { @@ -46,7 +46,8 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa m_qSettings->endGroup(); //初始化数据库 - refreshDataBase(); + refreshAllData2DB(); +// refreshDataBase(); //初始化FileSystemWatcher m_watchAppDir = new QFileSystemWatcher(this); @@ -95,19 +96,19 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa connect(m_timer, &QTimer::timeout, this, [ & ] { qDebug() << "Time out! Now I can update the database!"; Q_EMIT this->stopTimer(); - this->refreshDataBase(); + this->refreshAllData2DB(); }, Qt::DirectConnection); connect(m_maxProcessTimer, &QTimer::timeout, this, [ & ] { qDebug() << "I've waited too lang, I have to update the database now!"; Q_EMIT this->stopTimer(); - this->refreshDataBase(); + this->refreshAllData2DB(); }, Qt::DirectConnection); //监控应用进程开启 connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) { QString desktopfp = ConvertWinidToDesktop::getConverter().tranIdToDesktop(id); if (!desktopfp.isEmpty()) { - AppDBManager::getInstance()->updateAppLaunchTimes(desktopfp); + this->updateLaunchTimes(desktopfp); } }); } else { @@ -126,6 +127,7 @@ AppDBManager::~AppDBManager() void AppDBManager::buildAppInfoDB() { + qDebug() << "I'm going to build app info database."; QSqlQuery sql(m_database); QString cmd = QString("CREATE TABLE IF NOT EXISTS appInfo(%1, %2, %3, %4, %5, %6, %7, %8,%9, %10, %11, %12, %13, %14, %15, %16, %17, %18, %19, %20, %21)") // .arg("ID INT")//自增id @@ -159,7 +161,8 @@ void AppDBManager::buildAppInfoDB() void AppDBManager::updateAppInfoDB() { - QMutexLocker locker(&s_installAppMapMutex); + /* + QMutexLocker locker(&s_mutex); m_installAppMap.clear(); this->getAllDesktopFilePath(GENERAL_APP_DESKTOP_PATH); this->getAllDesktopFilePath(ANDROID_APP_DESKTOP_PATH); @@ -167,7 +170,7 @@ void AppDBManager::updateAppInfoDB() QStringList filePathList; this->getFilePathList(filePathList); QSqlQuery sql(m_database); - QString cmd = "SELECT COUNT(*) FROM appInfo"; + QString cmd = "SELECT COUNT(*) FROM APPINFO"; if (!sql.exec(cmd)) { this->buildAppInfoDB(); for (auto &filePath : filePathList) { @@ -179,7 +182,7 @@ void AppDBManager::updateAppInfoDB() //删除多余项 if (sql.value(0).toInt() > filePathList.size()) { int size = sql.value(0).toInt(); - cmd = QString("SELECT DESKTOP_FILE_PATH FROM appInfo"); + cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO"); if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; return; @@ -199,13 +202,13 @@ void AppDBManager::updateAppInfoDB() } //添加新增项,根据md5判断desktop文件是否改变以更新对应项 for (QString &filePath : filePathList) { - cmd = QString("SELECT COUNT(*) FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(filePath); + cmd = QString("SELECT COUNT(*) FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(filePath); if (sql.exec(cmd)) { if (sql.next()) { if (sql.value(0).toInt() == 0) { this->addAppDesktopFile2DB(filePath); } else { - cmd = QString("SELECT MD5 FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(filePath); + cmd = QString("SELECT MD5 FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(filePath); if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; return; @@ -236,21 +239,23 @@ void AppDBManager::updateAppInfoDB() return; } } + */ } void AppDBManager::getFilePathList(QStringList &pathList) { - for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { - pathList.append(i.value().at(0)); - } +// for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { +// pathList.append(i.value().at(0)); +// } } /** * @brief AppMatch::getAllDesktopFilePath 遍历所有desktop文件 * @param path 存放desktop文件夹 */ -void AppDBManager::getAllDesktopFilePath(QString path) { - +void AppDBManager::getAllDesktopFilePath(QString path) +{ + /* QDir dir(path); if(!dir.exists()) { return; @@ -310,6 +315,7 @@ void AppDBManager::getAllDesktopFilePath(QString path) { ++i; } } + */ } void AppDBManager::loadDesktopFilePaths(QString path, QFileInfoList &infolist) @@ -320,12 +326,12 @@ void AppDBManager::loadDesktopFilePaths(QString path, QFileInfoList &infolist) infolist.append(dir.entryInfoList()); } -void AppDBManager::updateAllData2DB() +void AppDBManager::refreshAllData2DB() { m_dbChanged = false; bool firstExec = false; QSqlQuery sql(m_database); - QString cmd = "SELECT DESKTOP_FILE_PATH,MD5 FROM appInfo"; + QString cmd = "SELECT DESKTOP_FILE_PATH,MD5 FROM APPINFO"; QMap dataMap; if (!sql.exec(cmd)) { qDebug() << "Fail to read database, because: " << m_database.lastError(); @@ -374,29 +380,25 @@ void AppDBManager::updateAllData2DB() if (!QString::compare(dataMap.value(path), getAppDesktopMd5(path))) { //判断系统语言是否改变 if (m_localeChanged) { - this->updateLocaleData2DB(path); - m_dbChanged = true; + this->updateLocaleData(path); } dataMap.remove(path); continue; } else { //数据库有记录但md5值改变则update - this->updateAppDesktopFile2DB(path); - m_dbChanged = true; + this->updateDBItem(path); dataMap.remove(path); continue; } } else { //数据库中没有记录则insert - this->addAppDesktopFile2DB(path); - m_dbChanged = true; + this->insertDBItem(path); dataMap.remove(path); continue; } } //数据库为空则全部insert - this->addAppDesktopFile2DB(path); - m_dbChanged = true; + this->insertDBItem(path); dataMap.remove(path); } @@ -406,13 +408,12 @@ void AppDBManager::updateAllData2DB() //数据库冗余项直接delete if (!dataMap.isEmpty()) { for (auto i = dataMap.constBegin(); i != dataMap.constEnd(); i++) { - this->deleteAppDesktopFile2DB(i.key()); - m_dbChanged = true; + this->deleteDBItem(i.key()); } } } -bool AppDBManager::updateLocaleData2DB(QString desktopPath) +bool AppDBManager::handleLocaleDataUpdate(const QString &desktopPath) { bool res(true); XdgDesktopFile desktopFile; @@ -456,20 +457,19 @@ void AppDBManager::run() void AppDBManager::refreshDataBase() { - if (m_database.transaction()) { -// this->updateAppInfoDB(); - this->updateAllData2DB(); - if (!m_database.commit()) { - qWarning() << "Failed to commit !"; - m_database.rollback(); - } else if (!m_dbChanged) { - qDebug() << "app DataBase has no changes!"; - } else { - Q_EMIT this->finishHandleAppDB(); - } - } else { - qWarning() << "Failed to start transaction mode!!!"; - } +// if (m_database.transaction()) { +// this->updateAllData2DB(); +// if (!m_database.commit()) { +// qWarning() << "Failed to commit !"; +// m_database.rollback(); +// } else if (!m_dbChanged) { +// qDebug() << "app DataBase has no changes!"; +// } else { +// Q_EMIT this->finishHandleAppDB(); +// } +// } else { +// qWarning() << "Failed to start transaction mode!!!"; +// } } bool AppDBManager::openDataBase() @@ -500,7 +500,7 @@ void AppDBManager::closeDataBase() QSqlDatabase::removeDatabase(CONNECTION_NAME); } -QString AppDBManager::getAppDesktopMd5(QString &desktopfd) +QString AppDBManager::getAppDesktopMd5(const QString &desktopfd) { QString res; QFile file(desktopfd); @@ -510,16 +510,37 @@ QString AppDBManager::getAppDesktopMd5(QString &desktopfd) return res; } -void AppDBManager::getInstallAppMap(QMap &installAppMap) +bool AppDBManager::startTransaction() { - QMutexLocker locker(&s_installAppMapMutex); - for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { - installAppMap[i.key().app_name] = i.value(); + if (m_database.transaction()) { + return true; + } else { + qWarning() << "Failed to start transaction mode!!!"; + return false; } - installAppMap.detach(); } -bool AppDBManager::addAppDesktopFile2DB(QString &desktopfd) +bool AppDBManager::startCommit() +{ + if (!m_database.commit()) { + qWarning() << "Failed to commit !"; + m_database.rollback(); + return false; + } else { + return true; + } +} + +void AppDBManager::getInstallAppMap(QMap &installAppMap) +{ +// QMutexLocker locker(&s_mutex); +// for (auto i=m_installAppMap.begin(); i!=m_installAppMap.end(); ++i) { +// installAppMap[i.key().app_name] = i.value(); +// } +// installAppMap.detach(); +} + +bool AppDBManager::handleDBItemInsert(const QString &desktopfd) { bool res(true); QSqlQuery sql(m_database); @@ -600,11 +621,11 @@ bool AppDBManager::addAppDesktopFile2DB(QString &desktopfd) return res; } -bool AppDBManager::deleteAppDesktopFile2DB(const QString &desktopfd) +bool AppDBManager::handleDBItemDelete(const QString &desktopfd) { bool res(true); QSqlQuery sql(m_database); - QString cmd = QString("SELECT FAVORITES, TOP FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); + QString cmd = QString("SELECT FAVORITES, TOP FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); //查询要删除信息的应用是否被收藏或顶置过 if (!sql.exec(cmd)) { @@ -629,7 +650,7 @@ bool AppDBManager::deleteAppDesktopFile2DB(const QString &desktopfd) } //执行删除操作 - cmd = QString("DELETE FROM appInfo WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); + cmd = QString("DELETE FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfd); if (!sql.exec(cmd)) { qWarning() << m_database.lastError() << cmd; res = false; @@ -644,14 +665,14 @@ bool AppDBManager::deleteAppDesktopFile2DB(const QString &desktopfd) return res; } -bool AppDBManager::updateAppDesktopFile2DB(QString &desktopfd) +bool AppDBManager::handleDBItemUpdate(const QString &desktopfd) { bool res(true); XdgDesktopFile desktopfile; desktopfile.load(desktopfd); - if(desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) { - qDebug() << "app" << desktopfd << "is changed, NoDisplay or NotShowIn is working!"; - return this->deleteAppDesktopFile2DB(desktopfd); + if (desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) { + qDebug() << "app" << desktopfd << "is changed, but NoDisplay or NotShowIn is working!"; + return this->handleDBItemDelete(desktopfd); } QString hanzi, pinyin, firstLetterOfPinyin; QString localName = desktopfile.localizedValue("Name", "NULL").toString(); @@ -732,49 +753,449 @@ bool AppDBManager::updateAppDesktopFile2DB(QString &desktopfd) return res; } -bool AppDBManager::updateAppLaunchTimes(QString &desktopfp) +bool AppDBManager::handleLaunchTimesUpdate(const QString &desktopfp) { bool res(true); - if (m_database.transaction()) { - QSqlQuery sql(m_database); - QString cmd = QString("SELECT LAUNCH_TIMES FROM appInfo WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); - if (sql.exec(cmd)) { - if (sql.next()) { - int launchTimes = sql.value(0).toInt() + 1; - cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH='%3'") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) - .arg(launchTimes) - .arg(1) - .arg(desktopfp); - if (!sql.exec(cmd)) { - qWarning() << "Set app favorites state failed!" << m_database.lastError(); - res = false; - } else { - AppInfoResult result; - result.desktopPath = desktopfp; - result.launchTimes = launchTimes; - Q_EMIT this->appDBItemUpdate(result); - } - } else { - qWarning() << "Failed to exec next!" << cmd; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT LAUNCH_TIMES FROM APPINFO WHERE DESKTOP_FILE_PATH='%1'").arg(desktopfp); + if (sql.exec(cmd)) { + if (sql.next()) { + int launchTimes = sql.value(0).toInt() + 1; + cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LAUNCH_TIMES=%1, LAUNCHED=%2 WHERE DESKTOP_FILE_PATH='%3'") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(launchTimes) + .arg(1) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); res = false; + } else { + AppInfoResult result; + result.desktopPath = desktopfp; + result.launchTimes = launchTimes; + Q_EMIT this->appDBItemUpdate(result); + qDebug() << "app database update " << desktopfp << "launch times success!"; } } else { - qWarning() << "Failed to exec:" << cmd; + qWarning() << "Failed to exec next!" << cmd; res = false; } - if (!m_database.commit()) { - qWarning() << "Failed to commit !" << cmd; - m_database.rollback(); - res = false; - } else { - Q_EMIT this->finishHandleAppDB(); - } } else { - qWarning() << "Failed to start transaction mode!!!"; + qWarning() << "Failed to exec:" << cmd; res = false; } return res; } +bool AppDBManager::handleFavoritesStateUpdate(const QString &desktopfp, int num) +{ + if (num < 0) { + qWarning() << "Invalid favorite num, I quit!!!"; + return false; + } + bool res(true); + QSqlQuery sql(m_database); + + //查询要设置的favorites标志位是否被占用 + QString cmd = QString("SELECT DESKTOP_FILE_PATH, FAVORITES FROM APPINFO WHERE FAVORITES = %1").arg(num); + if (!sql.exec(cmd)) { + qWarning() << "Fail to exec:" << cmd << "because:" << m_database.lastError(); + } else { + while (sql.next()) { + if (sql.value("FAVORITES").toInt() == num) { + res = false; + if (sql.value("DESKTOP_FILE_PATH").toString() == desktopfp) { + qWarning() << "favorites state has no changes, I quit!"; + return res; + } else { + qWarning() << "the favorites num:" << num << "has been used, fail to update favorites state of" << desktopfp; + return res; + } + } + } + } + + //更新favorites状态 + cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', FAVORITES=%1 WHERE DESKTOP_FILE_PATH='%2'") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(num) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } else { + AppInfoResult info; + info.desktopPath = desktopfp; + info.favorite = num; + Q_EMIT this->appDBItemUpdate(info); + qDebug() << "app database update " << desktopfp << "favorites state: " << num << "success!"; + } + return res; +} + +bool AppDBManager::handleTopStateUpdate(const QString &desktopfp, int num) +{ + if (num < 0) { + qWarning() << "Invalid top num, I quit!!!"; + return false; + } + + bool res(true); + QSqlQuery sql(m_database); + + //查询要设置的top标志位是否被占用 + QString cmd = QString("SELECT DESKTOP_FILE_PATH, TOP FROM APPINFO WHERE TOP = %1").arg(num); + if (!sql.exec(cmd)) { + qWarning() << "Fail to exec:" << cmd << "because:" << m_database.lastError(); + } else { + while (sql.next()) { + if (sql.value("TOP").toInt() == num) { + res = false; + if (sql.value("DESKTOP_FILE_PATH").toString() == desktopfp) { + qWarning() << "top state has no changes, I quit!"; + return res; + } else { + qWarning() << "the top num:" << num << "has been used, fail to update top state of" << desktopfp; + return res; + } + } + } + } + + //更新top状态 + cmd = QString("UPDATE APPINFO SET MODIFYED_TIME='%0', TOP=%1 WHERE DESKTOP_FILE_PATH='%2'") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(num) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } else { + AppInfoResult info; + info.desktopPath = desktopfp; + info.top = num; + Q_EMIT this->appDBItemUpdate(info); + qDebug() << "app database update " << desktopfp << "top state: " << num << "success!"; + } + return res; +} + +bool AppDBManager::handleLockStateUpdate(const QString &desktopfp, int num) +{ + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("UPDATE appInfo SET MODIFYED_TIME='%0', LOCK=%1 WHERE DESKTOP_FILE_PATH='%2'") + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(num) + .arg(desktopfp); + if (!sql.exec(cmd)) { + qWarning() << "Set app favorites state failed!" << m_database.lastError(); + res = false; + } else { + AppInfoResult info; + info.desktopPath = desktopfp; + info.lock = num; + Q_EMIT this->appDBItemUpdate(info); + qDebug() << "app database update " << desktopfp << "lock state: " << num << "success!"; + } + return res; +} + +void AppDBManager::insertDBItem(const QString &desktopfd) +{ + PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Insert); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::updateDBItem(const QString &desktopfd) +{ + PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::UpdateAll); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::deleteDBItem(const QString &desktopfd) +{ + PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Delete); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::updateLocaleData(const QString &desktopfp) +{ + PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateLocaleData); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::updateLaunchTimes(const QString &desktopfp) +{ + PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateLaunchTimes); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::updateFavoritesState(const QString &desktopfp, int num) +{ + PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateFavorites, num); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::updateTopState(const QString &desktopfp, int num) +{ + PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateTop); + item.setTop(num); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +void AppDBManager::udpateLockState(const QString &desktopfp, int num) +{ + PendingAppInfo item(desktopfp, PendingAppInfo::HandleType::UpdateTop); + item.setLock(num); + PendingAppInfoQueue::getAppInfoQueue().enqueue(item); +} + +bool AppDBManager::changeFavoriteAppPos(const QString &desktopfp, int pos) +{ + if (pos < 1) { + qWarning() << "To be moved to a invalid favorites pos , I quit!!"; + return false; + } + + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfp); + int previousPos = 0; + + //记录应用原位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + if (sql.next()) { + previousPos = sql.value(0).toInt(); + + if (previousPos < 1) { + qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopfp); + } + + if (previousPos == pos) { + qDebug() << "favorite app's pos has no changes!"; + return res; + } + + cmd = QString("SELECT DESKTOP_FILE_PATH, FAVORITES FROM APPINFO WHERE FAVORITES BETWEEN MIN(%1, %2) AND MAX(%1, %2)") + .arg(previousPos) + .arg(pos); + } else { + qWarning() << "Fail to change favorite-app pos when exec next, because: " << m_database.lastError(); + } + } + + //更新原位置和新位置之间的应用的位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change favorite-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + while (sql.next()) { + if (sql.value("FAVORITES").toInt() == previousPos) { + this->updateFavoritesState(desktopfp, pos); + continue; + } + if (previousPos > pos) { + this->updateFavoritesState(sql.value("DESKTOP_FILE_PATH").toString(), sql.value("FAVORITES").toInt() + 1); + } else { + this->updateFavoritesState(sql.value("DESKTOP_FILE_PATH").toString(), sql.value("FAVORITES").toInt() - 1); + } + + } + } + + return res; +} + +bool AppDBManager::changeTopAppPos(const QString &desktopfp, int pos) +{ + if (pos < 1) { + qWarning() << "To be moved to a invalid top pos, I quit!!"; + return false; + } + + bool res(true); + QSqlQuery sql(m_database); + QString cmd = QString("SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH = '%0'").arg(desktopfp); + int previousPos = 0; + + //记录应用原位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + if (sql.next()) { + previousPos = sql.value(0).toInt(); + + if (previousPos < 1) { + qWarning() << QString("app: %1 is not a favorites app, I quit!!").arg(desktopfp); + res = false; + return res; + } + + if (previousPos == pos) { + qDebug() << "top app's pos has no changes!"; + res = false; + return res; + } + + cmd = QString("SELECT DESKTOP_FILE_PATH, TOP FROM APPINFO WHERE TOP BETWEEN MIN(%1, %2) AND MAX(%1, %2)") + .arg(previousPos) + .arg(pos); + } else { + qWarning() << "Fail to change top-app pos when exec next, because: " << m_database.lastError(); + } + } + + //更新原位置和新位置之间的应用的位置 + if (!sql.exec(cmd)) { + qWarning() << "Fail to change top-app pos, because: " << m_database.lastError() << " when exec :" << cmd; + res = false; + } else { + while (sql.next()) { + if (sql.value("TOP").toInt() == previousPos) { + this->updateTopState(desktopfp, pos); + continue; + } + if (previousPos > pos) { + this->updateTopState(sql.value("DESKTOP_FILE_PATH").toString(), sql.value("TOP").toInt() + 1); + } else { + this->updateTopState(sql.value("DESKTOP_FILE_PATH").toString(), sql.value("TOP").toInt() - 1); + } + + } + } + + return res; +} + +QVector AppDBManager::getAppInfoResults() +{ + QVector appInfoResults; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT DESKTOP_FILE_PATH,LOCAL_NAME,ICON,CATEGORY,TOP,FAVORITES,LAUNCH_TIMES,LOCK,FIRST_LETTER_ALL FROM APPINFO"); + + if (sql.exec(cmd)) { + while (sql.next()) { + AppInfoResult result; + result.desktopPath = sql.value("DESKTOP_FILE_PATH").toString(); + result.appLocalName = sql.value("LOCAL_NAME").toString(); + result.iconName = sql.value("ICON").toString(); + result.category = sql.value("CATEGORY").toString(); + result.top = sql.value("TOP").toInt(); + result.favorite = sql.value("FAVORITES").toInt(); + result.launchTimes = sql.value("LAUNCH_TIMES").toInt(); + result.lock = sql.value("LOCK").toInt(); + result.firstLetter = sql.value("FIRST_LETTER_ALL").toString(); + appInfoResults.append(std::move(result)); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return appInfoResults; +} + +int AppDBManager::getAppLockState(const QString &desktopfp) +{ + int lockState = -1; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT LOCK FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") + .arg(desktopfp); + + if (sql.exec(cmd)) { + if (sql.next()) { + lockState = sql.value(0).toInt(); + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return lockState; +} + +int AppDBManager::getAppTopState(const QString &desktopfp) +{ + int topState = -1; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT TOP FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") + .arg(desktopfp); + + if (sql.exec(cmd)) { + if (sql.next()) { + topState = sql.value(0).toInt(); + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return topState; +} + +int AppDBManager::getAppLaunchedState(const QString &desktopfp) +{ + int launchedState = -1; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT LAUNCHED FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") + .arg(desktopfp); + + if (sql.exec(cmd)) { + if (sql.next()) { + launchedState = sql.value(0).toInt(); + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return launchedState; +} + +int AppDBManager::getAppFavoriteState(const QString &desktopfp) +{ + int favoriteState = -1; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT FAVORITES FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") + .arg(desktopfp); + + if (sql.exec(cmd)) { + if (sql.next()) { + favoriteState = sql.value(0).toInt(); + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return favoriteState; +} + +QString AppDBManager::getAppCategory(const QString &desktopfp) +{ + QString category; + QSqlQuery sql(m_database); + QString cmd = QString("SELECT CATEGORY FROM APPINFO WHERE DESKTOP_FILE_PATH='%0'") + .arg(desktopfp); + + if (sql.exec(cmd)) { + if (sql.next()) { + category = sql.value(0).toString(); + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + } else { + qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database.lastError(); + } + + return category; +} diff --git a/ukui-search-app-data-service/app-db-manager.h b/ukui-search-app-data-service/app-db-manager.h index 8d51816..b663d38 100644 --- a/ukui-search-app-data-service/app-db-manager.h +++ b/ukui-search-app-data-service/app-db-manager.h @@ -2,6 +2,7 @@ #define APPDBMANAGER_H #include "app-db-common.h" +#include "pending-app-info-queue.h" #include #include @@ -42,6 +43,8 @@ class AppDBManager : public QThread { Q_OBJECT + Q_CLASSINFO("D-Bus Interface","org.ukui.search.appDBManager") + enum APP_LOCK_STATE{ APP_UNLOCK = 0, APP_LOCK @@ -50,16 +53,52 @@ class AppDBManager : public QThread public: static AppDBManager *getInstance(); - QString getAppDesktopMd5(QString &desktopfd); + //刷新数据库数据 + void refreshAllData2DB(); - void getInstallAppMap(QMap &installAppMap); + //获取desktop文件的md5值 + QString getAppDesktopMd5(const QString &desktopfd); + + bool startTransaction(); + bool startCommit(); + + bool handleDBItemInsert(const QString &desktopfd); + bool handleDBItemUpdate(const QString &desktopfd); + bool handleDBItemDelete(const QString &desktopfd); + + bool handleLocaleDataUpdate(const QString &desktopPath); + bool handleLaunchTimesUpdate(const QString &desktopfp); + bool handleFavoritesStateUpdate(const QString &desktopfp, int num); + bool handleTopStateUpdate(const QString &desktopfp, int num); + bool handleLockStateUpdate(const QString &desktopfp, int num); + +public Q_SLOTS: + //对数据库单条所有信息进行增删改 + void insertDBItem(const QString &desktopfd); + void updateDBItem(const QString &desktopfd); + void deleteDBItem(const QString &desktopfd); + + //对数据库某字段进行update + void updateLocaleData(const QString &desktopfp); + void updateLaunchTimes(const QString &desktopfp); + void updateFavoritesState(const QString &desktopfp, int num); + void updateTopState(const QString &desktopfp, int num); + void udpateLockState(const QString &desktopfp, int num); + + //拖动改变置顶和收藏应用位置 + bool changeFavoriteAppPos(const QString &desktopfp, int pos); + bool changeTopAppPos(const QString &desktopfp, int pos); + + //获取数据库中全部信息 + QVector getAppInfoResults(); + + //查询某应用的某个字段的值 + int getAppLockState(const QString &desktopfp); + int getAppTopState(const QString &desktopfp); + int getAppLaunchedState(const QString &desktopfp); + int getAppFavoriteState(const QString &desktopfp); + QString getAppCategory(const QString &desktopfp); - bool addAppDesktopFile2DB(QString &desktopfd); - bool deleteAppDesktopFile2DB(const QString &desktopfd); - bool updateAppDesktopFile2DB(QString &desktopfd); - bool updateAppLaunchTimes(QString &desktopfp); - void updateAllData2DB(); - bool updateLocaleData2DB(QString desktopPath); protected: void run() override; @@ -67,32 +106,39 @@ private: explicit AppDBManager(QObject *parent = nullptr); ~AppDBManager(); + //加载指定路径path中的所有desktop文件路径到infolist中 void loadDesktopFilePaths(QString path, QFileInfoList &infolist); - void refreshDataBase(); + //链接数据库 bool openDataBase(); + //刷新数据库 + void refreshDataBase(); + //关闭数据库,断开链接 void closeDataBase(); + //创建数据库字段 void buildAppInfoDB(); + + //暂时弃用 void updateAppInfoDB(); void getAllDesktopFilePath(QString path); void getFilePathList(QStringList &pathList); + void getInstallAppMap(QMap &installAppMap); - QSettings *m_qSettings = nullptr; - +private: + static QMutex s_mutex; bool m_localeChanged; bool m_dbChanged; + QSettings *m_qSettings = nullptr; + QTimer *m_timer = nullptr; QTimer *m_maxProcessTimer = nullptr; QSqlDatabase m_database; - QFileSystemWatcher *m_watchAppDir = nullptr; - static QMutex s_installAppMapMutex; - QMap m_installAppMap; - + //应用黑名单 QStringList m_excludedDesktopfiles = { "/usr/share/applications/software-properties-livepatch.desktop", "/usr/share/applications/mate-color-select.desktop", @@ -141,12 +187,17 @@ private: "/usr/share/applications/screensavers" }; + //暂时弃用 + QMap m_installAppMap; + Q_SIGNALS: + //操作数据库 void appDBItemUpdate(const AppInfoResult&); void appDBItemAdd(const AppInfoResult&); void appDBItemDelete(const QString&); void finishHandleAppDB(); + //定时器操作 void startTimer(); void maxProcessTimerStart(); void stopTimer(); diff --git a/ukui-search-app-data-service/pending-app-info-queue.cpp b/ukui-search-app-data-service/pending-app-info-queue.cpp new file mode 100644 index 0000000..a3956ab --- /dev/null +++ b/ukui-search-app-data-service/pending-app-info-queue.cpp @@ -0,0 +1,145 @@ +#include "pending-app-info-queue.h" +#include "app-db-manager.h" + +using namespace UkuiSearch; + +QMutex PendingAppInfoQueue::s_mutex; + +PendingAppInfoQueue &PendingAppInfoQueue::getAppInfoQueue() +{ + static PendingAppInfoQueue instance; + return instance; +} + +void PendingAppInfoQueue::enqueue(const PendingAppInfo &appInfo) +{ + QMutexLocker locker(&s_mutex); + m_handleTimes++; + int index = m_cache.indexOf(appInfo); + if (index == -1) { + m_cache << appInfo; + } else { + //已插入项操作类型为对某字段更新 + if (m_cache[index].handleType() > PendingAppInfo::HandleType::UpdateAll) { + if (appInfo.handleType() > PendingAppInfo::HandleType::UpdateAll) { + m_cache[index].merge(appInfo); + } else { + m_cache[index].setHandleType(appInfo); + } + } else { + //已插入项操作类型为对全部字段进行增删改时,设置为优先级高的操作类型 + if (m_cache[index].handleType() > appInfo.handleType()) { + m_cache[index].setHandleType(appInfo); + } + } + } + + //启动定时器 + if (!m_maxProcessTimer->isActive()) { + qDebug() << "start max timer"; + Q_EMIT this->startMaxProcessTimer(); + } + Q_EMIT this->startMinProcessTimer(); +} + +void PendingAppInfoQueue::run() +{ + exec(); +} + +PendingAppInfoQueue::PendingAppInfoQueue(QObject *parent) : QThread(parent) +{ + this->start(); + + m_handleTimes = 0; + + m_minProcessTimer = new QTimer; + m_maxProcessTimer = new QTimer; + + m_minProcessTimer->setInterval(500); + m_maxProcessTimer->setInterval(5*1000); + + m_minProcessTimer->setSingleShot(true); + m_maxProcessTimer->setSingleShot(true); + + m_minProcessTimer->moveToThread(this); + m_maxProcessTimer->moveToThread(this); + + connect(this, SIGNAL(startMinProcessTimer()), m_minProcessTimer, SLOT(start())); + connect(this, SIGNAL(startMaxProcessTimer()), m_maxProcessTimer, SLOT(start())); + + connect(this, &PendingAppInfoQueue::stopTimer, m_minProcessTimer, &QTimer::stop); + connect(this, &PendingAppInfoQueue::stopTimer, m_maxProcessTimer, &QTimer::stop); + + connect(m_minProcessTimer, &QTimer::timeout, this, &PendingAppInfoQueue::processCache); + connect(m_maxProcessTimer, &QTimer::timeout, this, &PendingAppInfoQueue::processCache); +} + +PendingAppInfoQueue::~PendingAppInfoQueue() +{ + if (m_minProcessTimer) { + delete m_minProcessTimer; + } + if (m_maxProcessTimer) { + delete m_maxProcessTimer; + } +} + +void PendingAppInfoQueue::processCache() +{ + s_mutex.lock(); + qDebug() << "handle apps:" << m_handleTimes; + m_handleTimes = 0; + m_cache.swap(m_pendingAppInfos); + s_mutex.unlock(); + + if (m_pendingAppInfos.isEmpty()) { + qWarning() << "No App Info will be process, I'll stop process cache of app queue."; + return; + } + + if (AppDBManager::getInstance()->startTransaction()) { + for (const PendingAppInfo &info : m_pendingAppInfos) { + PendingAppInfo::HandleTypes handleTypes = info.handleType(); + if (handleTypes < PendingAppInfo::HandleType::UpdateAll) { + switch (handleTypes) { + case PendingAppInfo::HandleType::Delete: + AppDBManager::getInstance()->handleDBItemDelete(info.path()); + break; + case PendingAppInfo::HandleType::Insert: + AppDBManager::getInstance()->handleDBItemInsert(info.path()); + break; + case PendingAppInfo::HandleType::UpdateAll: + AppDBManager::getInstance()->handleDBItemUpdate(info.path()); + break; + default: + break; + } + } else { + if (handleTypes & PendingAppInfo::HandleType::UpdateLocaleData) { + AppDBManager::getInstance()->handleLocaleDataUpdate(info.path()); + } + if (handleTypes & PendingAppInfo::HandleType::UpdateLaunchTimes) { + AppDBManager::getInstance()->handleLaunchTimesUpdate(info.path()); + } + if (handleTypes & PendingAppInfo::HandleType::UpdateFavorites) { + AppDBManager::getInstance()->handleFavoritesStateUpdate(info.path(), info.favoritesState()); + } + if (handleTypes & PendingAppInfo::HandleType::UpdateTop) { + AppDBManager::getInstance()->handleTopStateUpdate(info.path(), info.topState()); + } + if (handleTypes & PendingAppInfo::HandleType::UpdateLock) { + AppDBManager::getInstance()->handleLockStateUpdate(info.path(), info.lockState()); + } + } + } + + if (AppDBManager::getInstance()->startCommit()) { + Q_EMIT AppDBManager::getInstance()->finishHandleAppDB(); + } + + m_pendingAppInfos.clear(); + m_pendingAppInfos.squeeze(); + } +} + diff --git a/ukui-search-app-data-service/pending-app-info-queue.h b/ukui-search-app-data-service/pending-app-info-queue.h new file mode 100644 index 0000000..df1d11c --- /dev/null +++ b/ukui-search-app-data-service/pending-app-info-queue.h @@ -0,0 +1,51 @@ +#ifndef PENDINGAPPINFOQUEUE_H +#define PENDINGAPPINFOQUEUE_H + +#include "pending-app-info.h" + +#include +#include +#include +#include + +namespace UkuiSearch{ + +class PendingAppInfoQueue : public QThread +{ + Q_OBJECT +public: + static PendingAppInfoQueue &getAppInfoQueue(); + void enqueue(const PendingAppInfo& appInfo); + +protected: + void run() override; + +private: + explicit PendingAppInfoQueue(QObject *parent = nullptr); + PendingAppInfoQueue(const PendingAppInfoQueue&) = delete; + PendingAppInfoQueue& operator =(const PendingAppInfoQueue&) = delete; + ~PendingAppInfoQueue(); + + void processCache(); + +private: + static QMutex s_mutex; + + QTimer *m_minProcessTimer = nullptr; + QTimer *m_maxProcessTimer = nullptr; + + QVector m_cache; + QVector m_pendingAppInfos; + + int m_handleTimes; + +Q_SIGNALS: + void startMinProcessTimer(); + void startMaxProcessTimer(); + void stopTimer(); +}; +} + + + +#endif // PENDINGAPPINFOQUEUE_H diff --git a/ukui-search-app-data-service/pending-app-info.h b/ukui-search-app-data-service/pending-app-info.h new file mode 100644 index 0000000..8fd0639 --- /dev/null +++ b/ukui-search-app-data-service/pending-app-info.h @@ -0,0 +1,73 @@ +#ifndef PENDINGAPPINFO_H +#define PENDINGAPPINFO_H + +#include +#include + +namespace UkuiSearch { + +class PendingAppInfo +{ +public: + enum HandleType{ + Delete = 0, + Insert = 1u, + UpdateAll = 1u << 1, + UpdateLocaleData = 1u << 2, + UpdateLaunchTimes = 1u << 3, + UpdateFavorites = 1u << 4, + UpdateTop = 1u << 5, + UpdateLock = 1u << 6 + }; + Q_DECLARE_FLAGS(HandleTypes, HandleType) + + PendingAppInfo() = default; + PendingAppInfo(QString desktopfp, HandleTypes type, int favorites = -1, int top = -1, int lock = -1) + : m_desktopfp(desktopfp), + m_handleType(type), + m_favoritesState(favorites), + m_topState(top), + m_lockState(lock) {} + + QString path() const {return m_desktopfp;} + HandleTypes handleType() const {return m_handleType;} + int favoritesState() const {return m_favoritesState;} + int topState() const {return m_topState;} + int lockState() const {return m_lockState;} + + void setHandleType(const PendingAppInfo & info) {m_handleType = info.handleType();} + void setFavorites(int favoritesState) {m_favoritesState = favoritesState;} + void setTop(int top) {m_topState = top;} + void setLock(int lock) {m_lockState = lock;} + void merge(const PendingAppInfo &info) + { + m_handleType |= info.handleType(); + + if (info.favoritesState() != -1) { + m_favoritesState = info.favoritesState(); + } + + if (info.topState() != -1) { + m_topState = info.topState(); + } + + if (info.lockState() != -1) { + m_lockState = info.lockState(); + } + } + + bool operator ==(const PendingAppInfo& rhs) const { + return (m_desktopfp == rhs.m_desktopfp); + } +private: + QString m_desktopfp; + HandleTypes m_handleType; + int m_favoritesState; + int m_topState; + int m_lockState; +}; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(UkuiSearch::PendingAppInfo::HandleTypes) + +#endif // PENDINGAPPINFO_H diff --git a/ukui-search-app-data-service/signal-transformer.h b/ukui-search-app-data-service/signal-transformer.h index 4f2d4fa..6bb4ef4 100644 --- a/ukui-search-app-data-service/signal-transformer.h +++ b/ukui-search-app-data-service/signal-transformer.h @@ -10,7 +10,7 @@ using namespace UkuiSearch; class SignalTransformer : public QObject { - Q_CLASSINFO("D-Bus Interface","org.ukui.search.appdb") + Q_CLASSINFO("D-Bus Interface","org.ukui.search.signalTransformer") Q_OBJECT diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.cpp b/ukui-search-app-data-service/ukui-search-app-data-service.cpp index e2d6ae3..592a1c8 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.cpp +++ b/ukui-search-app-data-service/ukui-search-app-data-service.cpp @@ -32,8 +32,13 @@ UkuiSearchAppDataService::UkuiSearchAppDataService(int &argc, char *argv[], cons if (!sessionBus.registerService("com.ukui.search.appdb.service")) { qCritical() << "QDbus register service failed reason:" << sessionBus.lastError(); } - if(!sessionBus.registerObject("/org/ukui/search/appDataBase", SignalTransformer::getTransformer(), QDBusConnection::ExportAllSignals)) { - qCritical() << "ukui-search-fileindex dbus register object failed reason:" << sessionBus.lastError(); + + if(!sessionBus.registerObject("/org/ukui/search/appDataBase/dbManager", AppDBManager::getInstance(), QDBusConnection::ExportAllSlots)) { + qCritical() << "ukui-search-app-db-manager dbus register object failed reason:" << sessionBus.lastError(); + } + + if(!sessionBus.registerObject("/org/ukui/search/appDataBase/signalTransformer", SignalTransformer::getTransformer(), QDBusConnection::ExportAllSignals)) { + qCritical() << "ukui-search-signal-transformer dbus register object failed reason:" << sessionBus.lastError(); } connect(this, &QtSingleApplication::messageReceived, [ & ](QString msg) { diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.pro b/ukui-search-app-data-service/ukui-search-app-data-service.pro index e34dd85..82c6fe2 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.pro +++ b/ukui-search-app-data-service/ukui-search-app-data-service.pro @@ -29,12 +29,15 @@ SOURCES += \ main.cpp \ convert-winid-to-desktop.cpp \ app-db-manager.cpp \ + pending-app-info-queue.cpp \ signal-transformer.cpp \ ukui-search-app-data-service.cpp \ HEADERS += \ convert-winid-to-desktop.h \ app-db-manager.h \ + pending-app-info-queue.h \ + pending-app-info.h \ signal-transformer.h \ ukui-search-app-data-service.h \