Added playlist import (and sync)from m3u files, ref #391
This commit is contained in:
@@ -170,10 +170,12 @@ namespace lms::db
|
||||
query.leftJoin("track t ON d.id = t.directory_id");
|
||||
query.leftJoin("image i ON d.id = i.directory_id");
|
||||
query.leftJoin("track_lyrics l_lrc ON d.id = l_lrc.directory_id");
|
||||
query.leftJoin("playlist_file pl_f ON d.id = pl_f.directory_id");
|
||||
query.where("d_child.id IS NULL");
|
||||
query.where("t.directory_id IS NULL");
|
||||
query.where("i.directory_id IS NULL");
|
||||
query.where("l_lrc.directory_id IS NULL");
|
||||
query.where("pl_f.directory_id IS NULL");
|
||||
|
||||
return utils::execRangeQuery<DirectoryId>(query, range);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace lms::db
|
||||
{
|
||||
namespace
|
||||
{
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 76 };
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 77 };
|
||||
}
|
||||
|
||||
VersionInfo::VersionInfo()
|
||||
@@ -127,7 +127,7 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
void migrateFromV36(Session& session)
|
||||
{
|
||||
// Increased precision for track durations (now in milliseconds instead of secodns)
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
// Support Performer tags (via subtypes)
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track_artist_link ADD subtype TEXT");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), "DROP TABLE track");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track_backup RENAME TO track");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD primary_type INTEGER");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD secondary_types INTEGER");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD artist_display_name TEXT NOT NULL DEFAULT ''");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD artist_display_name TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE cluster ADD track_count INTEGER");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE cluster ADD release_count INTEGER");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
// add bitrate
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD bitrate INTEGER NOT NULL DEFAULT 0");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE scan_settings ADD COLUMN extra_tags_to_scan TEXT");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -299,14 +299,14 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "release_release_type_release_type" on "release_release_type" ("release_type_id"))");
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "release_release_type_release" on "release_release_type" ("release_id"))");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
void migrateFromV48(Session& session)
|
||||
{
|
||||
// Regression for the extra tags not being parsed
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD year INTEGER");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD original_year INTEGER");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -423,7 +423,7 @@ SELECT
|
||||
// Add sort name for releases
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD sort_name TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ SELECT
|
||||
// Add release group mbid
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD group_mbid TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD file_size BIGINT NOT NULL DEFAULT(0)");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD relative_file_path TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD channel_count INTEGER NOT NULL DEFAULT(0)");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD sample_rate INTEGER NOT NULL DEFAULT(0)");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ SELECT
|
||||
constraint "fk_image_artist" foreign key ("artist_id") references "artist" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -625,7 +625,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "DROP TABLE image");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE image_backup RENAME TO image");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "DROP TABLE directory");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE directory_backup RENAME TO directory");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -669,7 +669,7 @@ SELECT
|
||||
// Add a new column comment
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD comment TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -732,7 +732,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "release_label_label" on "release_label" ("label_id"))");
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "release_label_release" on "release_label" ("release_id"))");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -740,7 +740,7 @@ SELECT
|
||||
{
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD is_compilation BOOLEAN NOT NULL DEFAULT(false)");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ SELECT
|
||||
for (const auto& indexName : indexeNames)
|
||||
utils::executeCommand(*session.getDboSession(), "DROP INDEX " + indexName);
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -868,7 +868,7 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "DROP TABLE artist");
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE artist_backup RENAME TO artist");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -903,7 +903,7 @@ SELECT
|
||||
constraint "fk_track_lyrics_directory" foreign key ("directory_id") references "directory" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -937,7 +937,7 @@ SELECT
|
||||
// Add catalog number
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE release ADD barcode TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
@@ -968,6 +968,67 @@ SELECT
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE user ADD bcrypt_round_count INTEGER NOT NULL DEFAULT(7)");
|
||||
}
|
||||
|
||||
void migrateFromV76(Session& session)
|
||||
{
|
||||
// Rename public -> visibility (false is Private(0) and true is Public(1))
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE tracklist RENAME COLUMN public TO visibility");
|
||||
|
||||
// Supported extensions are now runtime
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE scan_settings DROP COLUMN audio_file_extensions");
|
||||
|
||||
// Add PlayListFile
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "playlist_file" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"absolute_file_path" text not null,
|
||||
"file_stem" text not null,
|
||||
"file_size" bigint not null,
|
||||
"file_last_write" text,
|
||||
"name" text not null,
|
||||
"entries" text not null,
|
||||
"media_library_id" bigint,
|
||||
"directory_id" bigint,
|
||||
constraint "fk_playlist_file_media_library" foreign key ("media_library_id") references "media_library" ("id") on delete set null deferrable initially deferred,
|
||||
constraint "fk_playlist_file_directory" foreign key ("directory_id") references "directory" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
// Add a link into tracklist to ease cleanup
|
||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "tracklist_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"name" text not null,
|
||||
"type" integer not null,
|
||||
"visibility" integer not null,
|
||||
"creation_date_time" text,
|
||||
"last_modified_date_time" text,
|
||||
"user_id" bigint,
|
||||
"playlist_file_id" bigint,
|
||||
constraint "fk_tracklist_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_tracklist_playlist_file" foreign key ("playlist_file_id") references "playlist_file" ("id") on delete cascade deferrable initially deferred))");
|
||||
|
||||
utils::executeCommand(*session.getDboSession(), R"(INSERT INTO tracklist_backup
|
||||
SELECT
|
||||
id,
|
||||
version,
|
||||
name,
|
||||
type,
|
||||
visibility,
|
||||
creation_date_time,
|
||||
last_modified_date_time,
|
||||
user_id,
|
||||
NULL AS playlist_file_id
|
||||
FROM tracklist)");
|
||||
|
||||
utils::executeCommand(*session.getDboSession(), R"(DROP TABLE tracklist)");
|
||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE tracklist_backup RENAME TO tracklist)");
|
||||
|
||||
// Add a file name in tracks
|
||||
utils::executeCommand(*session.getDboSession(), "ALTER TABLE track ADD COLUMN file_name TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scan rescan everything
|
||||
utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
|
||||
}
|
||||
|
||||
bool doDbMigration(Session& session)
|
||||
{
|
||||
constexpr std::string_view outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
|
||||
@@ -1020,6 +1081,7 @@ SELECT
|
||||
{ 73, migrateFromV73 },
|
||||
{ 74, migrateFromV74 },
|
||||
{ 75, migrateFromV75 },
|
||||
{ 76, migrateFromV76 },
|
||||
};
|
||||
|
||||
bool migrationPerformed{};
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS 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.
|
||||
*
|
||||
* LMS 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 LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "database/PlayListFile.hpp"
|
||||
|
||||
#include <Wt/Dbo/WtSqlTraits.h>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Directory.hpp"
|
||||
#include "database/MediaLibrary.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
#include "database/User.hpp"
|
||||
|
||||
#include "IdTypeTraits.hpp"
|
||||
#include "PathTraits.hpp"
|
||||
#include "StringViewTraits.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
namespace lms::db
|
||||
{
|
||||
PlayListFile::PlayListFile(const std::filesystem::path& file)
|
||||
{
|
||||
setAbsoluteFilePath(file);
|
||||
}
|
||||
|
||||
PlayListFile::pointer PlayListFile::create(Session& session, const std::filesystem::path& file)
|
||||
{
|
||||
return session.getDboSession()->add(std::unique_ptr<PlayListFile>{ new PlayListFile{ file } });
|
||||
}
|
||||
|
||||
std::size_t PlayListFile::getCount(Session& session)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->query<int>("SELECT COUNT(*) FROM playlist_file"));
|
||||
}
|
||||
|
||||
PlayListFile::pointer PlayListFile::find(Session& session, const std::filesystem::path& p)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->query<Wt::Dbo::ptr<PlayListFile>>("SELECT pl_f from playlist_file pl_f").where("pl_f.absolute_file_path = ?").bind(p.string()));
|
||||
}
|
||||
|
||||
void PlayListFile::find(Session& session, PlayListFileId& lastRetrievedId, std::size_t count, const std::function<void(const pointer&)>& func)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<PlayListFile>>("SELECT pl_f from playlist_file pl_f").orderBy("pl_f.id").where("pl_f.id > ?").bind(lastRetrievedId).limit(static_cast<int>(count)) };
|
||||
|
||||
utils::forEachQueryResult(query, [&](const PlayListFile::pointer& playList) {
|
||||
func(playList);
|
||||
lastRetrievedId = playList->getId();
|
||||
});
|
||||
}
|
||||
|
||||
PlayListFile::pointer PlayListFile::find(Session& session, PlayListFileId id)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->query<Wt::Dbo::ptr<PlayListFile>>("SELECT pl_f from playlist_file pl_f").where("pl_f.id = ?").bind(id));
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> PlayListFile::getFiles() const
|
||||
{
|
||||
std::vector<std::filesystem::path> files;
|
||||
{
|
||||
Wt::Json::Object root;
|
||||
Wt::Json::parse(_entries, root);
|
||||
|
||||
assert(root.type("files") == Wt::Json::Type::Array);
|
||||
const Wt::Json::Array& filesArray = root.get("files");
|
||||
for (const Wt::Json::Value& file : filesArray)
|
||||
files.push_back(static_cast<std::string>(file.toString()));
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
TrackList::pointer PlayListFile::getTrackList() const
|
||||
{
|
||||
return _trackList.lock();
|
||||
}
|
||||
|
||||
Directory::pointer PlayListFile::getDirectory() const
|
||||
{
|
||||
return _directory;
|
||||
}
|
||||
|
||||
void PlayListFile::setAbsoluteFilePath(const std::filesystem::path& filePath)
|
||||
{
|
||||
assert(filePath.is_absolute());
|
||||
_absoluteFilePath = filePath;
|
||||
_fileStem = filePath.stem();
|
||||
}
|
||||
|
||||
void PlayListFile::setDirectory(ObjectPtr<Directory> directory)
|
||||
{
|
||||
_directory = getDboPtr(directory);
|
||||
}
|
||||
|
||||
void PlayListFile::setTrackList(ObjectPtr<TrackList> trackList)
|
||||
{
|
||||
_trackList = getDboPtr(trackList);
|
||||
}
|
||||
|
||||
void PlayListFile::setName(std::string_view name)
|
||||
{
|
||||
_name = std::string{ name, 0, _maxNameLength };
|
||||
if (name.size() > _maxNameLength)
|
||||
LMS_LOG(DB, WARNING, "PlaylistFile name too long, truncated to '" << _name << "'");
|
||||
}
|
||||
|
||||
void PlayListFile::setFiles(std::span<const std::filesystem::path> files)
|
||||
{
|
||||
Wt::Json::Object root;
|
||||
|
||||
Wt::Json::Array fileArray;
|
||||
for (const auto& file : files)
|
||||
fileArray.push_back(Wt::Json::Value{ file.string() });
|
||||
|
||||
root["files"] = std::move(fileArray);
|
||||
_entries = Wt::Json::serialize(root);
|
||||
}
|
||||
} // namespace lms::db
|
||||
@@ -46,17 +46,6 @@ namespace lms::db
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->find<ScanSettings>());
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> ScanSettings::getAudioFileExtensions() const
|
||||
{
|
||||
const auto extensions{ core::stringUtils::splitString(_audioFileExtensions, ' ') };
|
||||
|
||||
std::vector<std::filesystem::path> res(std::cbegin(extensions), std::cend(extensions));
|
||||
std::sort(std::begin(res), std::end(res));
|
||||
res.erase(std::unique(std::begin(res), std::end(res)), std::end(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::string_view> ScanSettings::getExtraTagsToScan() const
|
||||
{
|
||||
std::vector<std::string_view> tags{ core::stringUtils::splitString(_extraTagsToScan, ';') };
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "database/Image.hpp"
|
||||
#include "database/Listen.hpp"
|
||||
#include "database/MediaLibrary.hpp"
|
||||
#include "database/PlayListFile.hpp"
|
||||
#include "database/PlayQueue.hpp"
|
||||
#include "database/RatedArtist.hpp"
|
||||
#include "database/RatedRelease.hpp"
|
||||
@@ -105,6 +106,7 @@ namespace lms::db
|
||||
_session.mapClass<Label>("label");
|
||||
_session.mapClass<Listen>("listen");
|
||||
_session.mapClass<MediaLibrary>("media_library");
|
||||
_session.mapClass<PlayListFile>("playlist_file");
|
||||
_session.mapClass<PlayQueue>("playqueue");
|
||||
_session.mapClass<RatedArtist>("rated_artist");
|
||||
_session.mapClass<RatedRelease>("rated_release");
|
||||
@@ -181,98 +183,107 @@ namespace lms::db
|
||||
LMS_SCOPED_TRACE_OVERVIEW("Database", "IndexCreation");
|
||||
LMS_LOG(DB, INFO, "Creating indexes... This may take a while...");
|
||||
|
||||
auto transaction{ createWriteTransaction() };
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_id_idx ON artist(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_image_idx ON artist(image_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_name_idx ON artist(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_sort_name_nocase_idx ON artist(sort_name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_mbid_idx ON artist(mbid)");
|
||||
{
|
||||
auto transaction{ createWriteTransaction() };
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_id_idx ON artist(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_image_idx ON artist(image_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_name_idx ON artist(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_sort_name_nocase_idx ON artist(sort_name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_mbid_idx ON artist(mbid)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_user_domain_idx ON auth_token(user_id, domain)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_domain_expiry_idx ON auth_token(domain, expiry)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_domain_value_idx ON auth_token(domain, value)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_user_domain_idx ON auth_token(user_id, domain)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_domain_expiry_idx ON auth_token(domain, expiry)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS auth_token_domain_value_idx ON auth_token(domain, value)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS cluster_cluster_type_idx ON cluster(cluster_type_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS cluster_type_name_idx ON cluster_type(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS cluster_cluster_type_idx ON cluster(cluster_type_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS cluster_type_name_idx ON cluster_type(name)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_id_idx ON directory(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_parent_directory_idx ON directory(parent_directory_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_path_idx ON directory(absolute_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_media_library_idx ON directory(media_library_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_id_idx ON directory(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_parent_directory_idx ON directory(parent_directory_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_path_idx ON directory(absolute_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS directory_media_library_idx ON directory(media_library_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_id_idx ON image(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_path_idx ON image(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_stem_idx ON image(stem COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_id_idx ON image(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_path_idx ON image(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS image_stem_idx ON image(stem COLLATE NOCASE)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS label_name_idx ON label(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS label_name_idx ON label(name)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_backend_idx ON listen(backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_id_idx ON listen(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_backend_idx ON listen(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_backend_date_time_idx ON listen(user_id, backend, date_time DESC)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_track_user_backend_idx ON listen(track_id,user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_track_backend_date_time_idx ON listen(user_id,track_id,backend,date_time)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_backend_idx ON listen(backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_id_idx ON listen(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_backend_idx ON listen(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_backend_date_time_idx ON listen(user_id, backend, date_time DESC)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_track_user_backend_idx ON listen(track_id,user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS listen_user_track_backend_date_time_idx ON listen(user_id,track_id,backend,date_time)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS media_library_id_idx ON media_library(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS media_library_id_idx ON media_library(id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_artist_user_artist_idx ON rated_artist(user_id,artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_release_user_release_idx ON rated_release(user_id,release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_track_user_track_idx ON rated_track(user_id,track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS playlist_file_id_idx ON playlist_file(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS playlist_file_absolute_file_path_idx ON playlist_file(absolute_file_path)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_id_idx ON release(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_image_idx ON release(image_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_mbid_idx ON release(mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_idx ON release(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_nocase_idx ON release(name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_artist_user_artist_idx ON rated_artist(user_id,artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_release_user_release_idx ON rated_release(user_id,release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS rated_track_user_track_idx ON rated_track(user_id,track_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_id_idx ON track(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_absolute_path_idx ON track(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_date_idx ON track(date)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_directory_release_idx ON track(directory_id, release_id);");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_directory_file_stem_idx ON track(directory_id, file_stem);");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_file_last_write_idx ON track(file_last_write)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_media_library_idx ON track(media_library_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_media_library_release_idx ON track(media_library_id, release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_mbid_idx ON track(mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_name_idx ON track(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_name_nocase_idx ON track(name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_original_date_idx ON track(original_date)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_original_year_idx ON track(original_year)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_recording_mbid_idx ON track(recording_mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_idx ON track(release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_file_last_write_idx ON track(release_id, file_last_write)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_year_idx ON track(release_id, year)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_year_idx ON track(year)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_id_idx ON release(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_image_idx ON release(image_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_mbid_idx ON release(mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_idx ON release(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_nocase_idx ON release(name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_name_idx ON tracklist(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_user_idx ON tracklist(user_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_id_idx ON track(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_absolute_path_idx ON track(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_date_idx ON track(date)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_directory_release_idx ON track(directory_id, release_id);");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_directory_file_stem_idx ON track(directory_id, file_stem);");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_file_last_write_idx ON track(file_last_write)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_media_library_idx ON track(media_library_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_media_library_release_idx ON track(media_library_id, release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_mbid_idx ON track(mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_name_idx ON track(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_name_nocase_idx ON track(name COLLATE NOCASE)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_original_date_idx ON track(original_date)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_original_year_idx ON track(original_year)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_recording_mbid_idx ON track(recording_mbid)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_idx ON track(release_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_file_last_write_idx ON track(release_id, file_last_write)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_year_idx ON track(release_id, year)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_year_idx ON track(year)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_idx ON track_artist_link(artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_track_idx ON track_artist_link(artist_id, track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_type_idx ON track_artist_link(artist_id,type)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_track_artist_idx ON track_artist_link(track_id, artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_track_type_idx ON track_artist_link(track_id,type)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_type_track_artist_idx ON track_artist_link(type, track_id, artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_name_idx ON tracklist(name)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_user_type_idx ON tracklist(user_id, type)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_last_modified_date_time_idx ON tracklist(last_modified_date_time)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_features_track_idx ON track_features(track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_entry_idx ON tracklist_entry(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_entry_tracklist_track_idx ON tracklist_entry(tracklist_id, track_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_id_idx ON track_lyrics(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_absolute_file_path_idx ON track_lyrics(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_track_idx ON track_lyrics(track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_idx ON track_artist_link(artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_track_idx ON track_artist_link(artist_id, track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_artist_type_idx ON track_artist_link(artist_id,type)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_track_artist_idx ON track_artist_link(track_id, artist_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_track_type_idx ON track_artist_link(track_id,type)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_artist_link_type_track_artist_idx ON track_artist_link(type, track_id, artist_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_bookmark_user_idx ON track_bookmark(user_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_bookmark_user_track_idx ON track_bookmark(user_id,track_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_features_track_idx ON track_features(track_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_artist_user_backend_idx ON starred_artist(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_artist_artist_user_backend_idx ON starred_artist(artist_id,user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_id_idx ON track_lyrics(id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_absolute_file_path_idx ON track_lyrics(absolute_file_path)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_lyrics_track_idx ON track_lyrics(track_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_release_user_backend_idx ON starred_release(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_release_release_user_backend_idx ON starred_release(release_id,user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_bookmark_user_idx ON track_bookmark(user_id)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_bookmark_user_track_idx ON track_bookmark(user_id,track_id)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_track_user_backend_idx ON starred_track(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_track_track_user_backend_idx ON starred_track(track_id,user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_artist_user_backend_idx ON starred_artist(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_artist_artist_user_backend_idx ON starred_artist(artist_id,user_id,backend)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_release_user_backend_idx ON starred_release(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_release_release_user_backend_idx ON starred_release(release_id,user_id,backend)");
|
||||
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_track_user_backend_idx ON starred_track(user_id,backend)");
|
||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS starred_track_track_user_backend_idx ON starred_track(track_id,user_id,backend)");
|
||||
}
|
||||
|
||||
LMS_LOG(DB, INFO, "Indexes created!");
|
||||
}
|
||||
|
||||
@@ -54,8 +54,11 @@ namespace lms::db
|
||||
for (std::string_view keyword : params.keywords)
|
||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
||||
|
||||
if (!params.stem.empty())
|
||||
query.where("t.file_stem = ?").bind(params.stem);
|
||||
if (!params.fileStem.empty())
|
||||
query.where("t.file_stem = ?").bind(params.fileStem);
|
||||
|
||||
if (!params.fileName.empty())
|
||||
query.where("t.file_name = ?").bind(params.fileName);
|
||||
|
||||
if (!params.name.empty())
|
||||
query.where("t.name = ?").bind(params.name);
|
||||
@@ -375,8 +378,10 @@ namespace lms::db
|
||||
void Track::setAbsoluteFilePath(const std::filesystem::path& filePath)
|
||||
{
|
||||
assert(filePath.is_absolute());
|
||||
|
||||
_absoluteFilePath = filePath;
|
||||
_fileStem = filePath.stem();
|
||||
_fileName = filePath.filename();
|
||||
}
|
||||
|
||||
void Track::setRelativeFilePath(const std::filesystem::path& filePath)
|
||||
@@ -385,6 +390,7 @@ namespace lms::db
|
||||
|
||||
assert(_absoluteFilePath.filename() == filePath.filename()); // must be compatible with previous setAbsoluteFilePath call
|
||||
_fileStem = filePath.stem(); // lazy migration (_fileStem added later, could be set only with setAbsoluteFilePath)
|
||||
_fileName = filePath.filename(); // lazy migration (_fileName added later, could be set only with setAbsoluteFilePath)
|
||||
_relativeFilePath = filePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,8 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "core/ILogger.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/PlayListFile.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "database/User.hpp"
|
||||
@@ -40,10 +38,13 @@ namespace lms::db
|
||||
template<typename ResultType>
|
||||
Wt::Dbo::Query<ResultType> createQuery(Session& session, std::string_view itemToSelect, const TrackList::FindParameters& params)
|
||||
{
|
||||
auto query{ session.getDboSession()->query<ResultType>("SELECT DISTINCT " + std::string{ itemToSelect } + " FROM tracklist t_l") };
|
||||
auto query{ session.getDboSession()->query<ResultType>("SELECT " + std::string{ itemToSelect } + " FROM tracklist t_l") };
|
||||
|
||||
if (!params.clusters.empty() || params.mediaLibrary.isValid())
|
||||
{
|
||||
query.join("tracklist_entry t_l_e ON t_l_e.tracklist_id = t_l.id");
|
||||
query.groupBy("t_l.id");
|
||||
}
|
||||
|
||||
if (params.mediaLibrary.isValid())
|
||||
query.join("track t ON t.id = t_l_e.track_id");
|
||||
@@ -57,6 +58,9 @@ namespace lms::db
|
||||
if (params.type)
|
||||
query.where("t_l.type = ?").bind(*params.type);
|
||||
|
||||
if (params.visibility)
|
||||
query.where("t_l.visibility = ?").bind(*params.visibility);
|
||||
|
||||
if (!params.clusters.empty())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@@ -108,20 +112,17 @@ namespace lms::db
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TrackList::TrackList(std::string_view name, TrackListType type, bool isPublic, ObjectPtr<User> user)
|
||||
TrackList::TrackList(std::string_view name, TrackListType type)
|
||||
: _name{ name }
|
||||
, _type{ type }
|
||||
, _isPublic{ isPublic }
|
||||
, _creationDateTime{ utils::normalizeDateTime(Wt::WDateTime::currentDateTime()) }
|
||||
, _lastModifiedDateTime{ utils::normalizeDateTime(Wt::WDateTime::currentDateTime()) }
|
||||
, _user{ getDboPtr(user) }
|
||||
{
|
||||
assert(user);
|
||||
}
|
||||
|
||||
TrackList::pointer TrackList::create(Session& session, std::string_view name, TrackListType type, bool isPublic, ObjectPtr<User> user)
|
||||
TrackList::pointer TrackList::create(Session& session, std::string_view name, TrackListType type)
|
||||
{
|
||||
return session.getDboSession()->add(std::unique_ptr<TrackList>{ new TrackList{ name, type, isPublic, user } });
|
||||
return session.getDboSession()->add(std::unique_ptr<TrackList>{ new TrackList{ name, type } });
|
||||
}
|
||||
|
||||
std::size_t TrackList::getCount(Session& session)
|
||||
@@ -311,20 +312,24 @@ namespace lms::db
|
||||
return session.getDboSession()->add(std::unique_ptr<TrackListEntry>{ new TrackListEntry{ track, tracklist, dateTime } });
|
||||
}
|
||||
|
||||
void TrackListEntry::onPostCreated()
|
||||
{
|
||||
_tracklist.modify()->setLastModifiedDateTime(utils::normalizeDateTime(Wt::WDateTime::currentDateTime()));
|
||||
}
|
||||
|
||||
void TrackListEntry::onPreRemove()
|
||||
{
|
||||
_tracklist.modify()->setLastModifiedDateTime(utils::normalizeDateTime(Wt::WDateTime::currentDateTime()));
|
||||
}
|
||||
|
||||
TrackListEntry::pointer TrackListEntry::getById(Session& session, TrackListEntryId id)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
return utils::fetchQuerySingleResult(session.getDboSession()->find<TrackListEntry>().where("id = ?").bind(id));
|
||||
}
|
||||
|
||||
void TrackListEntry::find(Session& session, const FindParameters& params, const std::function<void(const TrackListEntry::pointer&)>& func)
|
||||
{
|
||||
session.checkReadTransaction();
|
||||
|
||||
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<TrackListEntry>>("SELECT t_l_e FROM tracklist_entry t_l_e") };
|
||||
|
||||
if (params.trackList.isValid())
|
||||
query.where("t_l_e.tracklist_id = ?").bind(params.trackList);
|
||||
query.orderBy("t_l_e.id");
|
||||
|
||||
utils::forEachQueryRangeResult(query, params.range, func);
|
||||
}
|
||||
|
||||
} // namespace lms::db
|
||||
|
||||
Reference in New Issue
Block a user