Cut typical query count to 3

This commit is contained in:
byte[] 2021-11-11 21:04:36 -05:00
parent 8c9216ff53
commit 736af0ace3
10 changed files with 338 additions and 131 deletions

View file

@ -141,37 +141,32 @@ defmodule Philomena.Filters do
end end
def recent_and_user_filters(user) do def recent_and_user_filters(user) do
recent_filter_ids = sorter = fn f ->
[user.current_filter_id | user.recent_filter_ids]
|> Enum.take(10)
user_filters =
Filter
|> select([f], %{id: f.id, name: f.name, recent: ^"f"})
|> where(user_id: ^user.id)
|> limit(10)
recent_filters =
Filter
|> select([f], %{id: f.id, name: f.name, recent: ^"t"})
|> where([f], f.id in ^recent_filter_ids)
union_all(recent_filters, ^user_filters)
|> Repo.all()
|> Enum.sort_by(fn f ->
Enum.find_index(user.recent_filter_ids, fn id -> f.id == id end) Enum.find_index(user.recent_filter_ids, fn id -> f.id == id end)
end) end
|> Enum.group_by(
fn mapper = fn %{id: id, name: name} ->
%{recent: "t"} -> "Recent Filters"
_user -> "Your Filters"
end,
fn %{id: id, name: name} ->
[key: name, value: id] [key: name, value: id]
end end
)
|> Enum.to_list() add_if = fn
|> Enum.reverse() list, _label, [] -> list
list, label, entries -> [{label, entries} | list]
end
user_filters =
user.layout.my_filters
|> Enum.sort_by(sorter)
|> Enum.map(mapper)
recent_filters =
user.layout.recent_filters
|> Enum.sort_by(sorter)
|> Enum.map(mapper)
[]
|> add_if.("Your Filters", user_filters)
|> add_if.("Recent Filters", recent_filters)
end end
def hide_tag(filter, tag) do def hide_tag(filter, tag) do

View file

@ -21,4 +21,24 @@ defmodule Philomena.Layouts do
def get_layout! do def get_layout! do
Repo.one!(Layout) Repo.one!(Layout)
end end
alias Philomena.Layouts.UserLayout
alias Philomena.Users.User
@doc """
Gets a single user_layout.
## Examples
iex> get_user_layout!(%User{})
%UserLayout{}
"""
@spec get_user_layout!(User.t()) :: UserLayout.t()
def get_user_layout!(user) do
UserLayout
|> where(user_id: ^user.id)
|> Repo.one!()
end
end end

View file

@ -0,0 +1,18 @@
defmodule Philomena.Layouts.UserLayout do
use Ecto.Schema
alias Philomena.Users.User
alias Philomena.Users.Role
alias Philomena.Filters.Filter
@primary_key false
schema "user_layouts" do
field :unread_notification_count, :integer
field :conversation_count, :integer
belongs_to :user, User
embeds_many :my_filters, Filter
embeds_many :recent_filters, Filter
embeds_many :roles, Role
end
end

View file

@ -661,16 +661,33 @@ defmodule Philomena.Users do
end end
defp load_with_roles(query) do defp load_with_roles(query) do
query = exclude(query, :select)
query =
from [user_token, user] in query,
left_join: current_filter in assoc(user, :current_filter),
left_join: forced_filter in assoc(user, :forced_filter),
inner_join: layout in assoc(user, :layout),
preload: [
user: {
user,
current_filter: current_filter,
forced_filter: forced_filter,
layout: layout
}
],
select: user_token
query query
|> Repo.one() |> Repo.one()
|> Repo.preload([:roles, :current_filter]) |> Map.fetch!(:user)
|> setup_roles() |> setup_roles()
end end
defp setup_roles(nil), do: nil defp setup_roles(nil), do: nil
defp setup_roles(user) do defp setup_roles(user) do
role_map = Map.new(user.roles, &{&1.resource_type || &1.name, &1.name}) role_map = Map.new(user.layout.roles, &{&1.resource_type || &1.name, &1.name})
%{user | role_map: role_map} %{user | role_map: role_map}
end end

View file

