From: Michael Tremer Date: Mon, 5 Jan 2026 10:08:54 +0000 (+0000) Subject: lists: Store a stats history X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fd9026828a11c9d2d8abe826a5ecb65ca64741b;p=dbl.git lists: Store a stats history Signed-off-by: Michael Tremer --- diff --git a/src/database.sql b/src/database.sql index 94146f1..f1d3294 100644 --- a/src/database.sql +++ b/src/database.sql @@ -2,7 +2,7 @@ -- PostgreSQL database dump -- -\restrict pXUPUyLkgUWquVqcqOb0Ffu3EcVPJGROwmyXhgPEICcDG5af5bsnhpnMAO9PMhG +\restrict rL7JZX9lefDYCij1ck1YZ9zBYKQONa1UgbdrSppmH7VGwDI2usPtcuRDMxQJwsl -- Dumped from database version 17.6 (Debian 17.6-0+deb13u1) -- Dumped by pg_dump version 17.6 (Debian 17.6-0+deb13u1) @@ -109,6 +109,38 @@ CREATE SEQUENCE public.domains_id_seq ALTER SEQUENCE public.domains_id_seq OWNED BY public.domains.id; +-- +-- Name: list_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.list_stats ( + id integer NOT NULL, + list_id integer NOT NULL, + ts timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + total_domains integer NOT NULL +); + + +-- +-- Name: list_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.list_stats_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: list_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.list_stats_id_seq OWNED BY public.list_stats.id; + + -- -- Name: lists; Type: TABLE; Schema: public; Owner: - -- @@ -287,6 +319,13 @@ ALTER TABLE ONLY public.api_keys ALTER COLUMN id SET DEFAULT nextval('public.api ALTER TABLE ONLY public.domains ALTER COLUMN id SET DEFAULT nextval('public.domains_id_seq'::regclass); +-- +-- Name: list_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.list_stats ALTER COLUMN id SET DEFAULT nextval('public.list_stats_id_seq'::regclass); + + -- -- Name: lists id; Type: DEFAULT; Schema: public; Owner: - -- @@ -339,6 +378,14 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT domains_pkey PRIMARY KEY (id); +-- +-- Name: list_stats list_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.list_stats + ADD CONSTRAINT list_stats_pkey PRIMARY KEY (id); + + -- -- Name: lists lists_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -435,6 +482,13 @@ CREATE UNIQUE INDEX domains_unique ON public.domains USING btree (list_id, name) CREATE INDEX domains_updated_at ON public.domains USING btree (source_id, updated_at) WHERE (removed_at IS NULL); +-- +-- Name: list_stats_unique; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX list_stats_unique ON public.list_stats USING btree (list_id, ts DESC); + + -- -- Name: lists_unique; Type: INDEX; Schema: public; Owner: - -- @@ -495,6 +549,14 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT domains_source_id FOREIGN KEY (source_id) REFERENCES public.sources(id); +-- +-- Name: list_stats list_stats_list_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.list_stats + ADD CONSTRAINT list_stats_list_id FOREIGN KEY (list_id) REFERENCES public.lists(id); + + -- -- Name: reports reports_list_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -523,5 +585,5 @@ ALTER TABLE ONLY public.sources -- PostgreSQL database dump complete -- -\unrestrict pXUPUyLkgUWquVqcqOb0Ffu3EcVPJGROwmyXhgPEICcDG5af5bsnhpnMAO9PMhG +\unrestrict rL7JZX9lefDYCij1ck1YZ9zBYKQONa1UgbdrSppmH7VGwDI2usPtcuRDMxQJwsl diff --git a/src/dnsbl/lists.py b/src/dnsbl/lists.py index 324ab9f..2fcfb34 100644 --- a/src/dnsbl/lists.py +++ b/src/dnsbl/lists.py @@ -403,6 +403,13 @@ class List(sqlmodel.SQLModel, database.BackendMixin, table=True): # Store the number of total domains self.total_domains = self.backend.db.fetch_one(stmt) + # Store the stats history + self.backend.db.insert( + ListStats, + list = self, + total_domains = self.total_domains, + ) + # Export! def export(self, f, format, **kwargs): @@ -641,3 +648,24 @@ class List(sqlmodel.SQLModel, database.BackendMixin, table=True): ) return self.backend.db.select(stmt) + + +class ListStats(sqlmodel.SQLModel, table=True): + __tablename__ = "list_stats" + + # ID + id: int = sqlmodel.Field(primary_key=True, exclude=True) + + # List ID + list_id: int = sqlmodel.Field(foreign_key="lists.id", exclude=True) + + # List + list: "List" = sqlmodel.Relationship() + + # Timestamp + ts: datetime.datetime = sqlmodel.Field( + sa_column_kwargs = { "server_default" : sqlmodel.text("CURRENT_TIMESTAMP") }, + ) + + # Total Domains + total_domains: int