Optimize `Song::InitFromQuery`
Use `QSqlQuery::value(int)` or `QSqlRecord::value(int)` instead of `QSqlQuery::value(QString)`. Make `SqlRow` use `QSqlRecord` directly instead iterating over all columns.
This commit is contained in:
parent
7b88be2635
commit
df070ac0cf
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -401,7 +401,7 @@ SongList CollectionBackend::FindSongsInDirectory(const int id) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
|
@ -424,7 +424,7 @@ SongList CollectionBackend::SongsWithMissingFingerprint(const int id) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (fingerprint IS NULL OR fingerprint = '')").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (fingerprint IS NULL OR fingerprint = '')").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
|
@ -447,7 +447,7 @@ SongList CollectionBackend::SongsWithMissingLoudnessCharacteristics(const int id
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (ebur128_integrated_loudness_lufs IS NULL OR ebur128_loudness_range_lu IS NULL)").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE directory_id = :directory_id AND unavailable = 0 AND (ebur128_integrated_loudness_lufs IS NULL OR ebur128_loudness_range_lu IS NULL)").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
q.BindValue(QStringLiteral(":directory_id"), id);
|
q.BindValue(QStringLiteral(":directory_id"), id);
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
|
@ -548,7 +548,7 @@ SongList CollectionBackend::GetAllSongs() {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
return SongList();
|
return SongList();
|
||||||
|
@ -1164,7 +1164,7 @@ SongList CollectionBackend::GetSongsById(const QStringList &ids, QSqlDatabase &d
|
||||||
QString in = ids.join(QStringLiteral(","));
|
QString in = ids.join(QStringLiteral(","));
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE ROWID IN (%3)").arg(Song::kColumnSpec, songs_table_, in));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE ROWID IN (%3)").arg(Song::kRowIdColumnSpec, songs_table_, in));
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
return SongList();
|
return SongList();
|
||||||
|
@ -1186,7 +1186,7 @@ Song CollectionBackend::GetSongByUrl(const QUrl &url, const qint64 beginning) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND beginning = :beginning AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND beginning = :beginning AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
|
|
||||||
q.BindValue(QStringLiteral(":url1"), url);
|
q.BindValue(QStringLiteral(":url1"), url);
|
||||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||||
|
@ -1216,7 +1216,7 @@ Song CollectionBackend::GetSongByUrlAndTrack(const QUrl &url, const int track) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND track = :track AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND track = :track AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
|
|
||||||
q.BindValue(QStringLiteral(":url1"), url);
|
q.BindValue(QStringLiteral(":url1"), url);
|
||||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||||
|
@ -1246,7 +1246,7 @@ SongList CollectionBackend::GetSongsByUrl(const QUrl &url, const bool unavailabl
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = :unavailable").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = :unavailable").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
|
|
||||||
q.BindValue(QStringLiteral(":url1"), url);
|
q.BindValue(QStringLiteral(":url1"), url);
|
||||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||||
|
@ -1306,7 +1306,7 @@ SongList CollectionBackend::GetSongsBySongId(const QStringList &song_ids, QSqlDa
|
||||||
QString in = song_ids2.join(QLatin1Char(','));
|
QString in = song_ids2.join(QLatin1Char(','));
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE SONG_ID IN (%3)").arg(Song::kColumnSpec, songs_table_, in));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE SONG_ID IN (%3)").arg(Song::kRowIdColumnSpec, songs_table_, in));
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
return SongList();
|
return SongList();
|
||||||
|
@ -1329,7 +1329,7 @@ SongList CollectionBackend::GetSongsByFingerprint(const QString &fingerprint) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE fingerprint = :fingerprint").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE fingerprint = :fingerprint").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
q.BindValue(QStringLiteral(":fingerprint"), fingerprint);
|
q.BindValue(QStringLiteral(":fingerprint"), fingerprint);
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
db_->ReportErrors(q);
|
db_->ReportErrors(q);
|
||||||
|
@ -1452,7 +1452,7 @@ bool CollectionBackend::UpdateCompilations(const QSqlDatabase &db, SongList &del
|
||||||
|
|
||||||
{ // Get song, so we can tell the model its updated
|
{ // Get song, so we can tell the model its updated
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = 0").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE (url = :url1 OR url = :url2 OR url = :url3 OR url = :url4) AND unavailable = 0").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
q.BindValue(QStringLiteral(":url1"), url);
|
q.BindValue(QStringLiteral(":url1"), url);
|
||||||
q.BindValue(QStringLiteral(":url2"), url.toString());
|
q.BindValue(QStringLiteral(":url2"), url.toString());
|
||||||
q.BindValue(QStringLiteral(":url3"), url.toString(QUrl::FullyEncoded));
|
q.BindValue(QStringLiteral(":url3"), url.toString(QUrl::FullyEncoded));
|
||||||
|
@ -1622,7 +1622,7 @@ void CollectionBackend::UpdateEmbeddedAlbumArt(const QString &effective_albumart
|
||||||
|
|
||||||
// Get the songs before they're updated
|
// Get the songs before they're updated
|
||||||
CollectionQuery query(db, songs_table_, fts_table_);
|
CollectionQuery query(db, songs_table_, fts_table_);
|
||||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||||
query.AddWhere(QStringLiteral("album"), album);
|
query.AddWhere(QStringLiteral("album"), album);
|
||||||
|
|
||||||
|
@ -1684,7 +1684,7 @@ void CollectionBackend::UpdateManualAlbumArt(const QString &effective_albumartis
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
CollectionQuery query(db, songs_table_, fts_table_);
|
CollectionQuery query(db, songs_table_, fts_table_);
|
||||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||||
query.AddWhere(QStringLiteral("album"), album);
|
query.AddWhere(QStringLiteral("album"), album);
|
||||||
|
|
||||||
|
@ -1742,7 +1742,7 @@ void CollectionBackend::UnsetAlbumArt(const QString &effective_albumartist, cons
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
CollectionQuery query(db, songs_table_, fts_table_);
|
CollectionQuery query(db, songs_table_, fts_table_);
|
||||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||||
query.AddWhere(QStringLiteral("album"), album);
|
query.AddWhere(QStringLiteral("album"), album);
|
||||||
|
|
||||||
|
@ -1799,7 +1799,7 @@ void CollectionBackend::ClearAlbumArt(const QString &effective_albumartist, cons
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
CollectionQuery query(db, songs_table_, fts_table_);
|
CollectionQuery query(db, songs_table_, fts_table_);
|
||||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
query.AddWhere(QStringLiteral("effective_albumartist"), effective_albumartist);
|
||||||
query.AddWhere(QStringLiteral("album"), album);
|
query.AddWhere(QStringLiteral("album"), album);
|
||||||
|
|
||||||
|
@ -1854,7 +1854,7 @@ void CollectionBackend::ForceCompilation(const QString &album, const QList<QStri
|
||||||
for (const QString &artist : artists) {
|
for (const QString &artist : artists) {
|
||||||
// Get the songs before they're updated
|
// Get the songs before they're updated
|
||||||
CollectionQuery query(db, songs_table_, fts_table_);
|
CollectionQuery query(db, songs_table_, fts_table_);
|
||||||
query.SetColumnSpec(QStringLiteral("ROWID, ") + Song::kColumnSpec);
|
query.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
query.AddWhere(QStringLiteral("album"), album);
|
query.AddWhere(QStringLiteral("album"), album);
|
||||||
if (!artist.isEmpty()) query.AddWhere(QStringLiteral("artist"), artist);
|
if (!artist.isEmpty()) query.AddWhere(QStringLiteral("artist"), artist);
|
||||||
|
|
||||||
|
@ -2073,10 +2073,10 @@ SongList CollectionBackend::GetSongsBy(const QString &artist, const QString &alb
|
||||||
SongList songs;
|
SongList songs;
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
if (album.isEmpty()) {
|
if (album.isEmpty()) {
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
q.prepare(QStringLiteral("SELECT ROWID, %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND album = :album COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kColumnSpec, songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 WHERE artist = :artist COLLATE NOCASE AND album = :album COLLATE NOCASE AND title = :title COLLATE NOCASE").arg(Song::kRowIdColumnSpec, songs_table_));
|
||||||
}
|
}
|
||||||
q.BindValue(QStringLiteral(":artist"), artist);
|
q.BindValue(QStringLiteral(":artist"), artist);
|
||||||
if (!album.isEmpty()) q.BindValue(QStringLiteral(":album"), album);
|
if (!album.isEmpty()) q.BindValue(QStringLiteral(":album"), album);
|
||||||
|
@ -2220,7 +2220,7 @@ void CollectionBackend::ExpireSongs(const int directory_id, const int expire_una
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
q.prepare(QStringLiteral("SELECT %1.ROWID, ").arg(songs_table_) + Song::JoinSpec(songs_table_) + QStringLiteral(" FROM %1 LEFT JOIN playlist_items ON %1.ROWID = playlist_items.collection_id WHERE %1.directory_id = :directory_id AND %1.unavailable = 1 AND %1.lastseen > 0 AND %1.lastseen < :time AND playlist_items.collection_id IS NULL").arg(songs_table_));
|
q.prepare(QStringLiteral("SELECT %1 FROM %2 LEFT JOIN playlist_items ON %2.ROWID = playlist_items.collection_id WHERE %2.directory_id = :directory_id AND %2.unavailable = 1 AND %2.lastseen > 0 AND %2.lastseen < :time AND playlist_items.collection_id IS NULL").arg(Song::JoinSpec(songs_table_), songs_table_));
|
||||||
q.BindValue(QStringLiteral(":directory_id"), directory_id);
|
q.BindValue(QStringLiteral(":directory_id"), directory_id);
|
||||||
q.BindValue(QStringLiteral(":time"), QDateTime::currentDateTime().toSecsSinceEpoch() - (expire_unavailable_songs_days * 86400));
|
q.BindValue(QStringLiteral(":time"), QDateTime::currentDateTime().toSecsSinceEpoch() - (expire_unavailable_songs_days * 86400));
|
||||||
if (!q.Exec()) {
|
if (!q.Exec()) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
#include <QSqlQuery>
|
|
||||||
|
|
||||||
|
#include "core/sqlquery.h"
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
|
|
||||||
#include "collectionquery.h"
|
#include "collectionquery.h"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
#include "utilities/searchparserutils.h"
|
#include "utilities/searchparserutils.h"
|
||||||
|
|
||||||
CollectionQuery::CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options)
|
CollectionQuery::CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options)
|
||||||
: QSqlQuery(db),
|
: SqlQuery(db),
|
||||||
songs_table_(songs_table),
|
songs_table_(songs_table),
|
||||||
fts_table_(fts_table),
|
fts_table_(fts_table),
|
||||||
include_unavailable_(false),
|
include_unavailable_(false),
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,11 +29,12 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
#include <QSqlQuery>
|
|
||||||
|
#include "core/sqlquery.h"
|
||||||
|
|
||||||
#include "collectionfilteroptions.h"
|
#include "collectionfilteroptions.h"
|
||||||
|
|
||||||
class CollectionQuery : public QSqlQuery {
|
class CollectionQuery : public SqlQuery {
|
||||||
public:
|
public:
|
||||||
explicit CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options = CollectionFilterOptions());
|
explicit CollectionQuery(const QSqlDatabase &db, const QString &songs_table, const QString &fts_table, const CollectionFilterOptions &filter_options = CollectionFilterOptions());
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ class CollectionQuery : public QSqlQuery {
|
||||||
QVariant value(const int column) const { return Value(column); }
|
QVariant value(const int column) const { return Value(column); }
|
||||||
|
|
||||||
bool Exec();
|
bool Exec();
|
||||||
bool exec() { return QSqlQuery::exec(); }
|
bool exec() { return SqlQuery::exec(); }
|
||||||
|
|
||||||
bool Next();
|
bool Next();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QSqlRecord>
|
||||||
|
|
||||||
#include "core/iconloader.h"
|
#include "core/iconloader.h"
|
||||||
#include "engine/enginemetadata.h"
|
#include "engine/enginemetadata.h"
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#include "utilities/timeutils.h"
|
#include "utilities/timeutils.h"
|
||||||
#include "utilities/coverutils.h"
|
#include "utilities/coverutils.h"
|
||||||
#include "utilities/timeconstants.h"
|
#include "utilities/timeconstants.h"
|
||||||
|
#include "utilities/sqlhelper.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
#include "sqlquery.h"
|
#include "sqlquery.h"
|
||||||
#include "sqlrow.h"
|
#include "sqlrow.h"
|
||||||
|
@ -140,7 +142,10 @@ const QStringList Song::kColumns = QStringList() << QStringLiteral("title")
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
const QStringList Song::kRowIdColumns = QStringList() << QStringLiteral("ROWID") << kColumns;
|
||||||
|
|
||||||
const QString Song::kColumnSpec = Song::kColumns.join(QStringLiteral(", "));
|
const QString Song::kColumnSpec = Song::kColumns.join(QStringLiteral(", "));
|
||||||
|
const QString Song::kRowIdColumnSpec = Song::kRowIdColumns.join(QStringLiteral(", "));
|
||||||
const QString Song::kBindSpec = Utilities::Prepend(QStringLiteral(":"), Song::kColumns).join(QStringLiteral(", "));
|
const QString Song::kBindSpec = Utilities::Prepend(QStringLiteral(":"), Song::kColumns).join(QStringLiteral(", "));
|
||||||
const QString Song::kUpdateSpec = Utilities::Updateify(Song::kColumns).join(QStringLiteral(", "));
|
const QString Song::kUpdateSpec = Utilities::Updateify(Song::kColumns).join(QStringLiteral(", "));
|
||||||
|
|
||||||
|
@ -668,7 +673,7 @@ QString Song::sortable(const QString &v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Song::JoinSpec(const QString &table) {
|
QString Song::JoinSpec(const QString &table) {
|
||||||
return Utilities::Prepend(table + QLatin1Char('.'), kColumns).join(QStringLiteral(", "));
|
return Utilities::Prepend(table + QLatin1Char('.'), kRowIdColumns).join(QStringLiteral(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Song::PrettyTitle() const {
|
QString Song::PrettyTitle() const {
|
||||||
|
@ -1364,78 +1369,80 @@ void Song::ToProtobuf(spb::tagreader::SongMetadata *pb) const {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Song::InitFromQuery(const SqlRow &q, const bool reliable_metadata) {
|
void Song::InitFromQuery(const QSqlRecord &r, const bool reliable_metadata, const int col) {
|
||||||
|
|
||||||
d->id_ = q.value(QStringLiteral("rowid")).isNull() ? -1 : q.value(QStringLiteral("rowid")).toInt();
|
Q_ASSERT(kRowIdColumns.count() + col <= r.count());
|
||||||
|
|
||||||
set_title(q.ValueToString(QStringLiteral("title")));
|
d->id_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("ROWID")) + col);
|
||||||
set_album(q.ValueToString(QStringLiteral("album")));
|
|
||||||
set_artist(q.ValueToString(QStringLiteral("artist")));
|
set_title(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("title")) + col));
|
||||||
set_albumartist(q.ValueToString(QStringLiteral("albumartist")));
|
set_album(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("album")) + col));
|
||||||
d->track_ = q.ValueToInt(QStringLiteral("track"));
|
set_artist(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("artist")) + col));
|
||||||
d->disc_ = q.ValueToInt(QStringLiteral("disc"));
|
set_albumartist(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("albumartist")) + col));
|
||||||
d->year_ = q.ValueToInt(QStringLiteral("year"));
|
d->track_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("track")) + col);
|
||||||
d->originalyear_ = q.ValueToInt(QStringLiteral("originalyear"));
|
d->disc_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("disc")) + col);
|
||||||
d->genre_ = q.ValueToString(QStringLiteral("genre"));
|
d->year_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("year")) + col);
|
||||||
d->compilation_ = q.value(QStringLiteral("compilation")).toBool();
|
d->originalyear_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("originalyear")) + col);
|
||||||
d->composer_ = q.ValueToString(QStringLiteral("composer"));
|
d->genre_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("genre")) + col);
|
||||||
d->performer_ = q.ValueToString(QStringLiteral("performer"));
|
d->compilation_ = r.value(kRowIdColumns.indexOf(QStringLiteral("compilation")) + col).toBool();
|
||||||
d->grouping_ = q.ValueToString(QStringLiteral("grouping"));
|
d->composer_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("composer")) + col);
|
||||||
d->comment_ = q.ValueToString(QStringLiteral("comment"));
|
d->performer_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("performer")) + col);
|
||||||
d->lyrics_ = q.ValueToString(QStringLiteral("lyrics"));
|
d->grouping_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("grouping")) + col);
|
||||||
d->artist_id_ = q.ValueToString(QStringLiteral("artist_id"));
|
d->comment_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("comment")) + col);
|
||||||
d->album_id_ = q.ValueToString(QStringLiteral("album_id"));
|
d->lyrics_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("lyrics")) + col);
|
||||||
d->song_id_ = q.ValueToString(QStringLiteral("song_id"));
|
d->artist_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("artist_id")) + col);
|
||||||
d->beginning_ = q.value(QStringLiteral("beginning")).isNull() ? 0 : q.value(QStringLiteral("beginning")).toLongLong();
|
d->album_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("album_id")) + col);
|
||||||
set_length_nanosec(q.ValueToLongLong(QStringLiteral("length")));
|
d->song_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("song_id")) + col);
|
||||||
d->bitrate_ = q.ValueToInt(QStringLiteral("bitrate"));
|
d->beginning_ = r.value(kRowIdColumns.indexOf(QStringLiteral("beginning")) + col).isNull() ? 0 : r.value(kRowIdColumns.indexOf(QStringLiteral("beginning")) + col).toLongLong();
|
||||||
d->samplerate_ = q.ValueToInt(QStringLiteral("samplerate"));
|
set_length_nanosec(SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("length"))) + col);
|
||||||
d->bitdepth_ = q.ValueToInt(QStringLiteral("bitdepth"));
|
d->bitrate_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("bitrate")) + col);
|
||||||
if (!q.value(QStringLiteral("ebur128_integrated_loudness_lufs")).isNull()) {
|
d->samplerate_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("samplerate")) + col);
|
||||||
d->ebur128_integrated_loudness_lufs_ = q.value(QStringLiteral("ebur128_integrated_loudness_lufs")).toDouble();
|
d->bitdepth_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("bitdepth")) + col);
|
||||||
|
if (!r.value(kRowIdColumns.indexOf(QStringLiteral("ebur128_integrated_loudness_lufs")) + col).isNull()) {
|
||||||
|
d->ebur128_integrated_loudness_lufs_ = r.value(kRowIdColumns.indexOf(QStringLiteral("ebur128_integrated_loudness_lufs")) + col).toDouble();
|
||||||
}
|
}
|
||||||
if (!q.value(QStringLiteral("ebur128_loudness_range_lu")).isNull()) {
|
if (!r.value(kRowIdColumns.indexOf(QStringLiteral("ebur128_loudness_range_lu")) + col).isNull()) {
|
||||||
d->ebur128_loudness_range_lu_ = q.value(QStringLiteral("ebur128_loudness_range_lu")).toDouble();
|
d->ebur128_loudness_range_lu_ = r.value(kRowIdColumns.indexOf(QStringLiteral("ebur128_loudness_range_lu")) + col).toDouble();
|
||||||
}
|
}
|
||||||
d->source_ = static_cast<Source>(q.value(QStringLiteral("source")).isNull() ? 0 : q.value(QStringLiteral("source")).toInt());
|
d->source_ = static_cast<Source>(r.value(kRowIdColumns.indexOf(QStringLiteral("source")) + col).isNull() ? 0 : r.value(kRowIdColumns.indexOf(QStringLiteral("source")) + col).toInt());
|
||||||
d->directory_id_ = q.ValueToInt(QStringLiteral("directory_id"));
|
d->directory_id_ = SqlHelper::ValueToInt(r, kRowIdColumns.indexOf(QStringLiteral("directory_id")) + col);
|
||||||
set_url(QUrl::fromEncoded(q.ValueToString(QStringLiteral("url")).toUtf8()));
|
set_url(QUrl::fromEncoded(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("url")) + col).toUtf8()));
|
||||||
d->basefilename_ = QFileInfo(d->url_.toLocalFile()).fileName();
|
d->basefilename_ = QFileInfo(d->url_.toLocalFile()).fileName();
|
||||||
d->filetype_ = FileType(q.value(QStringLiteral("filetype")).isNull() ? 0 : q.value(QStringLiteral("filetype")).toInt());
|
d->filetype_ = FileType(r.value(kRowIdColumns.indexOf(QStringLiteral("filetype")) + col).isNull() ? 0 : r.value(kRowIdColumns.indexOf(QStringLiteral("filetype")) + col).toInt());
|
||||||
d->filesize_ = q.ValueToLongLong(QStringLiteral("filesize"));
|
d->filesize_ = SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("filesize")) + col);
|
||||||
d->mtime_ = q.ValueToLongLong(QStringLiteral("mtime"));
|
d->mtime_ = SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("mtime")) + col);
|
||||||
d->ctime_ = q.ValueToLongLong(QStringLiteral("ctime"));
|
d->ctime_ = SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("ctime")) + col);
|
||||||
d->unavailable_ = q.value(QStringLiteral("unavailable")).toBool();
|
d->unavailable_ = r.value(kRowIdColumns.indexOf(QStringLiteral("unavailable")) + col).toBool();
|
||||||
d->fingerprint_ = q.ValueToString(QStringLiteral("fingerprint"));
|
d->fingerprint_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("fingerprint")) + col);
|
||||||
d->playcount_ = q.ValueToUInt(QStringLiteral("playcount"));
|
d->playcount_ = SqlHelper::ValueToUInt(r, kRowIdColumns.indexOf(QStringLiteral("playcount")) + col);
|
||||||
d->skipcount_ = q.ValueToUInt(QStringLiteral("skipcount"));
|
d->skipcount_ = SqlHelper::ValueToUInt(r, kRowIdColumns.indexOf(QStringLiteral("skipcount")) + col);
|
||||||
d->lastplayed_ = q.ValueToLongLong(QStringLiteral("lastplayed"));
|
d->lastplayed_ = SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("lastplayed")) + col);
|
||||||
d->lastseen_ = q.ValueToLongLong(QStringLiteral("lastseen"));
|
d->lastseen_ = SqlHelper::ValueToLongLong(r, kRowIdColumns.indexOf(QStringLiteral("lastseen")) + col);
|
||||||
d->compilation_detected_ = q.ValueToBool(QStringLiteral("compilation_detected"));
|
d->compilation_detected_ = SqlHelper::ValueToBool(r, kRowIdColumns.indexOf(QStringLiteral("compilation_detected")) + col);
|
||||||
d->compilation_on_ = q.ValueToBool(QStringLiteral("compilation_on"));
|
d->compilation_on_ = SqlHelper::ValueToBool(r, kRowIdColumns.indexOf(QStringLiteral("compilation_on")) + col);
|
||||||
d->compilation_off_ = q.ValueToBool(QStringLiteral("compilation_off"));
|
d->compilation_off_ = SqlHelper::ValueToBool(r, kRowIdColumns.indexOf(QStringLiteral("compilation_off")) + col);
|
||||||
|
|
||||||
d->art_embedded_ = q.ValueToBool(QStringLiteral("art_embedded"));
|
d->art_embedded_ = SqlHelper::ValueToBool(r, kRowIdColumns.indexOf(QStringLiteral("art_embedded")) + col);
|
||||||
d->art_automatic_ = QUrl::fromEncoded(q.ValueToString(QStringLiteral("art_automatic")).toUtf8());
|
d->art_automatic_ = QUrl::fromEncoded(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("art_automatic")) + col).toUtf8());
|
||||||
d->art_manual_ = QUrl::fromEncoded(q.ValueToString(QStringLiteral("art_manual")).toUtf8());
|
d->art_manual_ = QUrl::fromEncoded(SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("art_manual")) + col).toUtf8());
|
||||||
d->art_unset_ = q.ValueToBool(QStringLiteral("art_unset"));
|
d->art_unset_ = SqlHelper::ValueToBool(r, kRowIdColumns.indexOf(QStringLiteral("art_unset")) + col);
|
||||||
|
|
||||||
d->cue_path_ = q.ValueToString(QStringLiteral("cue_path"));
|
d->cue_path_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("cue_path")) + col);
|
||||||
d->rating_ = q.ValueToFloat(QStringLiteral("rating"));
|
d->rating_ = SqlHelper::ValueToFloat(r, kRowIdColumns.indexOf(QStringLiteral("rating")) + col);
|
||||||
|
|
||||||
d->acoustid_id_ = q.ValueToString(QStringLiteral("acoustid_id"));
|
d->acoustid_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("acoustid_id")) + col);
|
||||||
d->acoustid_fingerprint_ = q.ValueToString(QStringLiteral("acoustid_fingerprint"));
|
d->acoustid_fingerprint_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("acoustid_fingerprint")) + col);
|
||||||
|
|
||||||
d->musicbrainz_album_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_album_artist_id"));
|
d->musicbrainz_album_artist_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_album_artist_id")) + col);
|
||||||
d->musicbrainz_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_artist_id"));
|
d->musicbrainz_artist_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_artist_id")) + col);
|
||||||
d->musicbrainz_original_artist_id_ = q.ValueToString(QStringLiteral("musicbrainz_original_artist_id"));
|
d->musicbrainz_original_artist_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_original_artist_id")) + col);
|
||||||
d->musicbrainz_album_id_ = q.ValueToString(QStringLiteral("musicbrainz_album_id"));
|
d->musicbrainz_album_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_album_id")) + col);
|
||||||
d->musicbrainz_original_album_id_ = q.ValueToString(QStringLiteral("musicbrainz_original_album_id"));
|
d->musicbrainz_original_album_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_original_album_id")) + col);
|
||||||
d->musicbrainz_recording_id_ = q.ValueToString(QStringLiteral("musicbrainz_recording_id"));
|
d->musicbrainz_recording_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_recording_id")) + col);
|
||||||
d->musicbrainz_track_id_ = q.ValueToString(QStringLiteral("musicbrainz_track_id"));
|
d->musicbrainz_track_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_track_id")) + col);
|
||||||
d->musicbrainz_disc_id_ = q.ValueToString(QStringLiteral("musicbrainz_disc_id"));
|
d->musicbrainz_disc_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_disc_id")) + col);
|
||||||
d->musicbrainz_release_group_id_ = q.ValueToString(QStringLiteral("musicbrainz_release_group_id"));
|
d->musicbrainz_release_group_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_release_group_id")) + col);
|
||||||
d->musicbrainz_work_id_ = q.ValueToString(QStringLiteral("musicbrainz_work_id"));
|
d->musicbrainz_work_id_ = SqlHelper::ValueToString(r, kRowIdColumns.indexOf(QStringLiteral("musicbrainz_work_id")) + col);
|
||||||
|
|
||||||
d->valid_ = true;
|
d->valid_ = true;
|
||||||
d->init_from_file_ = reliable_metadata;
|
d->init_from_file_ = reliable_metadata;
|
||||||
|
@ -1444,6 +1451,18 @@ void Song::InitFromQuery(const SqlRow &q, const bool reliable_metadata) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Song::InitFromQuery(const SqlQuery &query, const bool reliable_metadata, const int col) {
|
||||||
|
|
||||||
|
InitFromQuery(query.record(), reliable_metadata, col);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::InitFromQuery(const SqlRow &row, const bool reliable_metadata, const int col) {
|
||||||
|
|
||||||
|
InitFromQuery(row.record(), reliable_metadata, col);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Song::InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo) {
|
void Song::InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo) {
|
||||||
|
|
||||||
set_url(QUrl::fromLocalFile(filename));
|
set_url(QUrl::fromLocalFile(filename));
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* This file was part of Clementine.
|
* This file was part of Clementine.
|
||||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
class SqlQuery;
|
class SqlQuery;
|
||||||
|
class QSqlRecord;
|
||||||
|
|
||||||
class EngineMetadata;
|
class EngineMetadata;
|
||||||
|
|
||||||
|
@ -112,7 +113,9 @@ class Song {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const QStringList kColumns;
|
static const QStringList kColumns;
|
||||||
|
static const QStringList kRowIdColumns;
|
||||||
static const QString kColumnSpec;
|
static const QString kColumnSpec;
|
||||||
|
static const QString kRowIdColumnSpec;
|
||||||
static const QString kBindSpec;
|
static const QString kBindSpec;
|
||||||
static const QString kUpdateSpec;
|
static const QString kUpdateSpec;
|
||||||
|
|
||||||
|
@ -416,7 +419,9 @@ class Song {
|
||||||
void Init(const QString &title, const QString &artist, const QString &album, const qint64 length_nanosec);
|
void Init(const QString &title, const QString &artist, const QString &album, const qint64 length_nanosec);
|
||||||
void Init(const QString &title, const QString &artist, const QString &album, const qint64 beginning, const qint64 end);
|
void Init(const QString &title, const QString &artist, const QString &album, const qint64 beginning, const qint64 end);
|
||||||
void InitFromProtobuf(const spb::tagreader::SongMetadata &pb);
|
void InitFromProtobuf(const spb::tagreader::SongMetadata &pb);
|
||||||
void InitFromQuery(const SqlRow &query, const bool reliable_metadata);
|
void InitFromQuery(const QSqlRecord &r, const bool reliable_metadata, const int col = 0);
|
||||||
|
void InitFromQuery(const SqlQuery &query, const bool reliable_metadata, const int col = 0);
|
||||||
|
void InitFromQuery(const SqlRow &row, const bool reliable_metadata, const int col = 0);
|
||||||
void InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo);
|
void InitFromFilePartial(const QString &filename, const QFileInfo &fileinfo);
|
||||||
void InitArtManual();
|
void InitArtManual();
|
||||||
void InitArtAutomatic();
|
void InitArtAutomatic();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2021-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* Copyright 2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2021-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,12 +29,15 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
|
#include <QSqlRecord>
|
||||||
|
|
||||||
class SqlQuery : public QSqlQuery {
|
class SqlQuery : public QSqlQuery {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SqlQuery(const QSqlDatabase &db) : QSqlQuery(db) {}
|
explicit SqlQuery(const QSqlDatabase &db) : QSqlQuery(db) {}
|
||||||
|
|
||||||
|
int columns() const { return QSqlQuery::record().count(); }
|
||||||
|
|
||||||
void BindValue(const QString &placeholder, const QVariant &value);
|
void BindValue(const QString &placeholder, const QVariant &value);
|
||||||
void BindStringValue(const QString &placeholder, const QString &value);
|
void BindStringValue(const QString &placeholder, const QString &value);
|
||||||
void BindUrlValue(const QString &placeholder, const QUrl &value);
|
void BindUrlValue(const QString &placeholder, const QUrl &value);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,74 +20,22 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QString>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QSqlQuery>
|
|
||||||
#include <QSqlRecord>
|
#include <QSqlRecord>
|
||||||
|
|
||||||
#include "sqlrow.h"
|
#include "sqlrow.h"
|
||||||
|
|
||||||
SqlRow::SqlRow(const QSqlQuery &query) { Init(query); }
|
SqlRow::SqlRow(const SqlQuery &query) { Init(query); }
|
||||||
|
|
||||||
void SqlRow::Init(const QSqlQuery &query) {
|
void SqlRow::Init(const SqlQuery &query) {
|
||||||
|
|
||||||
const QSqlRecord r = query.record();
|
record_ = query.record();
|
||||||
for (int i = 0; i < r.count(); ++i) {
|
|
||||||
columns_by_number_.insert(i, query.value(i));
|
|
||||||
const QString field_name = r.fieldName(i);
|
|
||||||
if (!columns_by_name_.contains(field_name) || columns_by_name_[field_name].isNull()) {
|
|
||||||
columns_by_name_.insert(field_name, query.value(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariant SqlRow::value(const int number) const {
|
const QVariant SqlRow::value(const int n) const {
|
||||||
|
|
||||||
if (columns_by_number_.contains(number)) {
|
Q_ASSERT(n < record_.count());
|
||||||
return columns_by_number_[number];
|
|
||||||
}
|
return record_.value(n);
|
||||||
else {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariant SqlRow::value(const QString &name) const {
|
|
||||||
|
|
||||||
if (columns_by_name_.contains(name)) {
|
|
||||||
return columns_by_name_[name];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SqlRow::ValueToString(const QString &n) const {
|
|
||||||
return value(n).isNull() ? QString() : value(n).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl SqlRow::ValueToUrl(const QString &n) const {
|
|
||||||
return value(n).isNull() ? QUrl() : QUrl(value(n).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
int SqlRow::ValueToInt(const QString &n) const {
|
|
||||||
return value(n).isNull() ? -1 : value(n).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint SqlRow::ValueToUInt(const QString &n) const {
|
|
||||||
return value(n).isNull() || value(n).toInt() < 0 ? 0 : value(n).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 SqlRow::ValueToLongLong(const QString &n) const {
|
|
||||||
return value(n).isNull() ? -1 : value(n).toLongLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
float SqlRow::ValueToFloat(const QString &n) const {
|
|
||||||
return value(n).isNull() ? -1.0F : value(n).toFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SqlRow::ValueToBool(const QString &n) const {
|
|
||||||
return !value(n).isNull() && value(n).toInt() == 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Strawberry Music Player
|
* Strawberry Music Player
|
||||||
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
*
|
*
|
||||||
* Strawberry is free software: you can redistribute it and/or modify
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,33 +24,23 @@
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QUrl>
|
#include <QSqlRecord>
|
||||||
#include <QSqlQuery>
|
|
||||||
|
#include "sqlquery.h"
|
||||||
|
|
||||||
class SqlRow {
|
class SqlRow {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SqlRow(const QSqlQuery &query);
|
explicit SqlRow(const SqlQuery &query);
|
||||||
|
|
||||||
const QVariant value(const int number) const;
|
int columns() const { return record_.count(); }
|
||||||
const QVariant value(const QString &name) const;
|
const QSqlRecord &record() const { return record_; }
|
||||||
|
const QVariant value(const int n) const;
|
||||||
QString ValueToString(const QString &n) const;
|
|
||||||
QUrl ValueToUrl(const QString &n) const;
|
|
||||||
int ValueToInt(const QString &n) const;
|
|
||||||
uint ValueToUInt(const QString &n) const;
|
|
||||||
qint64 ValueToLongLong(const QString &n) const;
|
|
||||||
float ValueToFloat(const QString &n) const;
|
|
||||||
bool ValueToBool(const QString& n) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SqlRow();
|
void Init(const SqlQuery &query);
|
||||||
|
|
||||||
void Init(const QSqlQuery &query);
|
|
||||||
|
|
||||||
QMap<int, QVariant> columns_by_number_;
|
|
||||||
QMap<QString, QVariant> columns_by_name_;
|
|
||||||
|
|
||||||
|
QSqlRecord record_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using SqlRowList = QList<SqlRow>;
|
using SqlRowList = QList<SqlRow>;
|
||||||
|
|
|
@ -877,7 +877,7 @@ SongList AlbumCoverManager::GetSongsInAlbum(const QModelIndex &idx) const {
|
||||||
QSqlDatabase db(collection_backend_->db()->Connect());
|
QSqlDatabase db(collection_backend_->db()->Connect());
|
||||||
|
|
||||||
CollectionQuery q(db, collection_backend_->songs_table(), collection_backend_->fts_table());
|
CollectionQuery q(db, collection_backend_->songs_table(), collection_backend_->fts_table());
|
||||||
q.SetColumnSpec(QStringLiteral("ROWID,") + Song::kColumnSpec);
|
q.SetColumnSpec(Song::kRowIdColumnSpec);
|
||||||
q.AddWhere(QStringLiteral("album"), idx.data(Role_Album).toString());
|
q.AddWhere(QStringLiteral("album"), idx.data(Role_Album).toString());
|
||||||
q.SetOrderBy(QStringLiteral("disc, track, title"));
|
q.SetOrderBy(QStringLiteral("disc, track, title"));
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ InternetPlaylistItem::InternetPlaylistItem(InternetServicePtr service, const Son
|
||||||
|
|
||||||
bool InternetPlaylistItem::InitFromQuery(const SqlRow &query) {
|
bool InternetPlaylistItem::InitFromQuery(const SqlRow &query) {
|
||||||
|
|
||||||
metadata_.InitFromQuery(query, false);
|
metadata_.InitFromQuery(query, false, Song::kRowIdColumns.count() * 3);
|
||||||
InitMetadata();
|
InitMetadata();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,8 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) {
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
QString query = QStringLiteral("SELECT songs.ROWID, ") + Song::JoinSpec(QStringLiteral("songs")) + QStringLiteral(", p.ROWID, ") + Song::JoinSpec(QStringLiteral("p")) + QStringLiteral(", p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist");
|
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p")));
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
// Forward iterations only may be faster
|
// Forward iterations only may be faster
|
||||||
q.setForwardOnly(true);
|
q.setForwardOnly(true);
|
||||||
|
@ -219,7 +220,8 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
QString query = QStringLiteral("SELECT songs.ROWID, ") + Song::JoinSpec(QStringLiteral("songs")) + QStringLiteral(", p.ROWID, ") + Song::JoinSpec(QStringLiteral("p")) + QStringLiteral(", p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist");
|
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p")));
|
||||||
|
|
||||||
SqlQuery q(db);
|
SqlQuery q(db);
|
||||||
// Forward iterations only may be faster
|
// Forward iterations only may be faster
|
||||||
q.setForwardOnly(true);
|
q.setForwardOnly(true);
|
||||||
|
@ -249,7 +251,7 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
||||||
PlaylistItemPtr PlaylistBackend::NewPlaylistItemFromQuery(const SqlRow &row, SharedPtr<NewSongFromQueryState> state) {
|
PlaylistItemPtr PlaylistBackend::NewPlaylistItemFromQuery(const SqlRow &row, SharedPtr<NewSongFromQueryState> state) {
|
||||||
|
|
||||||
// The song tables get joined first, plus one each for the song ROWIDs
|
// The song tables get joined first, plus one each for the song ROWIDs
|
||||||
const int playlist_row = static_cast<int>(Song::kColumns.count() + 1) * kSongTableJoins;
|
const int playlist_row = static_cast<int>(Song::kRowIdColumns.count()) * kSongTableJoins;
|
||||||
|
|
||||||
PlaylistItemPtr item(PlaylistItem::NewFromSource(static_cast<Song::Source>(row.value(playlist_row).toInt())));
|
PlaylistItemPtr item(PlaylistItem::NewFromSource(static_cast<Song::Source>(row.value(playlist_row).toInt())));
|
||||||
if (item) {
|
if (item) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ SongPlaylistItem::SongPlaylistItem(const Song::Source source) : PlaylistItem(sou
|
||||||
SongPlaylistItem::SongPlaylistItem(const Song &song) : PlaylistItem(song.source()), song_(song) {}
|
SongPlaylistItem::SongPlaylistItem(const Song &song) : PlaylistItem(song.source()), song_(song) {}
|
||||||
|
|
||||||
bool SongPlaylistItem::InitFromQuery(const SqlRow &query) {
|
bool SongPlaylistItem::InitFromQuery(const SqlRow &query) {
|
||||||
song_.InitFromQuery(query, false);
|
song_.InitFromQuery(query, false, Song::kRowIdColumns.count() * 3);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ void SmartPlaylistSearch::Reset() {
|
||||||
|
|
||||||
QString SmartPlaylistSearch::ToSql(const QString &songs_table) const {
|
QString SmartPlaylistSearch::ToSql(const QString &songs_table) const {
|
||||||
|
|
||||||
QString sql = QStringLiteral("SELECT ROWID,") + Song::kColumnSpec + QStringLiteral(" FROM ") + songs_table;
|
QString sql = QStringLiteral("SELECT %1 FROM %2").arg(Song::kRowIdColumnSpec, songs_table);
|
||||||
|
|
||||||
// Add search terms
|
// Add search terms
|
||||||
QStringList where_clauses;
|
QStringList where_clauses;
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLHELPER_H
|
||||||
|
#define SQLHELPER_H
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
class SqlHelper {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
static QString ValueToString(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static QUrl ValueToUrl(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static int ValueToInt(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static uint ValueToUInt(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static qint64 ValueToLongLong(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static float ValueToFloat(const T &q, const int n);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static bool ValueToBool(const T &q, const int n);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QString SqlHelper::ValueToString(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() ? QString() : q.value(n).toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
QUrl SqlHelper::ValueToUrl(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() ? QUrl() : QUrl(q.value(n).toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int SqlHelper::ValueToInt(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() ? -1 : q.value(n).toInt();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
uint SqlHelper::ValueToUInt(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() || q.value(n).toInt() < 0 ? 0 : q.value(n).toInt();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
qint64 SqlHelper::ValueToLongLong(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() ? -1 : q.value(n).toLongLong();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
float SqlHelper::ValueToFloat(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return q.value(n).isNull() ? -1.0F : q.value(n).toFloat();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool SqlHelper::ValueToBool(const T &q, const int n) {
|
||||||
|
|
||||||
|
Q_ASSERT(n < q.count());
|
||||||
|
|
||||||
|
return !q.value(n).isNull() && q.value(n).toInt() == 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SQLHELPER_H
|
Loading…
Reference in New Issue