From ceea59b34e2ea9ec20c15cfe404acb5976071323 Mon Sep 17 00:00:00 2001
From: "Antoine R. Dumont (@ardumont)" <ardumont@softwareheritage.org>
Date: Thu, 24 Aug 2023 14:08:56 +0200
Subject: [PATCH] db: Allow to retrieve a configuration per name and optional
 datastore

To avoid returning only the first one when multiple configuration with the same name
exists for different backend to scrub.

Refs. swh/devel/swh-scrubber#4696
---
 swh/scrubber/db.py            | 22 ++++++++++++----------
 swh/scrubber/tests/test_db.py | 27 ++++++++++++++++++++++++++-
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/swh/scrubber/db.py b/swh/scrubber/db.py
index b34d154..3de6472 100644
--- a/swh/scrubber/db.py
+++ b/swh/scrubber/db.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2022  The Software Heritage developers
+# Copyright (C) 2022-2023  The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU General Public License version 3, or any later version
 # See top-level LICENSE file for more information
@@ -201,18 +201,20 @@ class ScrubberDb(BaseDb):
     def config_get_by_name(
         self,
         name: str,
+        datastore: Optional[int] = None,
     ) -> Optional[int]:
         """Get the configuration entry for given name, if any"""
+        query_parts = ["SELECT id FROM check_config WHERE "]
+        where_parts = [" name = %s "]
+        query_params = [name]
+        if datastore:
+            where_parts.append(" datastore = %s ")
+            query_params.append(str(datastore))
+
+        query_parts.append(" AND ".join(where_parts))
+        query = "\n".join(query_parts)
         with self.transaction() as cur:
-            cur.execute(
-                """
-                SELECT id
-                    FROM check_config
-                    WHERE
-                        name=%s
-                """,
-                (name,),
-            )
+            cur.execute(query, query_params)
             if cur.rowcount:
                 res = cur.fetchone()
                 if res:
diff --git a/swh/scrubber/tests/test_db.py b/swh/scrubber/tests/test_db.py
index e05eea9..4af7430 100644
--- a/swh/scrubber/tests/test_db.py
+++ b/swh/scrubber/tests/test_db.py
@@ -50,17 +50,42 @@ def test_config_get(datastore: Datastore, scrubber_db: ScrubberDb, config_id: in
         scrubber_db.config_get(cfg3 + 1)
 
 
+@pytest.fixture
+def datastore2():
+    return Datastore(package="storage", cls="postgresql", instance="service=swh-test-2")
+
+
+@pytest.fixture
+def config_id2(scrubber_db, datastore2):
+    return scrubber_db.config_add(
+        f"cfg_{OBJECT_TYPE}_{NB_PARTITIONS}", datastore2, OBJECT_TYPE, NB_PARTITIONS
+    )
+
+
 def test_checked_config_get_by_name(
-    datastore: Datastore, scrubber_db: ScrubberDb, config_id: int
+    datastore: Datastore,
+    datastore2: Datastore,
+    config_id: int,
+    config_id2: int,
+    scrubber_db: ScrubberDb,
 ):
+    assert datastore == scrubber_db.datastore_get(config_id)
+    assert datastore2 == scrubber_db.datastore_get(config_id2)
+
     cfg2 = scrubber_db.config_add("cfg2", datastore, ObjectType.SNAPSHOT, 42)
+    cfg2prime = scrubber_db.config_add("cfg2", datastore2, ObjectType.SNAPSHOT, 42)
     cfg3 = scrubber_db.config_add("cfg3", datastore, ObjectType.SNAPSHOT, 43)
 
     assert scrubber_db.config_get_by_name("cfg2") == cfg2
     assert scrubber_db.config_get_by_name("cfg3") == cfg3
 
+    # Check for unknown configuration
     assert scrubber_db.config_get_by_name("unknown config") is None
 
+    # Check for duplicated configurations
+    assert scrubber_db.config_get_by_name("cfg2", config_id) == cfg2
+    assert scrubber_db.config_get_by_name("cfg2", config_id2) == cfg2prime
+
 
 def test_datastore_get(datastore: Datastore, scrubber_db: ScrubberDb, config_id: int):
     assert scrubber_db.datastore_get(1) == datastore
-- 
GitLab