1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 10:46:35 +01:00

Fix performance when querying icons from database

Make use of the index on icons column by using GLOB
instead of LIKE and handle the escaping ourselves.

Closes #1679
This commit is contained in:
David Rosca 2016-12-20 14:19:58 +01:00
parent 3a9e0501df
commit 8a2fc0862f
6 changed files with 43 additions and 17 deletions

View File

@ -65,9 +65,8 @@ void IconChooser::searchIcon(const QString &string)
ui->iconList->clear(); ui->iconList->clear();
QSqlQuery query; QSqlQuery query;
query.prepare(QSL("SELECT icon FROM icons WHERE url LIKE ? ESCAPE ? LIMIT 20")); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 20"));
query.bindValue(0, QString(QL1S("%%1%")).arg(QzTools::escapeSqlString(string))); query.addBindValue(QString(QL1S("*%1*")).arg(QzTools::escapeSqlGlobString(string)));
query.bindValue(1, QL1S("!"));
query.exec(); query.exec();
while (query.next()) { while (query.next()) {

View File

@ -185,10 +185,8 @@ QImage IconProvider::imageForUrl(const QUrl &url, bool allowEmpty)
} }
QSqlQuery query; QSqlQuery query;
query.prepare(QSL("SELECT icon FROM icons WHERE url LIKE ? ESCAPE ? LIMIT 1")); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1"));
query.addBindValue(QString("%1*").arg(QzTools::escapeSqlGlobString(QString::fromUtf8(url.toEncoded(QUrl::RemoveFragment)))));
query.addBindValue(QString("%1%").arg(QzTools::escapeSqlString(QString::fromUtf8(url.toEncoded(QUrl::RemoveFragment)))));
query.addBindValue(QL1S("!"));
SqlDatabase::instance()->exec(query); SqlDatabase::instance()->exec(query);
if (query.next()) { if (query.next()) {
@ -216,10 +214,9 @@ QImage IconProvider::imageForDomain(const QUrl &url, bool allowEmpty)
} }
QSqlQuery query; QSqlQuery query;
query.prepare(QSL("SELECT icon FROM icons WHERE url LIKE ? ESCAPE ? LIMIT 1")); query.prepare(QSL("SELECT icon FROM icons WHERE url GLOB ? LIMIT 1"));
query.addBindValue(QString("%%1%").arg(QzTools::escapeSqlString(url.host()))); query.addBindValue(QString("*%1*").arg(QzTools::escapeSqlGlobString(url.host())));
query.addBindValue(QL1S("!"));
query.exec(); query.exec();
if (query.next()) { if (query.next()) {

View File

@ -198,13 +198,13 @@ QString QzTools::fromPunycode(const QString &str)
return decoded.left(decoded.size() - 4); return decoded.left(decoded.size() - 4);
} }
QString QzTools::escapeSqlString(QString urlString) QString QzTools::escapeSqlGlobString(QString urlString)
{ {
const static QString &escapeString = QL1S("!"); urlString.replace(QL1C('['), QStringLiteral("[["));
urlString.replace(escapeString, escapeString + escapeString); urlString.replace(QL1C(']'), QStringLiteral("[]]"));
urlString.replace(QL1S("_"), escapeString + QL1S("_")); urlString.replace(QStringLiteral("[["), QStringLiteral("[[]"));
urlString.replace(QL1S("%"), escapeString + QL1S("%")); urlString.replace(QL1C('*'), QStringLiteral("[*]"));
urlString.replace(QL1C('?'), QStringLiteral("[?]"));
return urlString; return urlString;
} }

View File

@ -48,7 +48,7 @@ public:
static QString samePartOfStrings(const QString &one, const QString &other); static QString samePartOfStrings(const QString &one, const QString &other);
static QString urlEncodeQueryString(const QUrl &url); static QString urlEncodeQueryString(const QUrl &url);
static QString fromPunycode(const QString &str); static QString fromPunycode(const QString &str);
static QString escapeSqlString(QString urlString); static QString escapeSqlGlobString(QString urlString);
static QString ensureUniqueFilename(const QString &name, const QString &appendFormat = QString("(%1)")); static QString ensureUniqueFilename(const QString &name, const QString &appendFormat = QString("(%1)"));
static QString getFileNameFromUrl(const QUrl &url); static QString getFileNameFromUrl(const QUrl &url);

View File

@ -134,6 +134,33 @@ void QzToolsTest::splitCommandArguments()
QCOMPARE(QzTools::splitCommandArguments(command), result); QCOMPARE(QzTools::splitCommandArguments(command), result);
} }
void QzToolsTest::escapeSqlGlobString_data()
{
QTest::addColumn<QString>("input");
QTest::addColumn<QString>("result");
QTest::newRow("NothingToEscape") << "http://test" << "http://test";
QTest::newRow("Escape *") << "http://test*/heh" << "http://test[*]/heh";
QTest::newRow("Escape **") << "http://test**/he*h" << "http://test[*][*]/he[*]h";
QTest::newRow("Escape ?") << "http://test?/heh" << "http://test[?]/heh";
QTest::newRow("Escape ??") << "http://t??est?/heh" << "http://t[?][?]est[?]/heh";
QTest::newRow("Escape [") << "http://[test/heh" << "http://[[]test/heh";
QTest::newRow("Escape [[") << "http://[[te[st/heh" << "http://[[][[]te[[]st/heh";
QTest::newRow("Escape ]") << "http://]test/heh" << "http://[]]test/heh";
QTest::newRow("Escape ]]") << "http://]]te]st/heh" << "http://[]][]]te[]]st/heh";
QTest::newRow("Escape []") << "http://[]test/heh" << "http://[[][]]test/heh";
QTest::newRow("Escape [][[]][]") << "http://t[][[]][]est/heh" << "http://t[[][]][[][[][]][]][[][]]est/heh";
QTest::newRow("Escape [?]][[*]") << "http://t[?]][[*]est/heh" << "http://t[[][?][]][]][[][[][*][]]est/heh";
}
void QzToolsTest::escapeSqlGlobString()
{
QFETCH(QString, input);
QFETCH(QString, result);
QCOMPARE(QzTools::escapeSqlGlobString(input), result);
}
class TempFile class TempFile
{ {
QString name; QString name;

View File

@ -37,6 +37,9 @@ private slots:
void splitCommandArguments_data(); void splitCommandArguments_data();
void splitCommandArguments(); void splitCommandArguments();
void escapeSqlGlobString_data();
void escapeSqlGlobString();
void ensureUniqueFilename(); void ensureUniqueFilename();
private: private: