summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/util.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-03-29 00:00:49 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-03-29 00:00:49 +0000
commitc4955c05a3ab40d53c83982da612e746c662640d (patch)
treec979c566711917679c9fa5d31b6dbcdb1c76eb34 /lib/sqlalchemy/util.py
parent30020880d90ee2f983b8e6bfb1624349209dd8b0 (diff)
downloadsqlalchemy-c4955c05a3ab40d53c83982da612e746c662640d.tar.gz
- merged with_polymorphic branch, which was merged with query_columns branch
- removes everything to do with select_table, which remains as a keyword argument synonymous with with_polymorphic=('*', select_table). - all "polymorphic" selectables find their way to Query by way of _set_select_from() now, so that all joins/aliasing/eager loads/etc. is handled consistently. Mapper has methods for producing polymorphic selectables so that Query and eagerloaders alike can get to them. - row aliasing simplified, so that they don't need to nest. they only need the source selectable and adapt to whatever incoming columns they get. - Query is more egalitarian about mappers/columns now. Still has a strong sense of "entity zero", but also introduces new unpublished/experimental _values() method which sets up a columns-only query. - Query.order_by() and Query.group_by() take *args now (also still take a list, will likely deprecate in 0.5). May want to do this for select() as well. - the existing "check for False discriminiator" "fix" was not working completely, added coverage - orphan detection was broken when the target object was a subclass of the mapper with the orphaned relation, fixed that too.
Diffstat (limited to 'lib/sqlalchemy/util.py')
-rw-r--r--lib/sqlalchemy/util.py58
1 files changed, 57 insertions, 1 deletions
diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py
index af77d792e..90332fdc0 100644
--- a/lib/sqlalchemy/util.py
+++ b/lib/sqlalchemy/util.py
@@ -163,6 +163,23 @@ except ImportError:
return 'defaultdict(%s, %s)' % (self.default_factory,
dict.__repr__(self))
+try:
+ from collections import deque
+except ImportError:
+ class deque(list):
+ def appendleft(self, x):
+ self.insert(0, x)
+
+ def extendleft(self, iterable):
+ self[0:0] = list(iterable)
+
+ def popleft(self):
+ return self.pop(0)
+
+ def rotate(self, n):
+ for i in xrange(n):
+ self.appendleft(self.pop())
+
def to_list(x, default=None):
if x is None:
return default
@@ -171,6 +188,16 @@ def to_list(x, default=None):
else:
return x
+def starargs_as_list(*args):
+ """interpret the given *args as either a list of *args,
+ or detect if it's a single list and return that.
+
+ """
+ if len(args) == 1:
+ return to_list(args[0], [])
+ else:
+ return list(args)
+
def to_set(x):
if x is None:
return Set()
@@ -1018,7 +1045,36 @@ class symbol(object):
return sym
finally:
symbol._lock.release()
-
+
+def conditional_cache_decorator(func):
+ """apply conditional caching to the return value of a function."""
+
+ return cache_decorator(func, conditional=True)
+
+def cache_decorator(func, conditional=False):
+ """apply caching to the return value of a function."""
+
+ name = '_cached_' + func.__name__
+
+ def do_with_cache(self, *args, **kwargs):
+ if conditional:
+ cache = kwargs.pop('cache', False)
+ if not cache:
+ return func(self, *args, **kwargs)
+ try:
+ return getattr(self, name)
+ except AttributeError:
+ value = func(self, *args, **kwargs)
+ setattr(self, name, value)
+ return value
+ return do_with_cache
+
+def reset_cached(instance, name):
+ try:
+ delattr(instance, '_cached_' + name)
+ except AttributeError:
+ pass
+
def warn(msg):
if isinstance(msg, basestring):
warnings.warn(msg, exceptions.SAWarning, stacklevel=3)