From 85cf27119cb230259550bfb795dffcb724ebebf3 Mon Sep 17 00:00:00 2001
From: Samantaz Fox
Date: Mon, 6 Dec 2021 17:02:15 +0100
Subject: [PATCH] Move DB queries related to playlists in a separate module
(3/3)
---
src/invidious.cr | 4 +-
src/invidious/database/playlists.cr | 83 +++++++++++++++++++++++++++++
src/invidious/playlists.cr | 10 ++--
src/invidious/routes/feeds.cr | 5 +-
src/invidious/views/watch.ecr | 2 +-
5 files changed, 94 insertions(+), 10 deletions(-)
diff --git a/src/invidious.cr b/src/invidious.cr
index 0149be11..561fc9cf 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -656,7 +656,7 @@ get "/subscription_manager" do |env|
if format == "json"
env.response.content_type = "application/json"
env.response.headers["content-disposition"] = "attachment"
- playlists = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+ playlists = Invidious::Database::Playlists.select_like_iv(user.email)
next JSON.build do |json|
json.object do
@@ -672,7 +672,7 @@ get "/subscription_manager" do |env|
json.field "privacy", playlist.privacy.to_s
json.field "videos" do
json.array do
- PG_DB.query_all("SELECT id FROM playlist_videos WHERE plid = $1 ORDER BY array_position($2, index) LIMIT 500", playlist.id, playlist.index, as: String).each do |video_id|
+ Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id|
json.string video_id
end
end
diff --git a/src/invidious/database/playlists.cr b/src/invidious/database/playlists.cr
index 1dba64f3..950d5f4b 100644
--- a/src/invidious/database/playlists.cr
+++ b/src/invidious/database/playlists.cr
@@ -117,6 +117,39 @@ module Invidious::Database::Playlists
return PG_DB.query_all(request, author, as: InvidiousPlaylist)
end
+ # -------------------
+ # Salect (filtered)
+ # -------------------
+
+ def select_like_iv(email : String) : Array(InvidiousPlaylist)
+ request = <<-SQL
+ SELECT * FROM playlists
+ WHERE author = $1 AND id LIKE 'IV%'
+ ORDER BY created
+ SQL
+
+ PG_DB.query_all(request, email, as: InvidiousPlaylist)
+ end
+
+ def select_not_like_iv(email : String) : Array(InvidiousPlaylist)
+ request = <<-SQL
+ SELECT * FROM playlists
+ WHERE author = $1 AND id NOT LIKE 'IV%'
+ ORDER BY created
+ SQL
+
+ PG_DB.query_all(request, email, as: InvidiousPlaylist)
+ end
+
+ def select_user_created_playlists(email : String) : Array({String, String})
+ request = <<-SQL
+ SELECT id,title FROM playlists
+ WHERE author = $1 AND id LIKE 'IV%'
+ SQL
+
+ PG_DB.query_all(request, email, as: {String, String})
+ end
+
# -------------------
# Misc checks
# -------------------
@@ -148,6 +181,8 @@ end
module Invidious::Database::PlaylistVideos
extend self
+ private alias VideoIndex = Int64 | Array(Int64)
+
# -------------------
# Insert / Delete
# -------------------
@@ -171,4 +206,52 @@ module Invidious::Database::PlaylistVideos
PG_DB.exec(request, index)
end
+
+ # -------------------
+ # Salect
+ # -------------------
+
+ def select(plid : String, index : VideoIndex, offset, limit = 100) : Array(PlaylistVideo)
+ request = <<-SQL
+ SELECT * FROM playlist_videos
+ WHERE plid = $1
+ ORDER BY array_position($2, index)
+ LIMIT $3
+ OFFSET $4
+ SQL
+
+ return PG_DB.query_all(request, plid, index, limit, offset, as: PlaylistVideo)
+ end
+
+ def select_index(plid : String, vid : String) : Int64?
+ request = <<-SQL
+ SELECT index FROM playlist_videos
+ WHERE plid = $1 AND id = $2
+ LIMIT 1
+ SQL
+
+ return PG_DB.query_one?(request, plid, vid, as: Int64)
+ end
+
+ def select_one_id(plid : String, index : VideoIndex) : String?
+ request = <<-SQL
+ SELECT id FROM playlist_videos
+ WHERE plid = $1
+ ORDER BY array_position($2, index)
+ LIMIT 1
+ SQL
+
+ return PG_DB.query_one?(request, plid, index, as: String)
+ end
+
+ def select_ids(plid : String, index : VideoIndex, limit = 500) : Array(String)
+ request = <<-SQL
+ SELECT id FROM playlist_videos
+ WHERE plid = $1
+ ORDER BY array_position($2, index)
+ LIMIT $3
+ SQL
+
+ return PG_DB.query_all(request, plid, index, limit, as: String)
+ end
end
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index f68dc3b0..9128f7db 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -200,8 +200,8 @@ struct InvidiousPlaylist
json.field "videos" do
json.array do
- if !offset || offset == 0
- index = PG_DB.query_one?("SELECT index FROM playlist_videos WHERE plid = $1 AND id = $2 LIMIT 1", self.id, video_id, as: Int64)
+ if (!offset || offset == 0) && !video_id.nil?
+ index = Invidious::Database::PlaylistVideos.select_index(self.id, video_id)
offset = self.index.index(index) || 0
end
@@ -225,7 +225,8 @@ struct InvidiousPlaylist
end
def thumbnail
- @thumbnail_id ||= PG_DB.query_one?("SELECT id FROM playlist_videos WHERE plid = $1 ORDER BY array_position($2, index) LIMIT 1", self.id, self.index, as: String) || "-----------"
+ # TODO: Get playlist thumbnail from playlist data rather than first video
+ @thumbnail_id ||= Invidious::Database::PlaylistVideos.select_one_id(self.id, self.index) || "-----------"
"/vi/#{@thumbnail_id}/mqdefault.jpg"
end
@@ -411,8 +412,7 @@ def get_playlist_videos(db, playlist, offset, locale = nil, video_id = nil)
end
if playlist.is_a? InvidiousPlaylist
- db.query_all("SELECT * FROM playlist_videos WHERE plid = $1 ORDER BY array_position($2, index) LIMIT 100 OFFSET $3",
- playlist.id, playlist.index, offset, as: PlaylistVideo)
+ Invidious::Database::PlaylistVideos.select(playlist.id, playlist.index, offset, limit: 100)
else
if video_id
initial_data = YoutubeAPI.next({
diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr
index be58dd8d..b58a988f 100644
--- a/src/invidious/routes/feeds.cr
+++ b/src/invidious/routes/feeds.cr
@@ -15,13 +15,14 @@ module Invidious::Routes::Feeds
user = user.as(User)
- items_created = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+ # TODO: make a single DB call and separate the items here?
+ items_created = Invidious::Database::Playlists.select_like_iv(user.email)
items_created.map! do |item|
item.author = ""
item
end
- items_saved = PG_DB.query_all("SELECT * FROM playlists WHERE author = $1 AND id NOT LIKE 'IV%' ORDER BY created", user.email, as: InvidiousPlaylist)
+ items_saved = Invidious::Database::Playlists.select_not_like_iv(user.email)
items_saved.map! do |item|
item.author = ""
item
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index b85ea59d..fa4fe083 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -138,7 +138,7 @@ we're going to need to do it here in order to allow for translations.
<% if user %>
- <% playlists = PG_DB.query_all("SELECT id,title FROM playlists WHERE author = $1 AND id LIKE 'IV%'", user.email, as: {String, String}) %>
+ <% playlists = Invidious::Database::Playlists.select_user_created_playlists(user.email) %>
<% if !playlists.empty? %>