From: Mike Bayer Date: Wed, 2 May 2007 23:51:01 +0000 (+0000) Subject: - Aliasizer removed. hooray ! X-Git-Tag: rel_0_3_8~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=612c49f545b5374be45dbb4da21a5d708ebb894f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Aliasizer removed. hooray ! - ClauseVisitor has handy chain() method. --- diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 4e5cf522d4..033d0cac14 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -363,27 +363,31 @@ class EagerLoader(AbstractRelationLoader): self.target = eagerloader.select_table self.eagertarget = eagerloader.select_table.alias(self._aliashash("/target")) self.extra_cols = {} - + if eagerloader.secondary: self.eagersecondary = eagerloader.secondary.alias(self._aliashash("/secondary")) - self.aliasizer = sql_util.Aliasizer(eagerloader.target, eagerloader.secondary, aliases={ - eagerloader.target:self.eagertarget, - eagerloader.secondary:self.eagersecondary - }) + if parentclauses is not None: + aliasizer = sql_util.ClauseAdapter(self.eagertarget).\ + chain(sql_util.ClauseAdapter(self.eagersecondary)).\ + chain(sql_util.ClauseAdapter(parentclauses.eagertarget)) + else: + aliasizer = sql_util.ClauseAdapter(self.eagertarget).\ + chain(sql_util.ClauseAdapter(self.eagersecondary)) self.eagersecondaryjoin = eagerloader.polymorphic_secondaryjoin.copy_container() - self.aliasizer.traverse(self.eagersecondaryjoin) + aliasizer.traverse(self.eagersecondaryjoin) self.eagerprimary = eagerloader.polymorphic_primaryjoin.copy_container() - self.aliasizer.traverse(self.eagerprimary) + aliasizer.traverse(self.eagerprimary) else: self.eagerprimary = eagerloader.polymorphic_primaryjoin.copy_container() - self.aliasizer = sql_util.Aliasizer(self.target, aliases={self.target:self.eagertarget}) - self.aliasizer.traverse(self.eagerprimary) - - if parentclauses is not None: - parentclauses.aliasizer.traverse(self.eagerprimary) + if parentclauses is not None: + aliasizer = sql_util.ClauseAdapter(self.eagertarget) + aliasizer.chain(sql_util.ClauseAdapter(parentclauses.eagertarget, exclude=eagerloader.parent_property.remote_side)) + else: + aliasizer = sql_util.ClauseAdapter(self.eagertarget) + aliasizer.traverse(self.eagerprimary) if eagerloader.order_by: - self.eager_order_by = self._aliasize_orderby(eagerloader.order_by) + self.eager_order_by = sql_util.ClauseAdapter(self.eagertarget).copy_and_process(util.to_list(eagerloader.order_by)) else: self.eager_order_by = None @@ -413,14 +417,6 @@ class EagerLoader(AbstractRelationLoader): # use the first 4 digits of an MD5 hash return "anon_" + util.hash(self.id + extra)[0:4] - def _aliasize_orderby(self, orderby, copy=True): - if copy: - return self.aliasizer.copy_and_process(util.to_list(orderby)) - else: - orderby = util.to_list(orderby) - self.aliasizer.process_list(orderby) - return orderby - def _create_decorator_row(self): class EagerRowAdapter(object): def __init__(self, row): diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index ab64d65287..fe987cc11e 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -828,7 +828,21 @@ class ClauseVisitor(object): def traverse(self, obj): for n in obj.get_children(**self.__traverse_options__): self.traverse(n) - obj.accept_visitor(self) + v = self + while v is not None: + obj.accept_visitor(v) + v = getattr(v, '_next', None) + + def chain(self, visitor): + """'chain' an additional ClauseVisitor onto this ClauseVisitor. + + the chained visitor will receive all visit events after this one.""" + tail = self + while getattr(tail, '_next', None) is not None: + tail = tail._next + tail._next = visitor + return self + def visit_column(self, column): pass def visit_table(self, table): diff --git a/lib/sqlalchemy/sql_util.py b/lib/sqlalchemy/sql_util.py index 1d185bbc5f..dcd19f8915 100644 --- a/lib/sqlalchemy/sql_util.py +++ b/lib/sqlalchemy/sql_util.py @@ -151,31 +151,8 @@ class AbstractClauseProcessor(sql.NoColumnVisitor): if elem is not None: binary.right = elem -class Aliasizer(AbstractClauseProcessor): - """Convert a table instance within an expression to be an alias of that table.""" - - def __init__(self, *tables, **kwargs): - self.tables = {} - self.aliases = kwargs.get('aliases', {}) - for t in tables: - self.tables[t] = t - if not self.aliases.has_key(t): - self.aliases[t] = sql.alias(t) - if isinstance(t, sql.Join): - for t2 in t.columns: - self.tables[t2.table] = t2 - self.aliases[t2.table] = self.aliases[t] - self.binary = None - - def get_alias(self, table): - return self.aliases[table] - - def convert_element(self, elem): - if isinstance(elem, sql.ColumnElement) and hasattr(elem, 'table') and self.tables.has_key(elem.table): - return self.get_alias(elem.table).corresponding_column(elem) - else: - return None - + # TODO: visit_select(). + class ClauseAdapter(AbstractClauseProcessor): """Given a clause (like as in a WHERE criterion), locate columns which are embedded within a given selectable, and changes those