diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-03-29 00:00:49 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-03-29 00:00:49 +0000 |
commit | c4955c05a3ab40d53c83982da612e746c662640d (patch) | |
tree | c979c566711917679c9fa5d31b6dbcdb1c76eb34 /lib/sqlalchemy/util.py | |
parent | 30020880d90ee2f983b8e6bfb1624349209dd8b0 (diff) | |
download | sqlalchemy-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.py | 58 |
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) |