X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/4c4150e0d0dc43c0468388956728d8ffc43e6c9c..f2f0cf1ad9e5fb7ea35c807f313820bd6efa641c:/db/structure.sql diff --git a/db/structure.sql b/db/structure.sql index 939799c0a..56e778523 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -91,7 +91,8 @@ CREATE TYPE public.nwr_enum AS ENUM ( CREATE TYPE public.user_role_enum AS ENUM ( 'administrator', - 'moderator' + 'moderator', + 'importer' ); @@ -107,6 +108,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; @@ -1883,7 +1945,7 @@ ALTER TABLE ONLY public.current_nodes -- 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); -- @@ -2107,7 +2169,7 @@ ALTER TABLE ONLY public.redactions -- 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); -- @@ -3393,122 +3455,125 @@ ALTER TABLE ONLY public.ways SET search_path TO "$user", public; INSERT INTO "schema_migrations" (version) VALUES -('1'), -('10'), -('11'), -('12'), -('13'), -('14'), -('15'), -('16'), -('17'), -('18'), -('19'), -('2'), -('20'), -('20100513171259'), -('20100516124737'), -('20100910084426'), -('20101114011429'), -('20110322001319'), -('20110508145337'), -('20110521142405'), -('20110925112722'), -('20111116184519'), -('20111212183945'), -('20120123184321'), -('20120208122334'), -('20120208194454'), -('20120214210114'), -('20120219161649'), -('20120318201948'), -('20120328090602'), -('20120404205604'), -('20120808231205'), -('20121005195010'), -('20121012044047'), -('20121119165817'), -('20121202155309'), -('20121203124841'), -('20130328184137'), -('20131212124700'), -('20140115192822'), -('20140117185510'), -('20140210003018'), -('20140507110937'), -('20140519141742'), -('20150110152606'), -('20150111192335'), -('20150222101847'), -('20150818224516'), -('20160822153055'), -('20161002153425'), -('20161011010929'), -('20170222134109'), -('20180204153242'), -('20181020114000'), -('20181031113522'), -('20190518115041'), -('20190623093642'), -('20190702193519'), -('20190716173946'), -('20191120140058'), -('20201004105659'), -('20201006213836'), -('20201006220807'), -('20201214144017'), -('20210510083027'), -('20210510083028'), -('20210511104518'), -('20211216185316'), -('20220201183346'), -('20220223140543'), -('20230816135800'), -('20230825162137'), -('20230830115219'), -('20230830115220'), -('20231007141103'), -('21'), -('22'), -('23'), -('24'), -('25'), -('26'), -('27'), -('28'), -('29'), -('3'), -('30'), -('31'), -('32'), -('33'), -('34'), -('35'), -('36'), -('37'), -('38'), -('39'), -('4'), -('40'), -('41'), -('42'), -('43'), -('44'), -('45'), -('46'), -('47'), -('48'), -('49'), -('5'), -('50'), -('51'), -('52'), -('53'), -('54'), -('55'), -('56'), -('57'), -('6'), -('7'), +('9'), ('8'), -('9'); +('7'), +('6'), +('57'), +('56'), +('55'), +('54'), +('53'), +('52'), +('51'), +('50'), +('5'), +('49'), +('48'), +('47'), +('46'), +('45'), +('44'), +('43'), +('42'), +('41'), +('40'), +('4'), +('39'), +('38'), +('37'), +('36'), +('35'), +('34'), +('33'), +('32'), +('31'), +('30'), +('3'), +('29'), +('28'), +('27'), +('26'), +('25'), +('24'), +('23'), +('22'), +('21'), +('20231101222146'), +('20231029151516'), +('20231010194809'), +('20231007141103'), +('20230830115220'), +('20230830115219'), +('20230825162137'), +('20230816135800'), +('20220223140543'), +('20220201183346'), +('20211216185316'), +('20210511104518'), +('20210510083028'), +('20210510083027'), +('20201214144017'), +('20201006220807'), +('20201006213836'), +('20201004105659'), +('20191120140058'), +('20190716173946'), +('20190702193519'), +('20190623093642'), +('20190518115041'), +('20181031113522'), +('20181020114000'), +('20180204153242'), +('20170222134109'), +('20161011010929'), +('20161002153425'), +('20160822153055'), +('20150818224516'), +('20150222101847'), +('20150111192335'), +('20150110152606'), +('20140519141742'), +('20140507110937'), +('20140210003018'), +('20140117185510'), +('20140115192822'), +('20131212124700'), +('20130328184137'), +('20121203124841'), +('20121202155309'), +('20121119165817'), +('20121012044047'), +('20121005195010'), +('20120808231205'), +('20120404205604'), +('20120328090602'), +('20120318201948'), +('20120219161649'), +('20120214210114'), +('20120208194454'), +('20120208122334'), +('20120123184321'), +('20111212183945'), +('20111116184519'), +('20110925112722'), +('20110521142405'), +('20110508145337'), +('20110322001319'), +('20101114011429'), +('20100910084426'), +('20100516124737'), +('20100513171259'), +('20'), +('2'), +('19'), +('18'), +('17'), +('16'), +('15'), +('14'), +('13'), +('12'), +('11'), +('10'), +('1');