Commits

bryanhelmig committed fe6125b

added whitelist

Comments (0)

Files changed (3)

docs/queryset_cache.rst

 value of ``0`` will work differently on different backends and might cause 
 Johnny to never cache anything.
 
+``JOHNNY_TABLE_WHITELIST``, default "[]", is a user defined tuple that 
+contains table names for exclusive inclusion in the cache. If you provide this
+setting, the ``MAN_IN_BLACKLIST`` (and ``JOHNNY_TABLE_BLACKLIST``) settings 
+are ignored.
+
 ``MAN_IN_BLACKLIST`` is a user defined tuple that contains table names to
 exclude from the QuerySet Cache.  If you have no sense of humor, or want your
 settings file to be understandable, you can use the alias
 
 local = localstore.LocalStore()
 
-def blacklist_match(*tables):
-    """Returns True if a set of tables is in the blacklist, False otherwise."""
-    # XXX: When using a blacklist, this has to be done EVERY query;
+def disallowed_table(*tables):
+    """Returns True if a set of tables is in the blacklist or, if a whitelist is set,
+    any of the tables is not in the whitelist. False otherwise."""
+    # XXX: When using a black or white list, this has to be done EVERY query;
     # It'd be nice to make this as fast as possible.  In general, queries
     # should have relatively few tables involved, and I don't imagine that
     # blacklists would grow very vast.  The fastest i've been able to come
     # up with is to pre-create a blacklist set and use intersect.
-    return bool(settings.BLACKLIST.intersection(tables))
+    return not bool(settings.WHITELIST.issuperset(tables)) if settings.WHITELIST\
+        else bool(settings.BLACKLIST.intersection(tables))
 
 def get_backend(cache_backend=None, keyhandler=None, keygen=None):
     """Get's a QueryCacheBackend object for the given options and current
             # check the blacklist for any of the involved tables;  if it's not
             # there, then look for the value in the cache.
             tables = get_tables_for_query(cls.query)
-            if tables and not blacklist_match(*tables):
+            if tables and not disallowed_table(*tables):
                 gen_key = self.keyhandler.get_generation(*tables, **{'db':db})
                 key = self.keyhandler.sql_key(gen_key, sql, params, cls.get_ordering(), result_type, db)
                 val = self.cache_backend.get(key, None, db)
             tables = get_tables_for_query11(cls)
             # check the blacklist for any of the involved tables;  if it's not
             # there, then look for the value in the cache.
-            if tables and not blacklist_match(*tables):
+            if tables and not disallowed_table(*tables):
                 gen_key = self.keyhandler.get_generation(*tables)
                 key = self.keyhandler.sql_key(gen_key, sql, params,
                         cls.ordering_aliases, result_type)

johnny/settings.py

             getattr(settings, 'JOHNNY_TABLE_BLACKLIST', []))
 BLACKLIST = set(BLACKLIST)
 
+WHITELIST = set(getattr(settings, 'JOHNNY_TABLE_WHITELIST', []))
+
 MIDDLEWARE_KEY_PREFIX = getattr(settings, 'JOHNNY_MIDDLEWARE_KEY_PREFIX', 'jc')
 
 MIDDLEWARE_SECONDS = getattr(settings, 'JOHNNY_MIDDLEWARE_SECONDS', 0)