From cd165a5c4703f7bbc16823b2ee29a330d0c8f8c2 Mon Sep 17 00:00:00 2001 From: CyferShepard Date: Fri, 7 Mar 2025 23:14:59 +0200 Subject: [PATCH] fix for #249 also fixed activity materialized view not refreshing for imported data --- backend/db.js | 3 + ...in_data_to_activity_table_EpisodeID_Fix.js | 127 ++++++++++++++++++ backend/routes/sync.js | 4 + 3 files changed, 134 insertions(+) create mode 100644 backend/migrations/093_ji_insert_playback_plugin_data_to_activity_table_EpisodeID_Fix.js diff --git a/backend/db.js b/backend/db.js index 748eb27..0783303 100644 --- a/backend/db.js +++ b/backend/db.js @@ -215,5 +215,8 @@ module.exports = { insertBulk: insertBulk, updateSingleFieldBulk: updateSingleFieldBulk, querySingle: querySingle, + refreshMaterializedView: refreshMaterializedView, + materializedViews: materializedViews, + // initDB: initDB, }; diff --git a/backend/migrations/093_ji_insert_playback_plugin_data_to_activity_table_EpisodeID_Fix.js b/backend/migrations/093_ji_insert_playback_plugin_data_to_activity_table_EpisodeID_Fix.js new file mode 100644 index 0000000..1e031ca --- /dev/null +++ b/backend/migrations/093_ji_insert_playback_plugin_data_to_activity_table_EpisodeID_Fix.js @@ -0,0 +1,127 @@ +exports.up = async function (knex) { + try { + await knex.schema.raw(` + CREATE OR REPLACE PROCEDURE public.ji_insert_playback_plugin_data_to_activity_table( + ) + LANGUAGE 'plpgsql' + AS $BODY$ + BEGIN + insert into jf_playback_activity + SELECT + rowid, + false "IsPaused", + pb."UserId", + u."Name", + pb."ClientName", + pb."DeviceName", + null "DeviceId", + null "ApplicationVersion", + "ItemId" "NowPlayingItemId", + "ItemName" "NowPlayingItemName", + CASE WHEN e."EpisodeId"=pb."ItemId" THEN e."SeasonId" ELSE null END "SeasonId", + CASE WHEN i."Id"=e."SeriesId" THEN i."Name" ELSE null END "SeriesName", + CASE WHEN e."EpisodeId"=pb."ItemId" THEN e."EpisodeId" ELSE null END "EpisodeId", + "PlayDuration" "PlaybackDuration", + pb."DateCreated" "ActivityDateInserted", + "PlaybackMethod" "PlayMethod", + null "MediaStreams", + null "TranscodingInfo", + null "PlayState", + null "OriginalContainer", + null "RemoteEndPoint", + null "ServerId", + true "imported" + FROM public.jf_playback_reporting_plugin_data pb + LEFT JOIN public.jf_users u + on u."Id"=pb."UserId" + + LEFT JOIN public.jf_library_episodes e + on e."EpisodeId"=pb."ItemId" + + LEFT JOIN public.jf_library_items i + on i."Id"=pb."ItemId" + or i."Id"=e."SeriesId" + + WHERE NOT EXISTS + ( + SELECT "Id" "rowid" + FROM jf_playback_activity + WHERE imported=true + ) + AND + (i."Type" is not null OR (i."Type"='Series' and e."SeasonId" is not null and e."Id" is not null )); + END; + + + $BODY$; + ALTER PROCEDURE public.ji_insert_playback_plugin_data_to_activity_table() + OWNER TO "${process.env.POSTGRES_ROLE}"; + `); + } catch (error) { + console.error(error); + } +}; + +exports.down = async function (knex) { + try { + await knex.schema.raw(` + CREATE OR REPLACE PROCEDURE public.ji_insert_playback_plugin_data_to_activity_table( + ) + LANGUAGE 'plpgsql' + AS $BODY$ + BEGIN + insert into jf_playback_activity + SELECT + rowid, + false "IsPaused", + pb."UserId", + u."Name", + pb."ClientName", + pb."DeviceName", + null "DeviceId", + null "ApplicationVersion", + "ItemId" "NowPlayingItemId", + "ItemName" "NowPlayingItemName", + CASE WHEN e."EpisodeId"=pb."ItemId" THEN e."SeasonId" ELSE null END "SeasonId", + CASE WHEN i."Id"=e."SeriesId" THEN i."Name" ELSE null END "SeriesName", + CASE WHEN e."EpisodeId"=pb."ItemId" THEN e."Id" ELSE null END "EpisodeId", + "PlayDuration" "PlaybackDuration", + pb."DateCreated" "ActivityDateInserted", + "PlaybackMethod" "PlayMethod", + null "MediaStreams", + null "TranscodingInfo", + null "PlayState", + null "OriginalContainer", + null "RemoteEndPoint", + null "ServerId", + true "imported" + FROM public.jf_playback_reporting_plugin_data pb + LEFT JOIN public.jf_users u + on u."Id"=pb."UserId" + + LEFT JOIN public.jf_library_episodes e + on e."EpisodeId"=pb."ItemId" + + LEFT JOIN public.jf_library_items i + on i."Id"=pb."ItemId" + or i."Id"=e."SeriesId" + + WHERE NOT EXISTS + ( + SELECT "Id" "rowid" + FROM jf_playback_activity + WHERE imported=true + ) + AND + (i."Type" is not null OR (i."Type"='Series' and e."SeasonId" is not null and e."Id" is not null )); + END; + + + $BODY$; + ALTER PROCEDURE public.ji_insert_playback_plugin_data_to_activity_table() + OWNER TO "${process.env.POSTGRES_ROLE}"; + `); + } catch (error) { + console.error(error); + } +}; diff --git a/backend/routes/sync.js b/backend/routes/sync.js index 264ce47..b63d560 100644 --- a/backend/routes/sync.js +++ b/backend/routes/sync.js @@ -543,6 +543,10 @@ async function syncPlaybackPluginData() { PlaybacksyncTask.loggedData.push({ color: "dodgerblue", Message: "Any imported data has been processed." }); PlaybacksyncTask.loggedData.push({ color: "lawngreen", Message: `Playback Reporting Plugin Sync Complete` }); + + for (const view of db.materializedViews) { + await db.refreshMaterializedView(view); + } await logging.updateLog(PlaybacksyncTask.uuid, PlaybacksyncTask.loggedData, taskstate.SUCCESS); } catch (error) { PlaybacksyncTask.loggedData.push({ color: "red", Message: `Error: ${error}` });