diff --git a/app/scodoc/sco_cache.py b/app/scodoc/sco_cache.py index 4c9960df..e31b6a18 100644 --- a/app/scodoc/sco_cache.py +++ b/app/scodoc/sco_cache.py @@ -121,6 +121,33 @@ class ScoDocCache: for oid in oids: cls.delete(oid) + @classmethod + def delete_pattern(cls, pattern: str, std_prefix=True) -> int: + """Delete all keys matching pattern. + The pattern starts with flask_cache_. + If std_prefix is true (default), the prefix is added + to the given pattern. + Examples: + 'TABASSI_tableau-etud-1234:*' + Or, with std_prefix false, 'flask_cache_RT_TABASSI_tableau-etud-1234:*' + + Returns number of keys deleted. + """ + # see https://stackoverflow.com/questions/36708461/flask-cache-list-keys-based-on-a-pattern + assert CACHE.cache.__class__.__name__ == "RedisCache" # Redis specific + import redis + + if std_prefix: + pattern = "flask_cache_" + g.scodoc_dept + "_" + cls.prefix + "_" + pattern + + r = redis.Redis() + count = 0 + for key in r.scan_iter(pattern): + log(f"{cls.__name__}.delete_pattern({key})") + r.delete(key) + count += 1 + return count + class EvaluationCache(ScoDocCache): """Cache for evaluations. diff --git a/sco_version.py b/sco_version.py index 53da13f9..7b986ac6 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.6.77" +SCOVERSION = "9.6.78" SCONAME = "ScoDoc" diff --git a/tests/unit/test_caches.py b/tests/unit/test_caches.py index 3a4882d7..0e3766ba 100644 --- a/tests/unit/test_caches.py +++ b/tests/unit/test_caches.py @@ -48,6 +48,10 @@ def test_notes_table(test_client): # XXX A REVOIR POUR TESTER RES TODO formsemestre_id = sem["formsemestre_id"] nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) assert sco_cache.ResultatsSemestreCache.get(formsemestre_id) + # Efface les semestres + sco_cache.ResultatsSemestreCache.delete_pattern("*") + for sem in sems[:10]: + assert sco_cache.ResultatsSemestreCache.get(formsemestre_id) is None def test_cache_evaluations(test_client):