Skip to content

Commit

Permalink
Use optimized SQL query to select crates and count tracks.
Browse files Browse the repository at this point in the history
Unfortunatelly QSqlQuery has no way of binding QLists
in WHERE x IN statements.

Use make_partented as suggested by daschuer
  • Loading branch information
poelzi committed Nov 10, 2017
1 parent 5ee8f66 commit 97a0684
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 20 deletions.
37 changes: 37 additions & 0 deletions src/library/crate/cratestorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,43 @@ 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(",");
qDebug() << numberlist;
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)"
" ) AS %6, 0 as %7 FROM %2 ORDER BY %8").arg(
CRATE_TRACKS_TABLE,
CRATE_TABLE,
CRATETABLE_ID,
CRATETRACKSTABLE_CRATEID,
CRATETRACKSTABLE_TRACKID,
CRATESUMMARY_TRACK_COUNT,
CRATESUMMARY_TRACK_DURATION,
CRATETABLE_NAME,
ids));

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

}



CrateTrackSelectResult CrateStorage::selectTracksSortedByCrateNameLike(const QString& crateNameLike) const {
FwdSqlQuery query(m_database, QString(
Expand Down
2 changes: 2 additions & 0 deletions src/library/crate/cratestorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ class CrateStorage: public virtual /*implements*/ SqlStorage {
CrateId crateId) const;
CrateTrackSelectResult selectTrackCratesSorted(
TrackId trackId) const;
CrateSummarySelectResult selectCratesWithTrackCount(
const QList<TrackId>& trackIds) const;
CrateTrackSelectResult selectTracksSortedByCrateNameLike(
const QString& crateNameLike) const;

Expand Down
4 changes: 2 additions & 2 deletions src/util/parented_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ inline bool operator== (const parented_ptr<T>& lhs, const U* rhs) {
}

template<typename T, typename U>
inline bool operator== (const parented_ptr<T>& lhs, const parented_ptr<U>& rhs) const {
inline bool operator== (const parented_ptr<T>& lhs, const parented_ptr<U>& rhs) {
return lhs.get() == rhs.get();
}

Expand All @@ -115,7 +115,7 @@ inline bool operator!= (const parented_ptr<T>& lhs, const U* rhs) {
}

template<typename T, typename U>
inline bool operator!= (const parented_ptr<T>& lhs, const parented_ptr<U>& rhs) const {
inline bool operator!= (const parented_ptr<T>& lhs, const parented_ptr<U>& rhs) {
return !(lhs.get() == rhs.get());
}

Expand Down
31 changes: 13 additions & 18 deletions src/widget/wtracktableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "util/dnd.h"
#include "util/time.h"
#include "util/assert.h"
#include "util/parented_ptr.h"

WTrackTableView::WTrackTableView(QWidget * parent,
UserSettingsPointer pConfig,
Expand Down Expand Up @@ -830,16 +831,14 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {

if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOCRATE)) {
m_pCrateMenu->clear();
CrateSelectResult allCrates(m_pTrackCollection->crates().selectCrates());

const QList<TrackId> trackIds = getSelectedTrackIds();

QHash<CrateId, int> currentCrates(m_pTrackCollection->crates().\
countTracksInCrates(trackIds));
Crate crate;
CrateSummarySelectResult allCrates(m_pTrackCollection->crates().selectCratesWithTrackCount(trackIds));

CrateSummary crate;
while (allCrates.populateNext(&crate)) {
auto pAction = std::make_unique<QWidgetAction>(m_pCrateMenu);
auto pCheckBox = std::make_unique<QCheckBox>(m_pCrateMenu);
auto pAction = make_parented<QWidgetAction>(m_pCrateMenu);
auto pCheckBox = make_parented<QCheckBox>(m_pCrateMenu);

pCheckBox->setText(crate.getName());
pCheckBox->setProperty("crateId",
Expand All @@ -848,15 +847,13 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
pAction->setEnabled(!crate.isLocked());
pAction->setDefaultWidget(pCheckBox.get());


auto i = currentCrates.find(crate.getId());
if(i != currentCrates.end() && i.key() == crate.getId()) {
if(i.value() != trackIds.size()) {
pCheckBox->setTristate(true);
pCheckBox->setCheckState(Qt::PartiallyChecked);
} else {
pCheckBox->setChecked(true);
}
if(crate.getTrackCount() == 0) {
pCheckBox->setChecked(false);
} else if(crate.getTrackCount() == (uint)trackIds.length()) {
pCheckBox->setChecked(true);
} else {
pCheckBox->setTristate(true);
pCheckBox->setCheckState(Qt::PartiallyChecked);
}

m_crateMapper.setMapping(pAction.get(), pCheckBox.get());
Expand All @@ -867,8 +864,6 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
connect(pCheckBox.get(), SIGNAL(stateChanged(int)),
&m_crateMapper, SLOT(map()));

pAction.release();
pCheckBox.release();
}
m_pCrateMenu->addSeparator();
QAction* newCrateAction = new QAction(tr("Create New Crate"), m_pCrateMenu);
Expand Down

0 comments on commit 97a0684

Please sign in to comment.