From: Michael Tremer Date: Wed, 12 Oct 2022 18:09:52 +0000 (+0000) Subject: builds: Refactor watchers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c6380e152a87474aed8be3ad2ac6829b9ba305f;p=pbs.git builds: Refactor watchers Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/builds.py b/src/buildservice/builds.py index 252c4c42..c673cf8b 100644 --- a/src/buildservice/builds.py +++ b/src/buildservice/builds.py @@ -674,23 +674,70 @@ class Build(base.DataObject): return entries - ## Watchers stuff + ## Watchers - def get_watchers(self): - query = self.db.query("SELECT DISTINCT users.id AS id FROM builds_watchers \ - JOIN users ON builds_watchers.user_id = users.id \ - WHERE builds_watchers.build_id = %s AND NOT users.deleted = 'Y' \ - AND users.activated = 'Y' ORDER BY users.id", self.id) + @lazy_property + def watchers(self): + users = self.backend.users._get_users(""" + SELECT + users.* + FROM + build_watchers + LEFT JOIN + users ON build_watchers.user_id = users.id + WHERE + users.deleted IS FALSE + AND + build_watchers.build_id = %s + AND + build_watchers.deleted_at IS NULL + """, self.id, + ) - return [users.User(self.backend, u.id) for u in query] + return set(users) def add_watcher(self, user): - # Don't add a user twice. - if user in self.get_watchers(): - return + """ + Adds a watcher to this build + """ + self.db.execute(""" + INSERT INTO + build_watchers( + build_id, + user_id + ) + VALUES( + %s, %s + ) + ON CONFLICT + (build_id, user_id) WHERE deleted_at IS NULL + DO NOTHING + """, self.id, user, + ) + + # Add to cache + self.watchers.add(user) + + def remove_watcher(self, user): + """ + Removes a watcher from this build + """ + self.db.execute(""" + UPDATE + build_watchers + SET + deleted_at = CURRENT_TIMESTAMP + WHERE + build_id = %s + AND + user_id = %s + AND + deleted_at IS NULL + """, self.id, user, + ) - self.db.execute("INSERT INTO builds_watchers(build_id, user_id) \ - VALUES(%s, %s)", self.id, user.id) + # Remove from cache + self.watchers.remove(user) @property def message_recipients(self): diff --git a/src/database.sql b/src/database.sql index 9e5eb7a5..97a7c17e 100644 --- a/src/database.sql +++ b/src/database.sql @@ -46,6 +46,18 @@ CREATE TABLE public.build_packages ( ); +-- +-- Name: build_watchers; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.build_watchers ( + build_id integer NOT NULL, + user_id integer NOT NULL, + added_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + deleted_at timestamp without time zone +); + + -- -- Name: builder_stats; Type: TABLE; Schema: public; Owner: - -- @@ -303,36 +315,6 @@ CREATE SEQUENCE public.builds_id_seq ALTER SEQUENCE public.builds_id_seq OWNED BY public.builds.id; --- --- Name: builds_watchers; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.builds_watchers ( - id integer NOT NULL, - build_id integer NOT NULL, - user_id integer NOT NULL -); - - --- --- Name: builds_watchers_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.builds_watchers_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: builds_watchers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.builds_watchers_id_seq OWNED BY public.builds_watchers.id; - - -- -- Name: distributions; Type: TABLE; Schema: public; Owner: - -- @@ -1290,13 +1272,6 @@ ALTER TABLE ONLY public.builds_comments ALTER COLUMN id SET DEFAULT nextval('pub ALTER TABLE ONLY public.builds_history ALTER COLUMN id SET DEFAULT nextval('public.builds_history_id_seq'::regclass); --- --- Name: builds_watchers id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.builds_watchers ALTER COLUMN id SET DEFAULT nextval('public.builds_watchers_id_seq'::regclass); - - -- -- Name: distributions id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1493,14 +1468,6 @@ ALTER TABLE ONLY public.builds_history ADD CONSTRAINT idx_2198027_primary PRIMARY KEY (id); --- --- Name: builds_watchers idx_2198033_primary; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.builds_watchers - ADD CONSTRAINT idx_2198033_primary PRIMARY KEY (id); - - -- -- Name: images_types idx_2198057_primary; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -1684,6 +1651,13 @@ ALTER TABLE ONLY public.uploads CREATE INDEX build_packages_build_id ON public.build_packages USING btree (build_id); +-- +-- Name: build_watchers_unique; Type: INDEX; Schema: public; Owner: - +-- + +CREATE UNIQUE INDEX build_watchers_unique ON public.build_watchers USING btree (build_id, user_id) WHERE (deleted_at IS NULL); + + -- -- Name: builders_name; Type: INDEX; Schema: public; Owner: - -- @@ -1712,13 +1686,6 @@ CREATE INDEX builds_pkg_id ON public.builds USING btree (pkg_id) WHERE (deleted CREATE UNIQUE INDEX builds_uuid ON public.builds USING btree (uuid) WHERE (deleted IS FALSE); --- --- Name: builds_watchers_build_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX builds_watchers_build_id ON public.builds_watchers USING btree (build_id); - - -- -- Name: distributions_slug; Type: INDEX; Schema: public; Owner: - -- @@ -2015,6 +1982,22 @@ ALTER TABLE ONLY public.build_packages ADD CONSTRAINT build_packages_package_id FOREIGN KEY (package_id) REFERENCES public.packages(id); +-- +-- Name: build_watchers build_watchers_build_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.build_watchers + ADD CONSTRAINT build_watchers_build_id FOREIGN KEY (build_id) REFERENCES public.builds(id); + + +-- +-- Name: build_watchers build_watchers_user_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.build_watchers + ADD CONSTRAINT build_watchers_user_id FOREIGN KEY (user_id) REFERENCES public.users(id); + + -- -- Name: builder_stats builder_stats_builder_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -2095,22 +2078,6 @@ ALTER TABLE ONLY public.builds ADD CONSTRAINT builds_pkg_id FOREIGN KEY (pkg_id) REFERENCES public.packages(id); --- --- Name: builds_watchers builds_watchers_build_id; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.builds_watchers - ADD CONSTRAINT builds_watchers_build_id FOREIGN KEY (build_id) REFERENCES public.builds(id); - - --- --- Name: builds_watchers builds_watchers_user_id; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.builds_watchers - ADD CONSTRAINT builds_watchers_user_id FOREIGN KEY (user_id) REFERENCES public.users(id); - - -- -- Name: filelists filelists_pkg_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- diff --git a/tests/build.py b/tests/build.py index 85716220..dbe63685 100755 --- a/tests/build.py +++ b/tests/build.py @@ -41,7 +41,7 @@ class BuildTestCase(test.TestCase): async def test_watchers(self): """ - Tests whether we can add a watcher to a build + Tests whether we can add and remove a watcher to a build """ path = self.source_path("tests/data/beep-1.3-2.ip3.src.pfm") @@ -54,7 +54,14 @@ class BuildTestCase(test.TestCase): build.add_watcher(self.user) # Check if the watcher has been added - self.assertIn(self.user, build.get_watchers()) + self.assertIn(self.user, build.watchers) + + # Remove the default user as watcher + with self.db.transaction(): + build.remove_watcher(self.user) + + # Check if the watcher has been removed + self.assertNotIn(self.user, build.watchers) if __name__ == "__main__":