CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public;
+--
+-- Name: EXTENSION btree_gist; Type: COMMENT; Schema: -; Owner: -
+--
+
+COMMENT ON EXTENSION btree_gist IS 'support for indexing common datatypes in GiST';
+
+
--
-- Name: format_enum; Type: TYPE; Schema: public; Owner: -
--
CREATE TYPE public.user_role_enum AS ENUM (
'administrator',
- 'moderator'
+ 'moderator',
+ 'importer'
);
'deleted'
);
+
+--
+-- Name: api_rate_limit(bigint); Type: FUNCTION; Schema: public; Owner: -
+--
+
+CREATE FUNCTION public.api_rate_limit(user_id bigint) RETURNS integer
+ LANGUAGE plpgsql STABLE
+ AS $$
+ DECLARE
+ min_changes_per_hour int4 := 100;
+ initial_changes_per_hour int4 := 1000;
+ max_changes_per_hour int4 := 100000;
+ days_to_max_changes int4 := 7;
+ importer_changes_per_hour int4 := 1000000;
+ moderator_changes_per_hour int4 := 1000000;
+ roles text[];
+ last_block timestamp without time zone;
+ first_change timestamp without time zone;
+ active_reports int4;
+ time_since_first_change double precision;
+ max_changes double precision;
+ recent_changes int4;
+ BEGIN
+ SELECT ARRAY_AGG(user_roles.role) INTO STRICT roles FROM user_roles WHERE user_roles.user_id = api_rate_limit.user_id;
+
+ IF 'moderator' = ANY(roles) THEN
+ max_changes := moderator_changes_per_hour;
+ ELSIF 'importer' = ANY(roles) THEN
+ max_changes := importer_changes_per_hour;
+ ELSE
+ SELECT user_blocks.created_at INTO last_block FROM user_blocks WHERE user_blocks.user_id = api_rate_limit.user_id ORDER BY user_blocks.created_at DESC LIMIT 1;
+
+ IF FOUND THEN
+ SELECT changesets.created_at INTO first_change FROM changesets WHERE changesets.user_id = api_rate_limit.user_id AND changesets.created_at > last_block ORDER BY changesets.created_at LIMIT 1;
+ ELSE
+ SELECT changesets.created_at INTO first_change FROM changesets WHERE changesets.user_id = api_rate_limit.user_id ORDER BY changesets.created_at LIMIT 1;
+ END IF;
+
+ IF NOT FOUND THEN
+ first_change := CURRENT_TIMESTAMP AT TIME ZONE 'UTC';
+ END IF;
+
+ SELECT COUNT(*) INTO STRICT active_reports
+ FROM issues INNER JOIN reports ON reports.issue_id = issues.id
+ WHERE issues.reported_user_id = api_rate_limit.user_id AND issues.status = 'open' AND reports.updated_at >= COALESCE(issues.resolved_at, '1970-01-01');
+
+ time_since_first_change := EXTRACT(EPOCH FROM CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - first_change);
+
+ max_changes := max_changes_per_hour * POWER(time_since_first_change, 2) / POWER(days_to_max_changes * 24 * 60 * 60, 2);
+ max_changes := GREATEST(initial_changes_per_hour, LEAST(max_changes_per_hour, FLOOR(max_changes)));
+ max_changes := max_changes / POWER(2, active_reports);
+ max_changes := GREATEST(min_changes_per_hour, LEAST(max_changes_per_hour, max_changes));
+ END IF;
+
+ SELECT COALESCE(SUM(changesets.num_changes), 0) INTO STRICT recent_changes FROM changesets WHERE changesets.user_id = api_rate_limit.user_id AND changesets.created_at >= CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - '1 hour'::interval;
+
+ RETURN max_changes - recent_changes;
+ END;
+ $$;
+
+
SET default_tablespace = '';
SET default_table_access_method = heap;
to_user_id bigint NOT NULL,
to_user_visible boolean DEFAULT true NOT NULL,
from_user_visible boolean DEFAULT true NOT NULL,
- body_format public.format_enum DEFAULT 'markdown'::public.format_enum NOT NULL
+ body_format public.format_enum DEFAULT 'markdown'::public.format_enum NOT NULL,
+ muted boolean DEFAULT false NOT NULL
);
--
CREATE SEQUENCE public.note_comments_id_seq
- AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
--
CREATE SEQUENCE public.notes_id_seq
- AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
--
CREATE SEQUENCE public.oauth_nonces_id_seq
- AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
ALTER SEQUENCE public.user_blocks_id_seq OWNED BY public.user_blocks.id;
+--
+-- Name: user_mutes; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.user_mutes (
+ id bigint NOT NULL,
+ owner_id bigint NOT NULL,
+ subject_id bigint NOT NULL,
+ created_at timestamp(6) without time zone NOT NULL,
+ updated_at timestamp(6) without time zone NOT NULL
+);
+
+
+--
+-- Name: user_mutes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
+--
+
+CREATE SEQUENCE public.user_mutes_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+--
+-- Name: user_mutes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
+--
+
+ALTER SEQUENCE public.user_mutes_id_seq OWNED BY public.user_mutes.id;
+
+
--
-- Name: user_preferences; Type: TABLE; Schema: public; Owner: -
--
ALTER TABLE ONLY public.user_blocks ALTER COLUMN id SET DEFAULT nextval('public.user_blocks_id_seq'::regclass);
+--
+-- Name: user_mutes id; Type: DEFAULT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.user_mutes ALTER COLUMN id SET DEFAULT nextval('public.user_mutes_id_seq'::regclass);
+
+
--
-- Name: user_roles id; Type: DEFAULT; Schema: public; Owner: -
--
--
ALTER TABLE ONLY public.current_relation_members
- ADD CONSTRAINT current_relation_members_pkey PRIMARY KEY (relation_id, member_type, member_id, member_role, sequence_id);
+ ADD CONSTRAINT current_relation_members_pkey PRIMARY KEY (relation_id, sequence_id);
--
--
ALTER TABLE ONLY public.relation_members
- ADD CONSTRAINT relation_members_pkey PRIMARY KEY (relation_id, version, member_type, member_id, member_role, sequence_id);
+ ADD CONSTRAINT relation_members_pkey PRIMARY KEY (relation_id, version, sequence_id);
--
ADD CONSTRAINT user_blocks_pkey PRIMARY KEY (id);
+--
+-- Name: user_mutes user_mutes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.user_mutes
+ ADD CONSTRAINT user_mutes_pkey PRIMARY KEY (id);
+
+
--
-- Name: user_preferences user_preferences_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
CREATE INDEX index_changeset_comments_on_created_at ON public.changeset_comments USING btree (created_at);
+--
+-- Name: index_changesets_on_user_id_and_closed_at; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE INDEX index_changesets_on_user_id_and_closed_at ON public.changesets USING btree (user_id, closed_at);
+
+
--
-- Name: index_changesets_subscribers_on_changeset_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_user_blocks_on_user_id ON public.user_blocks USING btree (user_id);
+--
+-- Name: index_user_mutes_on_owner_id_and_subject_id; Type: INDEX; Schema: public; Owner: -
+--
+
+CREATE UNIQUE INDEX index_user_mutes_on_owner_id_and_subject_id ON public.user_mutes USING btree (owner_id, subject_id);
+
+
--
-- Name: messages_from_user_id_idx; Type: INDEX; Schema: public; Owner: -
--
--
--- Name: users_display_name_idx; Type: INDEX; Schema: public; Owner: -
+-- Name: users_display_name_canonical_idx; Type: INDEX; Schema: public; Owner: -
--
-CREATE UNIQUE INDEX users_display_name_idx ON public.users USING btree (display_name);
+CREATE INDEX users_display_name_canonical_idx ON public.users USING btree (lower(NORMALIZE(display_name, NFKC)));
--
--- Name: users_display_name_lower_idx; Type: INDEX; Schema: public; Owner: -
+-- Name: users_display_name_idx; Type: INDEX; Schema: public; Owner: -
--
-CREATE INDEX users_display_name_lower_idx ON public.users USING btree (lower((display_name)::text));
+CREATE UNIQUE INDEX users_display_name_idx ON public.users USING btree (display_name);
--
ADD CONSTRAINT fk_rails_330c32d8d9 FOREIGN KEY (resource_owner_id) REFERENCES public.users(id) NOT VALID;
+--
+-- Name: user_mutes fk_rails_591dad3359; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.user_mutes
+ ADD CONSTRAINT fk_rails_591dad3359 FOREIGN KEY (owner_id) REFERENCES public.users(id);
+
+
--
-- Name: oauth_access_tokens fk_rails_732cb83ab7; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ADD CONSTRAINT fk_rails_cc886e315a FOREIGN KEY (owner_id) REFERENCES public.users(id) NOT VALID;
+--
+-- Name: user_mutes fk_rails_e9dd4fb6c3; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.user_mutes
+ ADD CONSTRAINT fk_rails_e9dd4fb6c3 FOREIGN KEY (subject_id) REFERENCES public.users(id);
+
+
--
-- Name: oauth_access_tokens fk_rails_ee63f25419; Type: FK CONSTRAINT; Schema: public; Owner: -
--
('23'),
('22'),
('21'),
+('20240117185445'),
+('20231213182102'),
+('20231206141457'),
+('20231117170422'),
+('20231101222146'),
+('20231029151516'),
+('20231010203028'),
+('20231010201451'),
+('20231010194809'),
('20231007141103'),
('20230830115220'),
('20230830115219'),