ukui-search/libsearch/appdata/app-info-table.cpp

676 lines
21 KiB
C++
Raw Normal View History

#include "app-info-table.h"
#include "app-info-table-private.h"
#include "app-info-dbus-argument.h"
#include <QDebug>
#include <QtGlobal>
#include <string>
#include <QStandardPaths>
#include <QProcess>
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusMetaType>
#include <QFileInfo>
#include <QTime>
#include <QSqlQuery>
#include <QSqlError>
#include <mutex>
#include <QFile>
#include <application-property-helper.h>
2022-03-01 17:39:53 +08:00
using namespace UkuiSearch;
static std::once_flag flag;
static AppInfoTable *global_intance = nullptr;
AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent), q(parent), m_database(new QSqlDatabase())
{
//dbus接收数据库信号
qRegisterMetaType<AppInfoResult>("AppInfoResult");
qRegisterMetaType<QVector<AppInfoResult>>("QVector<AppInfoResult>");
qDBusRegisterMetaType<AppInfoResult>();
qDBusRegisterMetaType<QVector<AppInfoResult>>();
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_signalTransInterface, SIGNAL(appDBItemsAdd(QVector<AppInfoResult>)), this, SLOT(sendAppDBItemsAdd(QVector<AppInfoResult>)));
connect(m_signalTransInterface, SIGNAL(appDBItemsUpdate(QVector<AppInfoResult>)), this, SLOT(sendAppDBItemsUpdate(QVector<AppInfoResult>)));
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()));//随机生产链接
if (!QSqlDatabase::contains(m_ConnectionName))
break;
}
qDebug() << "App info database currunt connection name:" << m_ConnectionName;
if (!this->openDataBase()) {
Q_EMIT q->DBOpenFailed();
qWarning() << "Fail to open App DataBase, because:" << m_database->lastError();
}
}
void AppInfoTablePrivate::setAppFavoritesState(QString &desktopfp, int num)
{
m_appDBInterface->call("updateFavoritesState", desktopfp, num);
}
void AppInfoTablePrivate::setAppTopState(QString &desktopfp, int num)
{
m_appDBInterface->call("updateTopState", desktopfp, num);
}
bool AppInfoTablePrivate::changeFavoriteAppPos(const QString &desktopfp, int pos)
{
QDBusReply<bool> reply = m_appDBInterface->call("changeFavoriteAppPos", desktopfp, pos);
if (reply.isValid()) {
return reply.value();
} else {
qDebug() << m_appDBInterface->lastError();
return false;
}
}
bool AppInfoTablePrivate::changeTopAppPos(const QString &desktopfp, int pos)
{
QDBusReply<bool> reply = m_appDBInterface->call("changeTopAppPos", desktopfp, pos);
if (reply.isValid()) {
return reply.value();
} else {
qDebug() << m_appDBInterface->lastError();
return false;
}
}
bool AppInfoTablePrivate::getAppInfoResults(QVector<AppInfoResult> &appInfoResults)
{
QDBusReply<QVector<AppInfoResult>> reply = m_appDBInterface->call("getAppInfoResults");
if (reply.isValid()) {
appInfoResults = reply.value();
return true;
} else {
return false;
}
}
bool AppInfoTablePrivate::getAppLockState(QString &desktopfp, size_t &num)
{
QDBusReply<int> reply = m_appDBInterface->call("getAppLockState", desktopfp);
if (!reply.isValid()) {
qWarning() << m_appDBInterface->lastError();
return false;
} else {
num = reply.value();
if (num == -1) {
qWarning() << "There's something wrong while using database";
return false;
}
return true;
}
}
bool AppInfoTablePrivate::getAppTopState(QString &desktopfp, size_t &num)
{
QDBusReply<int> reply = m_appDBInterface->call("getAppTopState", desktopfp);
if (!reply.isValid()) {
qWarning() << m_appDBInterface->lastError();
return false;
} else {
num = reply.value();
if (num == -1) {
qWarning() << "There's something wrong while using database";
return false;
}
return true;
}
}
bool AppInfoTablePrivate::getAppLaunchedState(QString &desktopfp, size_t &num)
{
QDBusReply<int> reply = m_appDBInterface->call("getAppLaunchedState", desktopfp);
if (!reply.isValid()) {
qWarning() << m_appDBInterface->lastError();
return false;
} else {
num = reply.value();
if (num == -1) {
qWarning() << "There's something wrong while using database";
return false;
}
return true;
}
}
bool AppInfoTablePrivate::getAppFavoriteState(QString &desktopfp, size_t &num)
{
QDBusReply<int> reply = m_appDBInterface->call("getAppFavoriteState", desktopfp);
if (!reply.isValid()) {
qWarning() << m_appDBInterface->lastError();
return false;
} else {
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<QString> reply = m_appDBInterface->call("getAppCategory", desktopfp);
if (reply.isValid()) {
category = reply.value();
return true;
} else {
qDebug() << m_appDBInterface->lastError();
return false;
}
}
bool AppInfoTablePrivate::searchInstallApp(QString &keyWord, QStringList &installAppInfoRes)
{
bool res(true);
if (m_database->transaction()) {
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")
.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")
.arg(keyWord);
}
if (sql.exec(cmd)) {
while (sql.next()) {
installAppInfoRes << sql.value(0).toString() << sql.value(1).toString() << sql.value(2).toString();
}
} 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::searchInstallApp(QStringList &keyWord, QStringList &installAppInfoRes)
{
bool res(true);
if (m_database->transaction() or keyWord.size() != 0) {
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"
" 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"
" 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));
}
for (int i = 0; ++i<keyWord.size();) {
if (keyWord.at(i).size() < 2) {
cmd += QString(" AND (LOCAL_NAME LIKE '%%1%' OR NAME_EN LIKE '%%1%' OR NAME_ZH LIKE '%%1%' OR FIRST_LETTER_OF_PINYIN LIKE '%%1%')")
.arg(keyWord.at(i));
} else {
cmd += QString(" AND (LOCAL_NAME LIKE '%%1%' OR NAME_EN LIKE '%%1%' OR NAME_ZH LIKE '%%1%' OR PINYIN_NAME LIKE '%%1%' OR FIRST_LETTER_OF_PINYIN LIKE '%%1%')")
.arg(keyWord.at(i));
}
}
cmd += QString(" ORDER BY LENGTH(LOCAL_NAME)");
if (sql.exec(cmd)) {
while (sql.next()) {
installAppInfoRes << sql.value(0).toString() << sql.value(1).toString() << sql.value(2).toString();
}
} 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!!! keyword size:" << keyWord.size();
res = false;
}
return res;
}
QString AppInfoTablePrivate::lastError() const
{
return m_database->lastError().text();
}
bool AppInfoTablePrivate::tranPidToDesktopFp(int pid, QString &desktopfp)
{
QDBusReply<QString> reply = m_appDBInterface->call("tranPidToDesktopFp", pid);
if (reply.isValid()) {
desktopfp = reply.value();
return true;
} else {
qDebug() << m_appDBInterface->lastError();
return false;
}
}
bool AppInfoTablePrivate::setAppLaunchTimes(QString &desktopfp, size_t num)
{
bool res(true);
if (m_database->transaction()) {
QSqlQuery sql(*m_database);
QString 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(num)
.arg(1)
.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 {
qWarning() << "Failed to start transaction mode!!!";
res = false;
}
return res;
}
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);
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'")
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(sql.value(0).toInt() + 1)
.arg(1)
.arg(desktopfp);
if (!sql.exec(cmd)) {
qWarning() << "Set app favorites state failed!" << m_database->lastError();
res = false;
}
} else {
qWarning() << "Failed to exec next!" << cmd;
res = false;
}
} else {
qWarning() << "Failed to exec:" << cmd;
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::setAppLockState(QString &desktopfp, size_t num)
{
bool res(true);
if (m_database->transaction()) {
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;
}
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::getAllAppDesktopList(QStringList &list)
{
bool res(true);
QSqlQuery sql(*m_database);
QString cmd = QString("SELECT DESKTOP_FILE_PATH FROM APPINFO");
if (sql.exec(cmd)) {
while (sql.next()) {
list.append(sql.value(0).toString());
}
} else {
qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError();
res = false;
}
return res;
}
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");
if (sql.exec(cmd)) {
while (sql.next()) {
list.append(sql.value(0).toString());
}
} else {
qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError();
res = false;
}
return res;
}
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");
if (sql.exec(cmd)) {
while (sql.next()) {
list.append(sql.value(0).toString());
}
} else {
qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError();
res = false;
}
return res;
}
bool AppInfoTablePrivate::getLaunchTimesAppList(QStringList &list)
{
bool res(true);
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");
int count = 0;
if (sql.exec(cmd)) {
while (sql.next()) {
list.append(sql.value(0).toString());
cmd = QString("UPDATE appInfo SET TOP=%1 WHERE DESKTOP_FILE_PATH='%2'")
.arg(++count)
.arg(sql.value(0).toString());
if (!sqlque.exec(cmd)) {
qWarning() << QString("cmd %0 failed!").arg(cmd) << m_database->lastError();
res = false;
break;
}
}
} 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;
}
AppInfoTablePrivate::~AppInfoTablePrivate()
{
this->closeDataBase();
if (m_signalTransInterface)
delete m_signalTransInterface;
m_signalTransInterface = nullptr;
if (m_appDBInterface)
delete m_appDBInterface;
m_appDBInterface = nullptr;
}
bool AppInfoTablePrivate::initDateBaseConnection()
{
m_database->setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME);
if(!m_database->open()) {
qWarning() << m_database->lastError();
return false;
// QApplication::quit();
}
return true;
}
bool AppInfoTablePrivate::openDataBase()
{
*m_database = QSqlDatabase::addDatabase("QSQLITE", m_ConnectionName);
m_database->setDatabaseName(APP_DATABASE_PATH + APP_DATABASE_NAME);
if(!m_database->open()) {
return false;
}
return true;
}
void AppInfoTablePrivate::closeDataBase()
2022-03-01 17:39:53 +08:00
{
m_database->close();
delete m_database;
m_database = nullptr;
QSqlDatabase::removeDatabase(m_ConnectionName);
2022-03-01 17:39:53 +08:00
}
void AppInfoTablePrivate::sendAppDBItemsUpdate(QVector<AppInfoResult> results)
{
Q_EMIT q->appDBItems2BUpdate(results);
}
void AppInfoTablePrivate::sendAppDBItemsAdd(QVector<AppInfoResult> results)
{
Q_EMIT q->appDBItems2BAdd(results);
}
void AppInfoTablePrivate::sendAppDBItemsDelete(QStringList desktopfps)
{
Q_EMIT q->appDBItems2BDelete(desktopfps);
}
AppInfoTable *AppInfoTable::self()
{
std::call_once(flag, [ & ] {
global_intance = new AppInfoTable();
});
return global_intance;
}
2022-03-01 17:39:53 +08:00
AppInfoTable::AppInfoTable(QObject *parent) : QObject(parent), d(new AppInfoTablePrivate(this))
{
}
bool AppInfoTable::query(PropertyMap &propertyMap, const QString &desktopFile, Properties properties)
{
QString field;
for(const ApplicationProperty::Property &pro : properties) {
field.append(ApplicationPropertyHelper(pro).dataBaseField() + ",");
}
field.remove(field.length() - 1, 1);
QSqlQuery query(*d->m_database);
query.setForwardOnly(true);
query.prepare(QString("SELECT %0 FROM APPINFO WHERE DESKTOP_FILE_PATH=:desktopFile").arg(field));
query.bindValue(":desktopFile", desktopFile);
if (!query.exec()) {
qWarning() << d->m_database->lastError() << query.lastError();
return false;
}
while (query.next()) {
for(int i = 0; i< properties.size(); i++) {
propertyMap.insert(properties.at(i), query.value(i));
}
}
return true;
}
bool AppInfoTable::query(ApplicationInfoMap &infoMap, Properties properties)
{
QString field(ApplicationPropertyHelper(ApplicationProperty::Property::DesktopFilePath).dataBaseField());
for(const ApplicationProperty::Property &pro : properties) {
field.append("," + ApplicationPropertyHelper(pro).dataBaseField());
}
QString sql = QString("SELECT %0 FROM APPINFO").arg(field);
QSqlQuery query(*d->m_database);
query.setForwardOnly(true);
if (!query.exec(sql)) {
qWarning() << d->m_database->lastError() << sql;
return false;
}
while (query.next()) {
PropertyMap propertyMap;
for(int i = 1; i< properties.size(); i++) {
propertyMap.insert(properties.at(i), query.value(i));
}
infoMap.insert(query.value(0).toString(), propertyMap);
}
return true;
}
void AppInfoTable::setAppFavoritesState(QString &desktopfp, size_t num)
{
return d->setAppFavoritesState(desktopfp, num);
}
void AppInfoTable::setAppTopState(QString &desktopfp, size_t num)
{
return d->setAppTopState(desktopfp, num);
}
bool AppInfoTable::getAppCategory(QString &desktopfp, QString &category)
{
return d->getAppCategory(desktopfp, category);
}
bool AppInfoTable::changeFavoriteAppPos(const QString &desktopfp, size_t pos)
{
return d->changeFavoriteAppPos(desktopfp, pos);
}
bool AppInfoTable::changeTopAppPos(const QString &desktopfp, size_t pos)
{
return d->changeTopAppPos(desktopfp, pos);
}
bool AppInfoTable::getAppInfoResults(QVector<AppInfoResult> &appInfoResults)
{
return d->getAppInfoResults(appInfoResults);
}
bool AppInfoTable::getAppLockState(QString &desktopfp, size_t &num)
{
return d->getAppLockState(desktopfp, num);
}
bool AppInfoTable::getAppTopState(QString &desktopfp, size_t &num)
{
return d->getAppTopState(desktopfp, num);
}
bool AppInfoTable::getAppLaunchedState(QString &desktopfp, size_t &num)
{
return d->getAppLaunchedState(desktopfp, num);
}
bool AppInfoTable::getAppFavoriteState(QString &desktopfp, size_t &num)
{
return d->getAppFavoriteState(desktopfp, num);
}
bool AppInfoTable::searchInstallApp(QString &keyWord, QStringList &installAppInfoRes)
{
return d->searchInstallApp(keyWord, installAppInfoRes);
}
bool AppInfoTable::searchInstallApp(QStringList &keyWord, QStringList &installAppInfoRes)
{
return d->searchInstallApp(keyWord, installAppInfoRes);
}
QString AppInfoTable::lastError() const
{
return d->lastError();
}
bool AppInfoTable::tranPidToDesktopFp(int pid, QString &desktopfp)
{
return d->tranPidToDesktopFp(pid, desktopfp);
}
//下面接口暂时没啥用,不外放。
bool AppInfoTable::setAppLaunchTimes(QString &desktopfp, size_t num)
{
return d->setAppLaunchTimes(desktopfp, num);
}
bool AppInfoTable::updateAppLaunchTimes(QString &desktopfp)
{
return d->updateAppLaunchTimes(desktopfp);
}
bool AppInfoTable::setAppLockState(QString &desktopfp, size_t num)
{
return d->setAppLockState(desktopfp, num);
}
bool AppInfoTable::getAllAppDesktopList(QStringList &list)
{
return d->getAllAppDesktopList(list);
}
bool AppInfoTable::getFavoritesAppList(QStringList &list)
{
return d->getFavoritesAppList(list);
}
bool AppInfoTable::getTopAppList(QStringList &list)
{
return d->getTopAppList(list);
}
bool AppInfoTable::getLaunchTimesAppList(QStringList &list)
{
return d->getLaunchTimesAppList(list);
}