[CLEAN] expression.py: table_aliases now holds a list of aliases (names), and table_aliases_mapping does the mapping between a name and a table. The parsing algorithm now uses some accessors instead of directly accessing the data structures.

bzr revid: tde@openerp.com-20121127151113-zregov1i2isoll9z
This commit is contained in:
Thibault Delavallée 2012-11-27 16:11:13 +01:00
parent c1c5a85231
commit e147a5483f
1 changed files with 36 additions and 11 deletions

View File

@ -371,28 +371,56 @@ class expression(object):
:attr dict leaf_to_table: used to store the table to use for the :attr dict leaf_to_table: used to store the table to use for the
sql generation, according to the domain leaf. sql generation, according to the domain leaf.
structure: { [leaf index]: table object } structure: { [leaf index]: table object }
:attr set table_aliases: set of aliases. :attr set table_aliases: set of aliases. Previously this attribute
was a set of table objects; now that joins generation is included
into the expression parsing, it holds aliases, and a mapping
exist linking aliases to tables.
:attr dict table_aliases_mapping: mapping alias -> table object
:attr list joins: list of join conditions, such as (res_country_state."id" = res_partner."state_id") :attr list joins: list of join conditions, such as (res_country_state."id" = res_partner."state_id")
:attr root_table: root table, set by parse() :attr root_table: root table, set by parse()
""" """
self.has_unaccent = openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent self.has_unaccent = openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent
self.leaf_to_table = {} self.leaf_to_table = {}
self.table_aliases = set() self.table_aliases = set()
self.table_aliases_mapping = {}
self.joins = [] self.joins = []
self.root_table = None self.root_table = None
# assign self.__exp with the normalized, parsed domain. # assign self.__exp with the normalized, parsed domain.
self.parse(cr, uid, distribute_not(normalize(exp)), table, context) self.parse(cr, uid, distribute_not(normalize(exp)), table, context)
# TODO used only for osv_memory # TDE note: this seems not to be used anymore, commenting
@property # # TODO used only for osv_memory
def exp(self): # @property
return self.__exp[:] # def exp(self):
# return self.__exp[:]
def _has_table_alias(self, alias):
return alias in self.table_aliases
def _get_table_from_alias(self, alias):
return self.table_aliases_mapping.get(alias)
def _get_full_alias(self, alias):
if not self._get_table_from_alias(alias):
return False
return '%s as %s' % (self._get_table_from_alias(alias)._table, alias)
def _add_table_alias(self, alias, table):
if not self._has_table_alias(alias):
self.table_aliases.add(alias)
self.table_aliases_mapping[alias] = table
else:
raise ValueError("Already existing alias %s for table %s, trying to set it for table %s" % (alias, self._get_table_from_alias(alias)._table, table._table))
def get_tables(self):
""" Returns the list of tables for SQL queries, like select from ... """
return ['"%s"' % item for item in self.table_aliases]
def parse(self, cr, uid, exp, table, context): def parse(self, cr, uid, exp, table, context):
""" transform the leaves of the expression """ """ transform the leaves of the expression """
self.__exp = exp self.__exp = exp
self.root_table = table self.root_table = table
self.table_aliases.add(table) self._add_table_alias(table._table, table)
def child_of_domain(left, ids, left_model, parent=None, prefix=''): def child_of_domain(left, ids, left_model, parent=None, prefix=''):
"""Returns a domain implementing the child_of operator for [(left,child_of,ids)], """Returns a domain implementing the child_of operator for [(left,child_of,ids)],
@ -460,9 +488,9 @@ class expression(object):
self.leaf_to_table[i] = working_table self.leaf_to_table[i] = working_table
break break
next_table = working_table.pool.get(working_table._inherit_fields[field_path[0]][0]) next_table = working_table.pool.get(working_table._inherit_fields[field_path[0]][0])
if next_table not in self.table_aliases: if not self._has_table_alias(next_table._table):
self.joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name])) self.joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name]))
self.table_aliases.add(next_table) self._add_table_alias(next_table._table, next_table)
working_table = next_table working_table = next_table
# Or (try to) directly extract the field. # Or (try to) directly extract the field.
else: else:
@ -836,7 +864,4 @@ class expression(object):
query = '(%s) AND %s' % (joins, query) query = '(%s) AND %s' % (joins, query)
return (query, flatten(params)) return (query, flatten(params))
def get_tables(self):
return ['"%s"' % t._table for t in self.table_aliases]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: