M lib/linkhut/links.ex => lib/linkhut/links.ex +5 -4
@@ 228,9 228,10 @@ defmodule Linkhut.Links do
datetime = DateTime.add(DateTime.now!("Etc/UTC"), -days, :day)
links()
- |> where([l, s, _], l.inserted_at == s.last)
|> where(is_private: false)
|> where(is_unread: false)
+ |> where([_, s], s.user_daily_entry <= 2)
+ |> where([_, s], s.rank == 0.0)
|> where([l], l.inserted_at >= ^datetime)
|> ordering(params)
end
@@ 240,7 241,7 @@ defmodule Linkhut.Links do
"""
def popular(params, popularity \\ 3) do
links()
- |> where([l, s, _], l.inserted_at == s.first)
+ |> where([l, s, _], s.rank == 1.0)
|> where(is_private: false)
|> where(is_unread: false)
|> where([_, s, _], s.saves >= ^popularity)
@@ 270,8 271,8 @@ defmodule Linkhut.Links do
def links(params \\ []) do
from(l in Link,
- left_join: s in PublicLink,
- on: [url: l.url, user_id: l.user_id],
+ join: s in PublicLink,
+ on: [id: l.id],
select_merge: ^select_fields(params),
preload: [:user, :variants, :savers]
)
M lib/linkhut/links/public_link.ex => lib/linkhut/links/public_link.ex +4 -4
@@ 8,11 8,11 @@ defmodule Linkhut.Links.PublicLink do
@primary_key false
schema "public_links" do
- field :url, :string, primary_key: true
- field :user_id, :id, primary_key: true
+ field :id, :integer, primary_key: true
+ field :inserted_at, :utc_datetime
belongs_to :user, User, define_field: false
field :saves, :integer
- field :first, :utc_datetime
- field :last, :utc_datetime
+ field :rank, :float
+ field :user_daily_entry, :integer
end
end
M lib/linkhut/links/tags.ex => lib/linkhut/links/tags.ex +2 -1
@@ 53,6 53,7 @@ defmodule Linkhut.Links.Tags do
end
defp valid?(tag) do
- String.valid?(tag) && String.length(tag) <= 128 && not String.starts_with?(tag, "~")
+ String.valid?(tag) && String.length(tag) <= 128 && not String.starts_with?(tag, "~") &&
+ not String.starts_with?(tag, "-")
end
end
M lib/linkhut/tags.ex => lib/linkhut/tags.ex +0 -2
@@ 70,8 70,6 @@ defmodule Linkhut.Tags do
count: count("*")
},
group_by: fragment("lower(?)", t.tag)
-
- # order_by: [desc: count("*"), asc: fragment("label")]
end
defp ordering(query, opts) do
A priv/repo/migrations/20241008110848_add_inserted_at_to_public_links.exs => priv/repo/migrations/20241008110848_add_inserted_at_to_public_links.exs +48 -0
@@ 0,0 1,48 @@
+defmodule Linkhut.Repo.Migrations.Eifjcbfrhgfnurctrtbiftnfliinivrdtvbrthfejdib do
+ use Ecto.Migration
+
+ def up do
+ execute "DROP MATERIALIZED VIEW IF EXISTS public_links;"
+
+ execute """
+ CREATE MATERIALIZED VIEW public_links AS
+ SELECT
+ l.id,
+ l.url,
+ l.user_id,
+ l.inserted_at,
+ percent_rank() OVER "reverse_order" AS "rank",
+ rank() OVER "daily_entry" AS "user_daily_entry",
+ count(l.url) OVER "distinct_link" AS "saves",
+ u.username AS "username"
+ FROM links l
+ JOIN users u on l.user_id = u.id
+ WHERE (NOT l.is_private AND NOT l.is_unread AND NOT u.unlisted)
+ WINDOW
+ "distinct_link" AS (PARTITION BY l.url),
+ "reverse_order" AS (PARTITION BY l.url ORDER BY l.inserted_at DESC),
+ "daily_entry" AS (PARTITION BY date_trunc('day', l.inserted_at), l.user_id ORDER BY l.inserted_at ASC)
+ """
+ end
+
+ def down do
+ execute "DROP MATERIALIZED VIEW IF EXISTS public_links;"
+
+ execute """
+ CREATE MATERIALIZED VIEW public_links AS
+ SELECT
+ l.id,
+ l.url,
+ l.user_id,
+ min(l.inserted_at) OVER "distinct_link" AS "first",
+ max(l.inserted_at) OVER "distinct_link" AS "last",
+ count(l.url) OVER "distinct_link" AS "saves",
+ u.username AS "username"
+ FROM links l
+ JOIN users u on l.user_id = u.id
+ WHERE (NOT l.is_private AND NOT l.is_unread AND NOT u.unlisted)
+ WINDOW "distinct_link" AS (PARTITION BY l.url)
+ ;
+ """
+ end
+end