Skip to content

Commit

Permalink
Merge pull request #2 from uklotzde/feature/crate_selectbox
Browse files Browse the repository at this point in the history
Optimize formatting of string lists for SQL queries
  • Loading branch information
poelzi authored Nov 11, 2017
2 parents 0a75b38 + de8f406 commit 7f2e1e7
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions src/library/crate/cratestorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,26 @@ class CrateQueryBinder {
FwdSqlQuery& m_query;
};

const QChar kSqlListSeparator(',');

// It is not possible to bind multiple values as a list to a query.
// The list of track ids has to be transformed into a single list
// string before it can be used in an SQL query.
QString joinSqlStringList(const QList<TrackId>& trackIds) {
QString joinedTrackIds;
// Reserve memory up front to prevent reallocation. Here we
// assume that all track ids fit into 6 decimal digits and
// add 1 character for the list separator.
joinedTrackIds.reserve((6 + 1) * trackIds.size());
for (const auto trackId: trackIds) {
if (!joinedTrackIds.isEmpty()) {
joinedTrackIds += kSqlListSeparator;
}
joinedTrackIds += trackId.toString();
}
return joinedTrackIds;
}

} // anonymous namespace


Expand Down Expand Up @@ -469,18 +489,6 @@ CrateTrackSelectResult CrateStorage::selectTrackCratesSorted(TrackId trackId) co
}

CrateSummarySelectResult CrateStorage::selectCratesWithTrackCount(const QList<TrackId>& trackIds) const {

// unfortunatelly we can't bind a QList to a SqlQuery therefor we have to construct a String first
// see: https://stackoverflow.com/questions/3220357/qt-how-to-bind-a-qlist-to-a-qsqlquery-with-a-where-in-clause
// Using bindValue did not work, only constructing the SQL string befor.
// As TrackId is a int, we are safe here
QStringList idstrings;
foreach(TrackId id, trackIds) {
idstrings << id.toString();
}
QString numberlist = idstrings.join(",");
QString ids = QString("%1").arg(numberlist);

FwdSqlQuery query(m_database, QString(
"SELECT *, ("
" SELECT COUNT(*) FROM %1 WHERE %2.%3 = %1.%4 and %1.%5 in (%9)"
Expand All @@ -493,14 +501,13 @@ CrateSummarySelectResult CrateStorage::selectCratesWithTrackCount(const QList<Tr
CRATESUMMARY_TRACK_COUNT,
CRATESUMMARY_TRACK_DURATION,
CRATETABLE_NAME,
ids));
joinSqlStringList(trackIds)));

if (query.execPrepared()) {
return CrateSummarySelectResult(std::move(query));
} else {
return CrateSummarySelectResult();
}

}


Expand Down

0 comments on commit 7f2e1e7

Please sign in to comment.