Isolated migration steps within transactions
This commit is contained in:
@@ -90,10 +90,14 @@ namespace lms::db::Migration
|
|||||||
{
|
{
|
||||||
void dropIndexes(Session& session)
|
void dropIndexes(Session& session)
|
||||||
{
|
{
|
||||||
|
LMS_LOG(DB, INFO, "Droping all indexes...");
|
||||||
|
|
||||||
// Make sure we remove all the previoulsy created index, the createIndexesIfNeeded will recreate them all
|
// Make sure we remove all the previoulsy created index, the createIndexesIfNeeded will recreate them all
|
||||||
std::vector<std::string> indexeNames{ utils::fetchQueryResults(session.getDboSession()->query<std::string>(R"(SELECT name FROM sqlite_master WHERE type = 'index' AND name LIKE '%_idx')")) };
|
std::vector<std::string> indexeNames{ utils::fetchQueryResults(session.getDboSession()->query<std::string>(R"(SELECT name FROM sqlite_master WHERE type = 'index' AND name LIKE '%_idx')")) };
|
||||||
for (const auto& indexName : indexeNames)
|
for (const auto& indexName : indexeNames)
|
||||||
utils::executeCommand(*session.getDboSession(), "DROP INDEX " + indexName);
|
utils::executeCommand(*session.getDboSession(), "DROP INDEX " + indexName);
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Indexes dropped!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void migrateFromV33(Session& session)
|
void migrateFromV33(Session& session)
|
||||||
@@ -1738,46 +1742,34 @@ FROM track)");
|
|||||||
|
|
||||||
void migrateFromV106(Session& session)
|
void migrateFromV106(Session& session)
|
||||||
{
|
{
|
||||||
dropIndexes(session);
|
auto& dboSession{ *session.getDboSession() };
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS artist_name_mbid_idx");
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS artist_mbid_idx");
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS release_mbid_idx");
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS release_group_mbid_idx");
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS track_mbid_idx");
|
||||||
|
utils::executeCommand(dboSession, "DROP INDEX IF EXISTS track_recording_mbid_idx");
|
||||||
|
|
||||||
// Convert the 5 MBID TEXT columns to BLOB (16 raw bytes)
|
auto convertMBIDColumn = [&](std::string_view table, std::string_view column) {
|
||||||
// unhex() returns NULL for non-hex input, so malformed values become NULL
|
LMS_LOG(DB, INFO, "Migrating '" << column << "' from table '" << table << "'...");
|
||||||
|
|
||||||
// artist.mbid
|
utils::executeCommand(dboSession, "ALTER TABLE " + std::string{ table } + " ADD COLUMN " + std::string{ column } + "_new BLOB");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE artist ADD COLUMN mbid_new BLOB)");
|
utils::executeCommand(dboSession, "UPDATE " + std::string{ table } + " SET " + std::string{ column } + "_new = CASE WHEN " + std::string{ column } + " != '' THEN unhex(replace(" + std::string{ column } + ", '-', '')) ELSE NULL END");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(UPDATE artist SET mbid_new = CASE WHEN mbid != '' THEN unhex(replace(mbid, '-', '')) ELSE NULL END)");
|
utils::executeCommand(dboSession, "ALTER TABLE " + std::string{ table } + " DROP COLUMN " + std::string{ column });
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE artist DROP COLUMN mbid)");
|
utils::executeCommand(dboSession, "ALTER TABLE " + std::string{ table } + " RENAME COLUMN " + std::string{ column } + "_new TO " + std::string{ column });
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE artist RENAME COLUMN mbid_new TO mbid)");
|
};
|
||||||
|
|
||||||
// release.mbid
|
convertMBIDColumn("artist", "mbid");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release ADD COLUMN mbid_new BLOB)");
|
convertMBIDColumn("release", "mbid");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(UPDATE release SET mbid_new = CASE WHEN mbid != '' THEN unhex(replace(mbid, '-', '')) ELSE NULL END)");
|
convertMBIDColumn("release", "group_mbid");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release DROP COLUMN mbid)");
|
convertMBIDColumn("track", "mbid");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release RENAME COLUMN mbid_new TO mbid)");
|
convertMBIDColumn("track", "recording_mbid");
|
||||||
|
|
||||||
// release.group_mbid
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release ADD COLUMN group_mbid_new BLOB)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(UPDATE release SET group_mbid_new = CASE WHEN group_mbid != '' THEN unhex(replace(group_mbid, '-', '')) ELSE NULL END)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release DROP COLUMN group_mbid)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE release RENAME COLUMN group_mbid_new TO group_mbid)");
|
|
||||||
|
|
||||||
// track.mbid
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track ADD COLUMN mbid_new BLOB)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(UPDATE track SET mbid_new = CASE WHEN mbid != '' THEN unhex(replace(mbid, '-', '')) ELSE NULL END)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track DROP COLUMN mbid)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track RENAME COLUMN mbid_new TO mbid)");
|
|
||||||
|
|
||||||
// track.recording_mbid
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track ADD COLUMN recording_mbid_new BLOB)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(UPDATE track SET recording_mbid_new = CASE WHEN recording_mbid != '' THEN unhex(replace(recording_mbid, '-', '')) ELSE NULL END)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track DROP COLUMN recording_mbid)");
|
|
||||||
utils::executeCommand(*session.getDboSession(), R"(ALTER TABLE track RENAME COLUMN recording_mbid_new TO recording_mbid)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void migrateFromV107(Session& session)
|
void migrateFromV107(Session& session)
|
||||||
{
|
{
|
||||||
// Extract Genre, Mood, Language and Grouping from Cluster (keep it for user tags)
|
// Extract Genre, Mood, Language and Grouping from Cluster (keep it for user tags)
|
||||||
|
LMS_LOG(DB, INFO, "Migrating genre...");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "genre" (
|
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "genre" (
|
||||||
"id" integer primary key autoincrement,
|
"id" integer primary key autoincrement,
|
||||||
"version" integer not null,
|
"version" integer not null,
|
||||||
@@ -1808,6 +1800,7 @@ WHERE ct.name = 'GENRE')");
|
|||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_genre_genre" ON "track_genre" ("genre_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_genre_genre" ON "track_genre" ("genre_id"))");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_genre_track" ON "track_genre" ("track_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_genre_track" ON "track_genre" ("track_id"))");
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Migrating mood...");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "mood" (
|
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "mood" (
|
||||||
"id" integer primary key autoincrement,
|
"id" integer primary key autoincrement,
|
||||||
"version" integer not null,
|
"version" integer not null,
|
||||||
@@ -1835,6 +1828,7 @@ WHERE ct.name = 'MOOD')");
|
|||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_mood_mood" ON "track_mood" ("mood_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_mood_mood" ON "track_mood" ("mood_id"))");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_mood_track" ON "track_mood" ("track_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_mood_track" ON "track_mood" ("track_id"))");
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Migrating language...");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "language" (
|
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "language" (
|
||||||
"id" integer primary key autoincrement,
|
"id" integer primary key autoincrement,
|
||||||
"version" integer not null,
|
"version" integer not null,
|
||||||
@@ -1862,6 +1856,7 @@ WHERE ct.name = 'LANGUAGE')");
|
|||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_language_language" ON "track_language" ("language_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_language_language" ON "track_language" ("language_id"))");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_language_track" ON "track_language" ("track_id"))");
|
utils::executeCommand(*session.getDboSession(), R"(CREATE INDEX "track_language_track" ON "track_language" ("track_id"))");
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Migrating grouping...");
|
||||||
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "grouping" (
|
utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "grouping" (
|
||||||
"id" integer primary key autoincrement,
|
"id" integer primary key autoincrement,
|
||||||
"version" integer not null,
|
"version" integer not null,
|
||||||
@@ -1982,12 +1977,11 @@ WHERE ct.name = 'GROUPING')");
|
|||||||
{ 107, migrateFromV107 },
|
{ 107, migrateFromV107 },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool migrationPerformed{};
|
LMS_SCOPED_TRACE_OVERVIEW("Database", "Migration");
|
||||||
{
|
|
||||||
LMS_SCOPED_TRACE_OVERVIEW("Database", "Migration");
|
|
||||||
auto transaction{ session.createWriteTransaction() };
|
|
||||||
|
|
||||||
Version version;
|
Version version{};
|
||||||
|
{
|
||||||
|
auto transaction{ session.createWriteTransaction() };
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
version = VersionInfo::getOrCreate(session)->getVersion();
|
version = VersionInfo::getOrCreate(session)->getVersion();
|
||||||
@@ -2004,23 +1998,27 @@ WHERE ct.name = 'GROUPING')");
|
|||||||
|
|
||||||
if (version < migrationFunctions.begin()->first)
|
if (version < migrationFunctions.begin()->first)
|
||||||
throw core::LmsException{ outdatedMsg };
|
throw core::LmsException{ outdatedMsg };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool migrationPerformed{};
|
||||||
|
while (version < LMS_DATABASE_VERSION)
|
||||||
|
{
|
||||||
|
LMS_SCOPED_TRACE_DETAILED("Database", "MigrationStep");
|
||||||
|
LMS_LOG(DB, INFO, "Migrating database from version " << version << " to " << version + 1 << "...");
|
||||||
|
|
||||||
|
auto itMigrationFunc{ migrationFunctions.find(version) };
|
||||||
|
if (itMigrationFunc == std::cend(migrationFunctions))
|
||||||
|
throw core::LmsException{ "No code found to upgrade database!" };
|
||||||
|
|
||||||
while (version < LMS_DATABASE_VERSION)
|
|
||||||
{
|
{
|
||||||
LMS_SCOPED_TRACE_DETAILED("Database", "MigrationStep");
|
auto transaction{ session.createWriteTransaction() };
|
||||||
LMS_LOG(DB, INFO, "Migrating database from version " << version << " to " << version + 1 << "...");
|
|
||||||
|
|
||||||
auto itMigrationFunc{ migrationFunctions.find(version) };
|
|
||||||
if (itMigrationFunc == std::cend(migrationFunctions))
|
|
||||||
throw core::LmsException{ "No code found to upgrade database!" };
|
|
||||||
|
|
||||||
itMigrationFunc->second(session);
|
itMigrationFunc->second(session);
|
||||||
|
VersionInfo::get(session).modify()->setVersion(version + 1);
|
||||||
VersionInfo::get(session).modify()->setVersion(++version);
|
|
||||||
|
|
||||||
LMS_LOG(DB, INFO, "Migration complete to version " << version);
|
|
||||||
migrationPerformed = true;
|
|
||||||
}
|
}
|
||||||
|
++version;
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Migration complete to version " << version);
|
||||||
|
migrationPerformed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return migrationPerformed;
|
return migrationPerformed;
|
||||||
|
|||||||
+144
-139
@@ -194,146 +194,151 @@ namespace lms::db
|
|||||||
LMS_SCOPED_TRACE_OVERVIEW("Database", "IndexCreation");
|
LMS_SCOPED_TRACE_OVERVIEW("Database", "IndexCreation");
|
||||||
LMS_LOG(DB, INFO, "Creating indexes... This may take a while...");
|
LMS_LOG(DB, INFO, "Creating indexes... This may take a while...");
|
||||||
|
|
||||||
|
constexpr std::string_view indexSqls[]{
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_id_idx ON artist(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_name_mbid_idx ON artist(name, mbid)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_sort_name_nocase_idx ON artist(sort_name COLLATE NOCASE)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_mbid_idx ON artist(mbid)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_info_path_idx ON artist_info(absolute_file_path)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_info_directory_id_idx ON artist_info(directory_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_info_artist_id_idx ON artist_info(artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artist_info_mbid_matched_artist_idx ON artist_info(mbid_matched, artist_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS artwork_id_idx ON artwork(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artwork_image_idx ON artwork(image_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS artwork_track_embedded_image_idx ON artwork(track_embedded_image_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS auth_token_user_domain_idx ON auth_token(user_id, domain)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS auth_token_domain_expiry_idx ON auth_token(domain, expiry)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS auth_token_domain_value_idx ON auth_token(domain, value)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS cluster_id_idx ON cluster(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS cluster_cluster_type_idx ON cluster(cluster_type_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS cluster_type_name_idx ON cluster_type(name)",
|
||||||
|
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS genre_name_idx ON genre(name)",
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS grouping_name_idx ON grouping(name)",
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS language_name_idx ON language(name)",
|
||||||
|
"CREATE UNIQUE INDEX IF NOT EXISTS mood_name_idx ON mood(name)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS country_id_idx ON country(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS country_name_idx ON country(name COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS directory_id_idx ON directory(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS directory_parent_directory_idx ON directory(parent_directory_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS directory_path_idx ON directory(absolute_path)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS directory_media_library_idx ON directory(media_library_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS directory_name_idx ON directory(name COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_id_idx ON track_embedded_image(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_hash_idx ON track_embedded_image(hash)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_link_id_idx ON track_embedded_image_link(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_id_idx ON track_embedded_image_link(track_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_embedded_image_id_track_id_idx ON track_embedded_image_link(track_embedded_image_id, track_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_track_embedded_image_id_idx ON track_embedded_image_link(track_id, track_embedded_image_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS image_directory_stem_idx ON image(directory_id, stem COLLATE NOCASE)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS image_id_idx ON image(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS image_path_idx ON image(absolute_file_path)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS image_stem_idx ON image(stem COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS label_id_idx ON label(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS label_name_idx ON label(name COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_backend_idx ON listen(backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_id_idx ON listen(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_user_backend_idx ON listen(user_id,backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_user_backend_date_time_idx ON listen(user_id, backend, date_time DESC)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_track_user_backend_idx ON listen(track_id,user_id,backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS listen_user_track_backend_date_time_idx ON listen(user_id,track_id,backend,date_time)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS media_library_id_idx ON media_library(id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS medium_release_position_idx ON medium(release_id, position)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS playlist_file_id_idx ON playlist_file(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS playlist_file_directory_idx ON playlist_file(directory_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS playlist_file_absolute_file_path_idx ON playlist_file(absolute_file_path)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS rated_artist_user_artist_idx ON rated_artist(user_id,artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS rated_release_user_release_idx ON rated_release(user_id,release_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS rated_track_user_track_idx ON rated_track(user_id,track_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_id_idx ON release(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_group_mbid_idx ON release(group_mbid)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_mbid_idx ON release(mbid)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_name_idx ON release(name)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_name_nocase_idx ON release(name COLLATE NOCASE)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_sort_name_idx ON release(sort_name)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_sort_name_nocase_idx ON release(sort_name COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_artist_link_id_idx ON release_artist_link(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_artist_link_artist_idx ON release_artist_link(artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_artist_link_release_idx ON release_artist_link(release_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_type_id_idx ON release_type(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name COLLATE NOCASE)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_id_idx ON track(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_absolute_path_idx ON track(absolute_file_path)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_date_idx ON track(date)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_directory_release_idx ON track(directory_id, release_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_file_added_idx ON track(file_added)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_file_last_write_idx ON track(file_last_write)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_media_library_idx ON track(media_library_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_media_library_release_idx ON track(media_library_id, release_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_medium_idx ON track(medium_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_mbid_idx ON track(mbid)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_name_file_size_idx ON track(name, file_size)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_name_nocase_idx ON track(name COLLATE NOCASE)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_original_date_idx ON track(original_date)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_recording_mbid_idx ON track(recording_mbid)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_release_date_idx ON track(release_id, date)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_release_file_last_write_idx ON track(release_id, file_last_write)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_release_file_added_idx ON track(release_id, file_added)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_id_idx ON tracklist(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_name_idx ON tracklist(name)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_user_type_idx ON tracklist(user_id, type)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_last_modified_date_time_idx ON tracklist(last_modified_date_time)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_entry_idx ON tracklist_entry(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS tracklist_entry_tracklist_track_idx ON tracklist_entry(tracklist_id, track_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_id_idx ON track_artist_link(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_artist_idx ON track_artist_link(artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_artist_mbid_matched_artist_idx ON track_artist_link(artist_mbid_matched, artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_artist_track_idx ON track_artist_link(artist_id, track_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_artist_type_track_idx ON track_artist_link(artist_id, type, track_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_track_artist_idx ON track_artist_link(track_id, artist_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_artist_link_track_type_idx ON track_artist_link(track_id, type)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_musicnn_embeddings_track_idx ON track_musicnn_embeddings(track_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_lyrics_id_idx ON track_lyrics(id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_lyrics_absolute_file_path_idx ON track_lyrics(absolute_file_path)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_lyrics_directory_idx ON track_lyrics(directory_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_lyrics_track_idx ON track_lyrics(track_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_bookmark_user_idx ON track_bookmark(user_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS track_bookmark_user_track_idx ON track_bookmark(user_id,track_id)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_artist_user_backend_idx ON starred_artist(user_id,backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_artist_artist_user_backend_idx ON starred_artist(artist_id,user_id,backend)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_release_user_backend_idx ON starred_release(user_id,backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_release_release_user_backend_idx ON starred_release(release_id,user_id,backend)",
|
||||||
|
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_track_user_backend_idx ON starred_track(user_id,backend)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS starred_track_track_user_backend_idx ON starred_track(track_id,user_id,backend)",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (std::string_view sql : indexSqls)
|
||||||
{
|
{
|
||||||
auto transaction{ createWriteTransaction() };
|
auto transaction{ createWriteTransaction() };
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_id_idx ON artist(id)");
|
utils::executeCommand(_session, std::string{ sql });
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_name_mbid_idx ON artist(name, mbid)");
|
|
||||||
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 artist_info_path_idx ON artist_info(absolute_file_path)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_info_directory_id_idx ON artist_info(directory_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_info_artist_id_idx ON artist_info(artist_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artist_info_mbid_matched_artist_idx ON artist_info(mbid_matched, artist_id)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artwork_id_idx ON artwork(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artwork_image_idx ON artwork(image_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS artwork_track_embedded_image_idx ON artwork(track_embedded_image_id)");
|
|
||||||
|
|
||||||
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_id_idx ON cluster(id)");
|
|
||||||
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 UNIQUE INDEX IF NOT EXISTS genre_name_idx ON genre(name)");
|
|
||||||
utils::executeCommand(_session, "CREATE UNIQUE INDEX IF NOT EXISTS grouping_name_idx ON grouping(name)");
|
|
||||||
utils::executeCommand(_session, "CREATE UNIQUE INDEX IF NOT EXISTS language_name_idx ON language(name)");
|
|
||||||
utils::executeCommand(_session, "CREATE UNIQUE INDEX IF NOT EXISTS mood_name_idx ON mood(name)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS country_id_idx ON country(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS country_name_idx ON country(name COLLATE NOCASE)");
|
|
||||||
|
|
||||||
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_name_idx ON directory(name COLLATE NOCASE)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_id_idx ON track_embedded_image(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_hash_idx ON track_embedded_image(hash)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_id_idx ON track_embedded_image_link(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_id_idx ON track_embedded_image_link(track_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_embedded_image_id_track_id_idx ON track_embedded_image_link(track_embedded_image_id, track_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_embedded_image_link_track_track_embedded_image_id_idx ON track_embedded_image_link(track_id, track_embedded_image_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 label_id_idx ON label(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS label_name_idx ON label(name COLLATE NOCASE)");
|
|
||||||
|
|
||||||
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 medium_release_position_idx ON medium(release_id, position)");
|
|
||||||
|
|
||||||
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_directory_idx ON playlist_file(directory_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 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 release_id_idx ON release(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_group_mbid_idx ON release(group_mbid)");
|
|
||||||
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_sort_name_idx ON release(sort_name)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_sort_name_nocase_idx ON release(sort_name COLLATE NOCASE)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_artist_link_id_idx ON release_artist_link(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_artist_link_artist_idx ON release_artist_link(artist_id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_artist_link_release_idx ON release_artist_link(release_id)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_id_idx ON release_type(id)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name COLLATE NOCASE)");
|
|
||||||
|
|
||||||
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_file_added_idx ON track(file_added)");
|
|
||||||
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_medium_idx ON track(medium_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_file_size_idx ON track(name, file_size)");
|
|
||||||
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_recording_mbid_idx ON track(recording_mbid)");
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_release_date_idx ON track(release_id, date)");
|
|
||||||
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_file_added_idx ON track(release_id, file_added)");
|
|
||||||
|
|
||||||
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS tracklist_id_idx ON tracklist(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 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_artist_link_id_idx ON track_artist_link(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_mbid_matched_artist_idx ON track_artist_link(artist_mbid_matched, 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_track_idx ON track_artist_link(artist_id, type, track_id)");
|
|
||||||
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_musicnn_embeddings_track_idx ON track_musicnn_embeddings(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_directory_idx ON track_lyrics(directory_id)");
|
|
||||||
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_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_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!");
|
LMS_LOG(DB, INFO, "Indexes created!");
|
||||||
@@ -360,7 +365,7 @@ namespace lms::db
|
|||||||
LMS_SCOPED_TRACE_OVERVIEW("Database", "Vacuum");
|
LMS_SCOPED_TRACE_OVERVIEW("Database", "Vacuum");
|
||||||
LMS_LOG(DB, INFO, "Performing vacuum... This may take a while...");
|
LMS_LOG(DB, INFO, "Performing vacuum... This may take a while...");
|
||||||
|
|
||||||
// We manually take a lock here since vacuum cannot be inside a transaction
|
// We manually take a lock here since vacuum cannot be inside a transaction.
|
||||||
{
|
{
|
||||||
std::unique_lock lock{ static_cast<Db&>(_db).getMutex() };
|
std::unique_lock lock{ static_cast<Db&>(_db).getMutex() };
|
||||||
static_cast<Db&>(_db).executeSql("VACUUM");
|
static_cast<Db&>(_db).executeSql("VACUUM");
|
||||||
|
|||||||
@@ -383,7 +383,6 @@ VALUES
|
|||||||
EXPECT_FALSE(UIState::find(session, UIStateId{}));
|
EXPECT_FALSE(UIState::find(session, UIStateId{}));
|
||||||
EXPECT_FALSE(User::find(session, UserId{}));
|
EXPECT_FALSE(User::find(session, UserId{}));
|
||||||
|
|
||||||
// Verify UUID MBID round-trip through V107 migration (TEXT → BLOB)
|
|
||||||
const auto artistMBID{ core::UUID::fromString("550e8400-e29b-41d4-a716-446655440000") };
|
const auto artistMBID{ core::UUID::fromString("550e8400-e29b-41d4-a716-446655440000") };
|
||||||
ASSERT_TRUE(artistMBID);
|
ASSERT_TRUE(artistMBID);
|
||||||
const auto artist{ Artist::find(session, *artistMBID) };
|
const auto artist{ Artist::find(session, *artistMBID) };
|
||||||
|
|||||||
Reference in New Issue
Block a user