@ -20,6 +20,7 @@ defmodule Philomena.Users.User do
alias Philomena.UserIps.UserIp alias Philomena.UserIps.UserIp
alias Philomena.Bans.User, as: UserBan alias Philomena.Bans.User, as: UserBan
alias Philomena.Donations.Donation alias Philomena.Donations.Donation
alias Philomena.Layouts.UserLayout
@derive {Phoenix.Param, key: :slug} @derive {Phoenix.Param, key: :slug}
@derive {Inspect, except: [:password]} @derive {Inspect, except: [:password]}
@ -37,6 +38,7 @@ defmodule Philomena.Users.User do
has_many :bans, UserBan has_many :bans, UserBan
has_many :donations, Donation has_many :donations, Donation
has_one :commission, Commission has_one :commission, Commission
has_one :layout, UserLayout
many_to_many :roles, Role, join_through: "users_roles", on_replace: :delete many_to_many :roles, Role, join_through: "users_roles", on_replace: :delete
belongs_to :current_filter, Filter belongs_to :current_filter, Filter

View file

@ -14,10 +14,7 @@ defmodule PhilomenaWeb.CurrentFilterPlug do
{filter, forced_filter} = {filter, forced_filter} =
if user do if user do
user = user = maybe_set_default_filter(user)
user
|> Repo.preload([:current_filter, :forced_filter])
|> maybe_set_default_filter()
{user.current_filter, user.forced_filter} {user.current_filter, user.forced_filter}
else else

View file

@ -9,6 +9,7 @@ defmodule PhilomenaWeb.LayoutPlug do
alias Canada.Can alias Canada.Can
alias Philomena.Layouts alias Philomena.Layouts
alias Philomena.Users.User
import Plug.Conn import Plug.Conn
@doc false @doc false
@ -29,6 +30,7 @@ defmodule PhilomenaWeb.LayoutPlug do
|> assign(:report_count, layout.report_count) |> assign(:report_count, layout.report_count)
|> assign(:forums, visible_forums(user, layout.forums)) |> assign(:forums, visible_forums(user, layout.forums))
|> assign(:site_notices, site_notices(layout.site_notices)) |> assign(:site_notices, site_notices(layout.site_notices))
|> user_assignments(user)
end end
defp visible_forums(user, forum_list) do defp visible_forums(user, forum_list) do
@ -40,4 +42,15 @@ defmodule PhilomenaWeb.LayoutPlug do
defp site_notices(notice_list) do defp site_notices(notice_list) do
Enum.sort_by(notice_list, & &1.start_date, Date) Enum.sort_by(notice_list, & &1.start_date, Date)
end end
@spec user_assignments(Plug.Conn.t(), User.t()) :: Plug.Conn.t()
defp user_assignments(conn, %{layout: layout}) when is_map(layout) do
conn
|> assign(:notification_count, layout.unread_notification_count)
|> assign(:conversation_count, layout.conversation_count)
end
defp user_assignments(conn, _user) do
conn
end
end end

View file

@ -16,7 +16,6 @@ defmodule PhilomenaWeb.Router do
plug PhilomenaWeb.PaginationPlug plug PhilomenaWeb.PaginationPlug
plug PhilomenaWeb.EnsureUserEnabledPlug plug PhilomenaWeb.EnsureUserEnabledPlug
plug PhilomenaWeb.CurrentBanPlug plug PhilomenaWeb.CurrentBanPlug
plug PhilomenaWeb.NotificationCountPlug
plug PhilomenaWeb.LayoutPlug plug PhilomenaWeb.LayoutPlug
plug PhilomenaWeb.FilterSelectPlug plug PhilomenaWeb.FilterSelectPlug
end end

View file

