]> git.ipfire.org Git - pbs.git/commitdiff
builds: Refactor watchers
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 12 Oct 2022 18:09:52 +0000 (18:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 12 Oct 2022 18:09:52 +0000 (18:09 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/builds.py
src/database.sql
tests/build.py

index 252c4c4247e184b07ec57c42d4c2f5b053c8ed34..c673cf8bb4475df40e56b86df06c1da0a2ebcd1f 100644 (file)
@@ -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):
index 9e5eb7a571ad7792779ae0ec12efec2fd13e174b..97a7c17e6c9f5fd16f90089586de01cfd3ea572d 100644 (file)
@@ -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: -
 --
index 8571622023a6636fe8583f043ce3ed128c9ffdd9..dbe6368583b9d97c80ebd4c44d325552c821b537 100755 (executable)
@@ -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__":