nulla/lib/nulla/models/relation.ex
2025-06-23 09:16:27 +00:00

113 lines
2.9 KiB
Elixir

defmodule Nulla.Models.Relation do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias Nulla.Repo
alias Nulla.Snowflake
alias Nulla.Models.Actor
@primary_key {:id, :integer, autogenerate: false}
@foreign_key_type :integer
schema "relations" do
field :following, :boolean, default: false
field :followed_by, :boolean, default: false
field :showing_replies, :boolean, default: true
field :showing_reblogs, :boolean, default: true
field :notifying, :boolean, default: false
field :muting, :boolean, default: false
field :muting_notifications, :boolean, default: false
field :blocking, :boolean, default: false
field :blocked_by, :boolean, default: false
field :domain_blocking, :boolean, default: false
field :requested, :boolean, default: false
field :note, :string
belongs_to :local_actor, Actor
belongs_to :remote_actor, Actor
timestamps()
end
@doc false
def changeset(relation, attrs) do
relation
|> cast(attrs, [
:id,
:following,
:followed_by,
:showing_replies,
:showing_reblogs,
:notifying,
:muting,
:muting_notifications,
:blocking,
:blocked_by,
:domain_blocking,
:requested,
:note,
:local_actor_id,
:remote_actor_id
])
|> validate_required([:local_actor_id, :remote_actor_id])
|> unique_constraint([:local_actor_id, :remote_actor_id])
end
def create_relation(attrs) do
id = Map.get(attrs, :id, Snowflake.next_id())
%__MODULE__{}
|> __MODULE__.changeset(attrs)
|> put_change(:id, id)
|> Repo.insert()
end
def get_relation(by) when is_map(by) or is_list(by) do
Repo.get_by(__MODULE__, by)
end
def count_following(local_actor_id) do
__MODULE__
|> where([r], r.local_actor_id == ^local_actor_id and r.following == true)
|> select([r], count(r.id))
|> Repo.one()
end
def get_following(local_actor_id, page, limit) when is_integer(page) and page > 0 do
offset = (page - 1) * limit
query =
from r in __MODULE__,
join: a in Actor,
on: a.id == r.remote_actor_id,
where: r.local_actor_id == ^local_actor_id and r.following == true,
order_by: [asc: a.published],
offset: ^offset,
limit: ^limit,
select: a
Repo.all(query)
end
def count_followers(local_actor_id) do
__MODULE__
|> where([r], r.local_actor_id == ^local_actor_id and r.followed_by == true)
|> select([r], count(r.id))
|> Repo.one()
end
def get_followers(local_actor_id, page, limit) when is_integer(page) and page > 0 do
offset = (page - 1) * limit
query =
from r in __MODULE__,
join: a in Actor,
on: a.id == r.remote_actor_id,
where: r.local_actor_id == ^local_actor_id and r.followed_by == true,
order_by: [asc: a.published],
offset: ^offset,
limit: ^limit,
select: a
Repo.all(query)
end
end