@ -30,7 +30,28 @@ defmodule Philomena.Repo.Migrations.AddLayouts do
forums, forums,
site_notices site_notices
""", """,
"DROP VIEW layouts" "DROP VIEW IF EXISTS layouts"
)
execute(
"""
CREATE VIEW user_layouts AS
SELECT
u.id AS user_id,
roles.array AS roles,
my_filters.array AS my_filters,
recent_filters.array AS recent_filters,
unread_notification_count.count AS unread_notification_count,
conversation_from_count.count + conversation_to_count.count AS conversation_count
FROM users u
INNER JOIN LATERAL (SELECT array_agg(row_to_json(r.*)) AS array FROM roles r JOIN users_roles ur ON r.id=ur.role_id WHERE ur.user_id=u.id) roles ON 't'
INNER JOIN LATERAL (SELECT array_agg(row_to_json(f)) AS array FROM filters f WHERE f.user_id=u.id LIMIT 10) my_filters ON 't'
INNER JOIN LATERAL (SELECT array_agg(row_to_json(f)) AS array FROM filters f WHERE f.id = ANY(u.recent_filter_ids) LIMIT 10) recent_filters ON 't'
INNER JOIN LATERAL (SELECT COUNT(*) FROM unread_notifications WHERE user_id=u.id) unread_notification_count ON 't'
INNER JOIN LATERAL (SELECT COUNT(*) FROM conversations WHERE from_read='f' AND from_hidden='f' AND from_id=u.id) conversation_from_count ON 't'
INNER JOIN LATERAL (SELECT COUNT(*) FROM conversations WHERE to_read='f' AND to_hidden='f' AND to_id=u.id) conversation_to_count ON 't'
""",
"DROP VIEW IF EXISTS user_layouts"
) )
end end
end end

View file

