perf(app-database-service):add keywords field and use it to find applications more accurately.

This commit is contained in:
JunjieBai 2023-11-28 17:15:31 +08:00 committed by iaom
parent 8f1a039d5e
commit be196b07ea
6 changed files with 56 additions and 19 deletions

View File

@ -474,17 +474,16 @@ bool AppInfoTable::query(ApplicationInfoMap &infoMap, ApplicationProperties prop
return true;
}
bool AppInfoTable::query(ApplicationInfoMap &infoMap, ApplicationProperties properties, const QStringList &keywords, ApplicationPropertyMap restrictions)
bool AppInfoTable::query(ApplicationInfoMap &infoMap, const ApplicationProperties& properties, const QStringList &keywords, const ApplicationPropertyMap& restrictions)
{
QString field;
for(const ApplicationProperty::Property &pro : properties) {
field.append(ApplicationPropertyHelper(pro).dataBaseField() + ",");
}
if(!properties.contains(ApplicationProperty::Property::DesktopFilePath)) {
field.append(ApplicationPropertyHelper(ApplicationProperty::Property::DesktopFilePath).dataBaseField());
} else if(!field.isEmpty()) {
field.remove(field.length() - 1, 1);
field.append(ApplicationPropertyHelper(ApplicationProperty::Property::DesktopFilePath).dataBaseField() + ",");
}
field.append(ApplicationPropertyHelper(ApplicationProperty::Property::LocalKeywords).dataBaseField());
QString condition;
for (const ApplicationProperty::Property prop: restrictions.keys()) {
@ -492,18 +491,28 @@ bool AppInfoTable::query(ApplicationInfoMap &infoMap, ApplicationProperties prop
}
QString keywordCondition;
QString findWithLocalKeywords = "((select count(*) from ("
"WITH RECURSIVE split(str, rest) AS "
"("
"SELECT substr(LOCAL_KEYWORDS || ';', 1, instr(LOCAL_KEYWORDS || ';', ';') - 1),"
"substr(LOCAL_KEYWORDS || ';', instr(LOCAL_KEYWORDS || ';', ';') + 1) "
"UNION ALL "
"SELECT substr(rest, 1, instr(rest, ';') - 1), substr(rest, instr(rest, ';') + 1) "
"FROM split WHERE str <> ''"
")"
"SELECT str FROM split WHERE lower(str)=?)) <> 0)";
for(const QString& keyword : keywords) {
if(keyword.size() < 2) {
keywordCondition.append("(ifnull(LOCAL_NAME, '') like ? or ifnull(NAME_EN, '') like ? or ifnull(NAME_ZH, '') like ? or ifnull(FIRST_LETTER_OF_PINYIN, '') like ?) AND");
keywordCondition.append(QString("(ifnull(LOCAL_NAME, '') like ? or ifnull(NAME_EN, '') like ? or ifnull(NAME_ZH, '') like ? or ifnull(FIRST_LETTER_OF_PINYIN, '') like ? or %0) AND").arg(findWithLocalKeywords));
} else {
keywordCondition.append("(ifnull(LOCAL_NAME, '') like ? or ifnull(NAME_EN, '') like ? or ifnull(NAME_ZH, '') like ? or ifnull(FIRST_LETTER_OF_PINYIN, '') like ? or ifnull(PINYIN_NAME, '') like ?) AND");
keywordCondition.append(QString("(ifnull(LOCAL_NAME, '') like ? or ifnull(NAME_EN, '') like ? or ifnull(NAME_ZH, '') like ? or ifnull(FIRST_LETTER_OF_PINYIN, '') like ? or ifnull(PINYIN_NAME, '') like ? or %0) AND").arg(findWithLocalKeywords));
}
}
if(!keywordCondition.isEmpty()) {
keywordCondition.remove(keywordCondition.length() - 3, 3);
}
QString sql = QString("SELECT %0 FROM APPINFO WHERE %1 %2 ORDER BY LENGTH(LOCAL_NAME)").arg(field).arg(condition).arg(keywordCondition);
QString sql = QString("SELECT %0 FROM APPINFO WHERE %1 %2 ORDER BY LENGTH(LOCAL_NAME)").arg(field, condition, keywordCondition);
QSqlQuery query(*d->m_database);
query.setForwardOnly(true);
query.prepare(sql);
@ -515,12 +524,12 @@ bool AppInfoTable::query(ApplicationInfoMap &infoMap, ApplicationProperties prop
}
for(const QString &keyword : keywords) {
int i = 5;
int i = 6;
if(keyword.size() < 2) {
i--;
}
for (int bindCount = 0; bindCount < i; bindCount++) {
query.bindValue(count, "%" + keyword + "%");
query.bindValue(count, (bindCount - i + 1) ? "%" + keyword + "%" : keyword.toLower());
count++;
}
}

View File

@ -43,7 +43,7 @@ public:
bool query(ApplicationPropertyMap &propertyMap, const QString &desktopFile, ApplicationProperties properties);
bool query(ApplicationInfoMap &infoMap, ApplicationProperties properties);
bool query(ApplicationInfoMap &infoMap, ApplicationProperties properties, ApplicationPropertyMap restrictions);
bool query(ApplicationInfoMap &infoMap, ApplicationProperties properties, const QStringList &keywords, ApplicationPropertyMap restrictions);
bool query(ApplicationInfoMap &infoMap, const ApplicationProperties& properties, const QStringList &keywords, const ApplicationPropertyMap& restrictions);
/**
* @brief AppInfoTable::setAppFavoritesState

View File

@ -43,7 +43,7 @@ ApplicationPropertyHelper::ApplicationPropertyHelper(ApplicationProperty::Proper
d->m_valueType = QMetaType::QString;
break;
case ApplicationProperty::NameZh:
d->m_databaseField = "NAME_EN";
d->m_databaseField = "NAME_ZH";
d->m_valueType = QMetaType::QString;
break;
case ApplicationProperty::PinyinName:
@ -110,6 +110,18 @@ ApplicationPropertyHelper::ApplicationPropertyHelper(ApplicationProperty::Proper
d->m_databaseField = "AUTO_START";
d->m_valueType = QMetaType::Int;
break;
case ApplicationProperty::StartUpWMClass:
d->m_databaseField = "START_UP_WMCLASS";
d->m_valueType = QMetaType::QString;
break;
case ApplicationProperty::Keywords:
d->m_databaseField = "KEYWORDS";
d->m_valueType = QMetaType::QString;
break;
case ApplicationProperty::LocalKeywords:
d->m_databaseField = "LOCAL_KEYWORDS";
d->m_valueType = QMetaType::QString;
break;
default:
break;
}

View File

@ -54,7 +54,10 @@ enum Property {
Top, //置顶顺序0 未置顶)
Lock, //是否锁定(不允许显示或打开)
DontDisplay, //是否不需要显示设置了Nodisplay等字段
AutoStart //是否自启动(位于自启动目录/etc/xdg/autostart下
AutoStart, //是否自启动(位于自启动目录/etc/xdg/autostart下
StartUpWMClass, //应用的className
Keywords, //关键词
LocalKeywords //关键词(本地化)
};
} //namespace ApplicationProperty
typedef QVector<ApplicationProperty::Property> ApplicationProperties;

View File

@ -217,7 +217,7 @@ 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, %22, %23)")
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, %22, %23, %24, %25)")
// .arg("ID INT")//自增id
.arg("DESKTOP_FILE_PATH TEXT PRIMARY KEY NOT NULL")//desktop文件路径
.arg("MODIFYED_TIME TEXT")//YYYYMMDDHHmmSS 修改日期
@ -241,7 +241,9 @@ void AppDBManager::buildAppInfoDB()
.arg("LOCK INT")//应用是否锁定管控0未锁定1锁定
.arg("DONT_DISPLAY INT")//应用隐藏(NoDisplay, NotShowIn)
.arg("AUTO_START INT")//自启应用
.arg("START_UP_WMCLASS TEXT");//classname
.arg("START_UP_WMCLASS TEXT")//classname
.arg("KEYWORDS TEXT")//应用的关键词
.arg("LOCAL_KEYWORDS TEXT");//应用本地关键词,跟随系统语言
if (!sql.exec(cmd)) {
qWarning() << m_database.lastError() << cmd;
return;
@ -417,10 +419,11 @@ bool AppDBManager::handleLocaleDataUpdate(const QString &desktopFilePath)
QSqlQuery query(m_database);
query.prepare("UPDATE appInfo SET LOCAL_NAME=:localName, FIRST_LETTER_ALL=:firstOfLetter2All WHERE DESKTOP_FILE_PATH=:desktopFilePath");
query.prepare("UPDATE appInfo SET LOCAL_NAME=:localName, FIRST_LETTER_ALL=:firstOfLetter2All, LOCAL_KEYWORDS=:localKeywords WHERE DESKTOP_FILE_PATH=:desktopFilePath");
query.bindValue(":localName", localName);
query.bindValue(":firstOfLetter2All", firstLetter2All);
query.bindValue(":desktopFilePath", desktopFilePath);
query.bindValue(":localKeywords", desktopFile.localizedValue("Keywords", "NULL").toString());
if (!this->startTransaction()) {
return false;
@ -576,9 +579,9 @@ bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath)
"LOCAL_NAME, NAME_EN, NAME_ZH, PINYIN_NAME, "
"FIRST_LETTER_OF_PINYIN, FIRST_LETTER_ALL, "
"ICON, TYPE, CATEGORY, EXEC, COMMENT, MD5, "
"LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY, AUTO_START, START_UP_WMCLASS) "
"LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY, AUTO_START, START_UP_WMCLASS, KEYWORDS, LOCAL_KEYWORDS) "
"VALUES(:desktopFilePath, '%0', '%1', :localName, :enName, :zhName, :pinyinName, :firstLetterOfPinyin, :firstLetter2All, "
":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8,%9, :wmClass)")
":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8,%9, :wmClass, :keywords, :localKeywords)")
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(getAppDesktopMd5(desktopFilePath))
@ -602,6 +605,8 @@ bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath)
sql.bindValue(":exec", desktopfile.value("Exec").toString());
sql.bindValue(":comment", desktopfile.value("Comment").toString());
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
sql.bindValue(":keywords", desktopfile.value("Keywords").toString());
sql.bindValue(":localKeywords", desktopfile.localizedValue("Keywords", "NULL").toString());
if (!this->startTransaction()) {
return false;
@ -779,6 +784,8 @@ bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath)
"EXEC=:exec,"
"COMMENT=:comment,"
"START_UP_WMCLASS=:wmClass,"
"KEYWORDS=:keywords,"
"LOCAL_KEYWORDS=:localKeywords,"
"MD5='%1',"
"DONT_DISPLAY=%2,"
"AUTO_START=%3 "
@ -800,6 +807,8 @@ bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath)
sql.bindValue(":exec", desktopfile.value("Exec").toString());
sql.bindValue(":comment", desktopfile.value("Comment").toString());
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
sql.bindValue(":keywords", desktopfile.value("Keywords").toString());
sql.bindValue(":localKeywords", desktopfile.localizedValue("Keywords", "NULL").toString());
if (!this->startTransaction()) {
return false;

View File

@ -41,8 +41,10 @@
#define CONNECTION_NAME QLatin1String("ukss-appdb-connection")
/**
* changelog(1.2 to 1.3): Add the START_UP_WMCLASS field in order to find desktop file path by the windowClassClass.
* changelog(1.3 to 1.4): Add the KEYWORDS & LOCAL_KEYWORDS field in order to find application conveniently.
*/
static const QString APP_DATABASE_VERSION = QStringLiteral("1.3");
static const QString APP_DATABASE_VERSION = QStringLiteral("1.4");
namespace UkuiSearch {
/**
@ -184,7 +186,9 @@ private:
{"LOCK", "INT"},
{"DONT_DISPLAY", "INT"},
{"AUTO_START", "INT"},
{"START_UP_WMCLASS", "TEXT"}
{"START_UP_WMCLASS", "TEXT"},
{"KEYWORDS", "TEXT"},
{"LOCAL_KEYWORDS", "TEXT"}
};
//应用黑名单