X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/c6bb4a5f4eadc46bac599cd6a5174b199c1b6026..add9c06e01a9a9089e7927829009fdb1334c5dc5:/db/structure.sql diff --git a/db/structure.sql b/db/structure.sql index f7f329326..ba60918f0 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -16,6 +16,13 @@ SET row_security = off; 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: - -- @@ -108,6 +115,67 @@ CREATE TYPE public.user_status_enum AS ENUM ( '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; @@ -956,7 +1024,6 @@ CREATE TABLE public.note_comments ( -- CREATE SEQUENCE public.note_comments_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -992,7 +1059,6 @@ CREATE TABLE public.notes ( -- CREATE SEQUENCE public.notes_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -1138,7 +1204,6 @@ CREATE TABLE public.oauth_nonces ( -- CREATE SEQUENCE public.oauth_nonces_id_seq - AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE @@ -2438,6 +2503,13 @@ CREATE INDEX index_changeset_comments_on_changeset_id_and_created_at ON public.c 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: - -- @@ -3438,6 +3510,9 @@ INSERT INTO "schema_migrations" (version) VALUES ('23'), ('22'), ('21'), +('20231206141457'), +('20231117170422'), +('20231101222146'), ('20231029151516'), ('20231010194809'), ('20231007141103'),