@ -1145,6 +1145,39 @@ CREATE SEQUENCE public.mod_notes_id_seq
ALTER SEQUENCE public.mod_notes_id_seq OWNED BY public.mod_notes.id; ALTER SEQUENCE public.mod_notes_id_seq OWNED BY public.mod_notes.id;
--
-- Name: moderation_logs; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.moderation_logs (
id bigint NOT NULL,
user_id bigint NOT NULL,
body character varying NOT NULL,
subject_path character varying NOT NULL,
type character varying NOT NULL,
created_at timestamp(0) without time zone NOT NULL
);
--
-- Name: moderation_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.moderation_logs_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: moderation_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.moderation_logs_id_seq OWNED BY public.moderation_logs.id;
-- --
-- Name: notifications; Type: TABLE; Schema: public; Owner: - -- Name: notifications; Type: TABLE; Schema: public; Owner: -
-- --
@ -1840,6 +1873,136 @@ CREATE SEQUENCE public.user_ips_id_seq
ALTER SEQUENCE public.user_ips_id_seq OWNED BY public.user_ips.id; ALTER SEQUENCE public.user_ips_id_seq OWNED BY public.user_ips.id;
--
-- Name: users; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.users (
id integer NOT NULL,
email public.citext DEFAULT ''::character varying NOT NULL,
encrypted_password character varying DEFAULT ''::character varying NOT NULL,
reset_password_token character varying,
reset_password_sent_at timestamp without time zone,
remember_created_at timestamp without time zone,
sign_in_count integer DEFAULT 0 NOT NULL,
current_sign_in_at timestamp without time zone,
last_sign_in_at timestamp without time zone,
current_sign_in_ip inet,
last_sign_in_ip inet,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
deleted_at timestamp without time zone,
authentication_token character varying NOT NULL,
name character varying NOT NULL,
slug character varying NOT NULL,
role character varying DEFAULT 'user'::character varying NOT NULL,
description_textile character varying,
avatar character varying,
spoiler_type character varying DEFAULT 'static'::character varying NOT NULL,
theme character varying DEFAULT 'default'::character varying NOT NULL,
images_per_page integer DEFAULT 15 NOT NULL,
show_large_thumbnails boolean DEFAULT true NOT NULL,
show_sidebar_and_watched_images boolean DEFAULT true NOT NULL,
fancy_tag_field_on_upload boolean DEFAULT true NOT NULL,
fancy_tag_field_on_edit boolean DEFAULT true NOT NULL,
fancy_tag_field_in_settings boolean DEFAULT true NOT NULL,
autorefresh_by_default boolean DEFAULT false NOT NULL,
anonymous_by_default boolean DEFAULT false NOT NULL,
comments_newest_first boolean DEFAULT true NOT NULL,
comments_always_jump_to_last boolean DEFAULT false NOT NULL,
comments_per_page integer DEFAULT 20 NOT NULL,
watch_on_reply boolean DEFAULT true NOT NULL,
watch_on_new_topic boolean DEFAULT true NOT NULL,
watch_on_upload boolean DEFAULT true NOT NULL,
messages_newest_first boolean DEFAULT false NOT NULL,
serve_webm boolean DEFAULT false NOT NULL,
no_spoilered_in_watched boolean DEFAULT false NOT NULL,
watched_images_query_str character varying DEFAULT ''::character varying NOT NULL,
watched_images_exclude_str character varying DEFAULT ''::character varying NOT NULL,
forum_posts_count integer DEFAULT 0 NOT NULL,
topic_count integer DEFAULT 0 NOT NULL,
recent_filter_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
unread_notification_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
watched_tag_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
deleted_by_user_id integer,
current_filter_id integer,
failed_attempts integer,
unlock_token character varying,
locked_at timestamp without time zone,
uploads_count integer DEFAULT 0 NOT NULL,
votes_cast_count integer DEFAULT 0 NOT NULL,
comments_posted_count integer DEFAULT 0 NOT NULL,
metadata_updates_count integer DEFAULT 0 NOT NULL,
images_favourited_count integer DEFAULT 0 NOT NULL,
last_donation_at timestamp without time zone,
scratchpad_textile text,
use_centered_layout boolean DEFAULT true NOT NULL,
secondary_role character varying,
hide_default_role boolean DEFAULT false NOT NULL,
personal_title character varying,
show_hidden_items boolean DEFAULT false NOT NULL,
hide_vote_counts boolean DEFAULT false NOT NULL,
hide_advertisements boolean DEFAULT false NOT NULL,
encrypted_otp_secret character varying,
encrypted_otp_secret_iv character varying,
encrypted_otp_secret_salt character varying,
consumed_timestep integer,
otp_required_for_login boolean,
otp_backup_codes character varying[],
last_renamed_at timestamp without time zone DEFAULT '1970-01-01 00:00:00'::timestamp without time zone NOT NULL,
forced_filter_id bigint,
confirmed_at timestamp(0) without time zone,
senior_staff boolean DEFAULT false,
description character varying,
scratchpad character varying,
bypass_rate_limits boolean DEFAULT false,
scale_large_images character varying(255) DEFAULT 'true'::character varying NOT NULL
);
--
-- Name: users_roles; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.users_roles (
user_id integer NOT NULL,
role_id integer NOT NULL
);
--
-- Name: user_layouts; Type: VIEW; Schema: public; Owner: -
--
CREATE VIEW public.user_layouts AS
SELECT u.id AS user_id,
roles."array" AS roles,
my_filters."array" AS my_filters,
recent_filters."array" AS recent_filters,
unread_notification_count.count AS unread_notification_count,
(conversation_from_count.count + conversation_to_count.count) AS conversation_count
FROM ((((((public.users u
JOIN LATERAL ( SELECT array_agg(row_to_json(r.*)) AS "array"
FROM (public.roles r
JOIN public.users_roles ur ON ((r.id = ur.role_id)))
WHERE (ur.user_id = u.id)) roles ON (true))
JOIN LATERAL ( SELECT array_agg(row_to_json(f.*)) AS "array"
FROM public.filters f
WHERE (f.user_id = u.id)) my_filters ON (true))
JOIN LATERAL ( SELECT array_agg(row_to_json(f.*)) AS "array"
FROM public.filters f
WHERE (f.id = ANY (u.recent_filter_ids))) recent_filters ON (true))
JOIN LATERAL ( SELECT count(*) AS count
FROM public.unread_notifications
WHERE (unread_notifications.user_id = u.id)) unread_notification_count ON (true))
JOIN LATERAL ( SELECT count(*) AS count
FROM public.conversations
WHERE ((conversations.from_read = false) AND (conversations.from_hidden = false) AND (conversations.from_id = u.id))) conversation_from_count ON (true))
JOIN LATERAL ( SELECT count(*) AS count
FROM public.conversations
WHERE ((conversations.to_read = false) AND (conversations.to_hidden = false) AND (conversations.to_id = u.id))) conversation_to_count ON (true));
-- --
-- Name: user_name_changes; Type: TABLE; Schema: public; Owner: - -- Name: user_name_changes; Type: TABLE; Schema: public; Owner: -
-- --
@ -1973,93 +2136,6 @@ CREATE SEQUENCE public.user_whitelists_id_seq
ALTER SEQUENCE public.user_whitelists_id_seq OWNED BY public.user_whitelists.id; ALTER SEQUENCE public.user_whitelists_id_seq OWNED BY public.user_whitelists.id;
--
-- Name: users; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.users (
id integer NOT NULL,
email public.citext DEFAULT ''::character varying NOT NULL,
encrypted_password character varying DEFAULT ''::character varying NOT NULL,
reset_password_token character varying,
reset_password_sent_at timestamp without time zone,
remember_created_at timestamp without time zone,
sign_in_count integer DEFAULT 0 NOT NULL,
current_sign_in_at timestamp without time zone,
last_sign_in_at timestamp without time zone,
current_sign_in_ip inet,
last_sign_in_ip inet,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
deleted_at timestamp without time zone,
authentication_token character varying NOT NULL,
name character varying NOT NULL,
slug character varying NOT NULL,
role character varying DEFAULT 'user'::character varying NOT NULL,
description_textile character varying,
avatar character varying,
spoiler_type character varying DEFAULT 'static'::character varying NOT NULL,
theme character varying DEFAULT 'default'::character varying NOT NULL,
images_per_page integer DEFAULT 15 NOT NULL,
show_large_thumbnails boolean DEFAULT true NOT NULL,
show_sidebar_and_watched_images boolean DEFAULT true NOT NULL,
fancy_tag_field_on_upload boolean DEFAULT true NOT NULL,
fancy_tag_field_on_edit boolean DEFAULT true NOT NULL,
fancy_tag_field_in_settings boolean DEFAULT true NOT NULL,
autorefresh_by_default boolean DEFAULT false NOT NULL,
anonymous_by_default boolean DEFAULT false NOT NULL,
comments_newest_first boolean DEFAULT true NOT NULL,
comments_always_jump_to_last boolean DEFAULT false NOT NULL,
comments_per_page integer DEFAULT 20 NOT NULL,
watch_on_reply boolean DEFAULT true NOT NULL,
watch_on_new_topic boolean DEFAULT true NOT NULL,
watch_on_upload boolean DEFAULT true NOT NULL,
messages_newest_first boolean DEFAULT false NOT NULL,
serve_webm boolean DEFAULT false NOT NULL,
no_spoilered_in_watched boolean DEFAULT false NOT NULL,
watched_images_query_str character varying DEFAULT ''::character varying NOT NULL,
watched_images_exclude_str character varying DEFAULT ''::character varying NOT NULL,
forum_posts_count integer DEFAULT 0 NOT NULL,
topic_count integer DEFAULT 0 NOT NULL,
recent_filter_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
unread_notification_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
watched_tag_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
deleted_by_user_id integer,
current_filter_id integer,
failed_attempts integer,
unlock_token character varying,
locked_at timestamp without time zone,
uploads_count integer DEFAULT 0 NOT NULL,
votes_cast_count integer DEFAULT 0 NOT NULL,
comments_posted_count integer DEFAULT 0 NOT NULL,
metadata_updates_count integer DEFAULT 0 NOT NULL,
images_favourited_count integer DEFAULT 0 NOT NULL,
last_donation_at timestamp without time zone,
scratchpad_textile text,
use_centered_layout boolean DEFAULT true NOT NULL,
secondary_role character varying,
hide_default_role boolean DEFAULT false NOT NULL,
personal_title character varying,
show_hidden_items boolean DEFAULT false NOT NULL,
hide_vote_counts boolean DEFAULT false NOT NULL,
hide_advertisements boolean DEFAULT false NOT NULL,
encrypted_otp_secret character varying,
encrypted_otp_secret_iv character varying,
encrypted_otp_secret_salt character varying,
consumed_timestep integer,
otp_required_for_login boolean,
otp_backup_codes character varying[],
last_renamed_at timestamp without time zone DEFAULT '1970-01-01 00:00:00'::timestamp without time zone NOT NULL,
forced_filter_id bigint,
confirmed_at timestamp(0) without time zone,
senior_staff boolean DEFAULT false,
description character varying,
scratchpad character varying,
bypass_rate_limits boolean DEFAULT false,
scale_large_images character varying(255) DEFAULT 'true'::character varying NOT NULL
);
-- --
-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: -
-- --
@ -2079,16 +2155,6 @@ CREATE SEQUENCE public.users_id_seq
ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id;
--
-- Name: users_roles; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.users_roles (
user_id integer NOT NULL,
role_id integer NOT NULL
);
-- --
-- Name: versions; Type: TABLE; Schema: public; Owner: - -- Name: versions; Type: TABLE; Schema: public; Owner: -
-- --
@ -2293,6 +2359,13 @@ ALTER TABLE ONLY public.messages ALTER COLUMN id SET DEFAULT nextval('public.mes
ALTER TABLE ONLY public.mod_notes ALTER COLUMN id SET DEFAULT nextval('public.mod_notes_id_seq'::regclass); ALTER TABLE ONLY public.mod_notes ALTER COLUMN id SET DEFAULT nextval('public.mod_notes_id_seq'::regclass);
--
-- Name: moderation_logs id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.moderation_logs ALTER COLUMN id SET DEFAULT nextval('public.moderation_logs_id_seq'::regclass);
-- --
-- Name: notifications id; Type: DEFAULT; Schema: public; Owner: - -- Name: notifications id; Type: DEFAULT; Schema: public; Owner: -
-- --
@ -2652,6 +2725,14 @@ ALTER TABLE ONLY public.mod_notes
ADD CONSTRAINT mod_notes_pkey PRIMARY KEY (id); ADD CONSTRAINT mod_notes_pkey PRIMARY KEY (id);
--
-- Name: moderation_logs moderation_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.moderation_logs
ADD CONSTRAINT moderation_logs_pkey PRIMARY KEY (id);
-- --
-- Name: notifications notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- Name: notifications notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
-- --
@ -4050,6 +4131,41 @@ CREATE INDEX index_vpns_on_ip ON public.vpns USING gist (ip inet_ops);
CREATE INDEX intensities_index ON public.images USING btree (se_intensity, sw_intensity, ne_intensity, nw_intensity, average_intensity); CREATE INDEX intensities_index ON public.images USING btree (se_intensity, sw_intensity, ne_intensity, nw_intensity, average_intensity);
--
-- Name: moderation_logs_created_at_index; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX moderation_logs_created_at_index ON public.moderation_logs USING btree (created_at);
--
-- Name: moderation_logs_type_created_at_index; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX moderation_logs_type_created_at_index ON public.moderation_logs USING btree (type, created_at);
--
-- Name: moderation_logs_type_index; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX moderation_logs_type_index ON public.moderation_logs USING btree (type);
--
-- Name: moderation_logs_user_id_created_at_index; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX moderation_logs_user_id_created_at_index ON public.moderation_logs USING btree (user_id, created_at);
--
-- Name: moderation_logs_user_id_index; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX moderation_logs_user_id_index ON public.moderation_logs USING btree (user_id);
-- --
-- Name: user_tokens_context_token_index; Type: INDEX; Schema: public; Owner: - -- Name: user_tokens_context_token_index; Type: INDEX; Schema: public; Owner: -
-- --
@ -4880,6 +4996,14 @@ ALTER TABLE ONLY public.image_tag_locks
ADD CONSTRAINT image_tag_locks_tag_id_fkey FOREIGN KEY (tag_id) REFERENCES public.tags(id) ON DELETE CASCADE; ADD CONSTRAINT image_tag_locks_tag_id_fkey FOREIGN KEY (tag_id) REFERENCES public.tags(id) ON DELETE CASCADE;
--
-- Name: moderation_logs moderation_logs_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.moderation_logs
ADD CONSTRAINT moderation_logs_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
-- --
-- Name: user_tokens user_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- Name: user_tokens user_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
-- --
@ -4916,4 +5040,5 @@ INSERT INTO public."schema_migrations" (version) VALUES (20210912171343);
INSERT INTO public."schema_migrations" (version) VALUES (20210917190346); INSERT INTO public."schema_migrations" (version) VALUES (20210917190346);
INSERT INTO public."schema_migrations" (version) VALUES (20210921025336); INSERT INTO public."schema_migrations" (version) VALUES (20210921025336);
INSERT INTO public."schema_migrations" (version) VALUES (20210929181319); INSERT INTO public."schema_migrations" (version) VALUES (20210929181319);
INSERT INTO public."schema_migrations" (version) VALUES (20211107130226);
INSERT INTO public."schema_migrations" (version) VALUES (20211108003620); INSERT INTO public."schema_migrations" (version) VALUES (20211108003620);