summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-11-26 02:36:27 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-11-26 02:36:27 +0000
commitb6b0130646b677e507d2fb461829ed5d72658000 (patch)
treefe0acf9855ba4053cc7594e8e5b465721aad66c6 /lib/sqlalchemy/sql.py
parentd9f3b2a06370a88676afa91ff3cd73722ad38543 (diff)
downloadsqlalchemy-b6b0130646b677e507d2fb461829ed5d72658000.tar.gz
- made kwargs parsing to Table strict; removed various obsoluete "redefine=True" kw's from the unit tests
- documented instance variables in ANSICompiler - fixed [ticket:120], adds "inline_params" set to ANSICompiler which DefaultDialect picks up on when determining defaults. added unittests to query.py - additionally fixed up the behavior of the "values" parameter on _Insert/_Update - more cleanup to sql/Select - more succinct organization of FROM clauses, removed silly _process_from_dict methods and JoinMarker object
Diffstat (limited to 'lib/sqlalchemy/sql.py')
-rw-r--r--lib/sqlalchemy/sql.py80
1 files changed, 30 insertions, 50 deletions
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index 8605d5c0c..b3d61dc7e 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -423,14 +423,9 @@ class ClauseElement(object):
FROM list of a query, when this ClauseElement is placed in the column clause of a Select
statement."""
raise NotImplementedError(repr(self))
- def _process_from_dict(self, data, asfrom):
- """given a dictionary attached to a Select object, places the appropriate
- FROM objects in the dictionary corresponding to this ClauseElement,
- and possibly removes or modifies others."""
- for f in self._get_from_objects():
- data.setdefault(f, f)
- if asfrom:
- data[self] = self
+ def _hide_froms(self):
+ """return a list of FROM clause elements which this ClauseElement replaces."""
+ return []
def compare(self, other):
"""compare this ClauseElement to the given ClauseElement.
@@ -832,8 +827,9 @@ class _BindParamClause(ClauseElement, _CompareMixin):
return isinstance(other, _BindParamClause) and other.type.__class__ == self.type.__class__
def _make_proxy(self, selectable, name = None):
return self
-# return self.obj._make_proxy(selectable, name=self.name)
-
+ def __repr__(self):
+ return "_BindParamClause(%s, %s, type=%s)" % (repr(self.key), repr(self.value), repr(self.type))
+
class _TypeClause(ClauseElement):
"""handles a type keyword in a SQL statement. used by the Case statement."""
def __init__(self, type):
@@ -966,11 +962,6 @@ class _CalculatedClause(ClauseList, ColumnElement):
self._engine = kwargs.get('engine', None)
ClauseList.__init__(self, *clauses)
key = property(lambda self:self.name or "_calc_")
- def _process_from_dict(self, data, asfrom):
- super(_CalculatedClause, self)._process_from_dict(data, asfrom)
- # this helps a Select object get the engine from us
- if asfrom:
- data.setdefault(self, self)
def copy_container(self):
clauses = [clause.copy_container() for clause in self.clauses]
return _CalculatedClause(type=self.type, engine=self._engine, *clauses)
@@ -1156,25 +1147,13 @@ class Join(FromClause):
engine = property(lambda s:s.left.engine or s.right.engine)
- class JoinMarker(FromClause):
- def __init__(self, join):
- FromClause.__init__(self)
- self.join = join
- def _exportable_columns(self):
- return []
-
def alias(self, name=None):
"""creates a Select out of this Join clause and returns an Alias of it. The Select is not correlating."""
return self.select(use_labels=True, correlate=False).alias(name)
- def _process_from_dict(self, data, asfrom):
- for f in self.onclause._get_from_objects():
- data[f] = f
- for f in self.left._get_from_objects() + self.right._get_from_objects():
- # mark the object as a "blank" "from" that wont be printed
- data[f] = Join.JoinMarker(self)
- # a JOIN always impacts the final FROM list of a select statement
- data[self] = self
-
+
+ def _hide_froms(self):
+ return self.left._get_from_objects() + self.right._get_from_objects()
+
def _get_from_objects(self):
return [self] + self.onclause._get_from_objects() + self.left._get_from_objects() + self.right._get_from_objects()
@@ -1323,11 +1302,6 @@ class TableClause(FromClause):
raise NotImplementedError()
def _group_parenthesized(self):
return False
- def _process_from_dict(self, data, asfrom):
- for f in self._get_from_objects():
- data.setdefault(f, f)
- if asfrom:
- data[self] = self
def count(self, whereclause=None, **params):
if len(self.primary_key):
col = list(self.primary_key)[0]
@@ -1443,7 +1417,8 @@ class Select(_SelectBaseMixin, FromClause):
the ability to execute itself and return a result set."""
def __init__(self, columns=None, whereclause = None, from_obj = [], order_by = None, group_by=None, having=None, use_labels = False, distinct=False, for_update=False, engine=None, limit=None, offset=None, scalar=False, correlate=True):
_SelectBaseMixin.__init__(self)
- self.__froms = util.OrderedDict()
+ self.__froms = util.OrderedSet()
+ self.__hide_froms = util.Set([self])
self.use_labels = use_labels
self.whereclause = None
self.having = None
@@ -1526,7 +1501,7 @@ class Select(_SelectBaseMixin, FromClause):
# visit the FROM objects of the column looking for more Selects
for f in column._get_from_objects():
f.accept_visitor(self.__correlator)
- column._process_from_dict(self.__froms, False)
+ self._process_froms(column, False)
def _exportable_columns(self):
return self._raw_columns
@@ -1535,6 +1510,15 @@ class Select(_SelectBaseMixin, FromClause):
return column._make_proxy(self, name=column._label)
else:
return column._make_proxy(self, name=column.name)
+
+ def _process_froms(self, elem, asfrom):
+ for f in elem._get_from_objects():
+ self.__froms.add(f)
+ if asfrom:
+ self.__froms.add(elem)
+ for f in elem._hide_froms():
+ self.__hide_froms.add(f)
+
def append_whereclause(self, whereclause):
self._append_condition('whereclause', whereclause)
def append_having(self, having):
@@ -1543,7 +1527,7 @@ class Select(_SelectBaseMixin, FromClause):
if type(condition) == str:
condition = _TextClause(condition)
condition.accept_visitor(self.__wherecorrelator)
- condition._process_from_dict(self.__froms, False)
+ self._process_froms(condition, False)
if getattr(self, attribute) is not None:
setattr(self, attribute, and_(getattr(self, attribute), condition))
else:
@@ -1560,9 +1544,10 @@ class Select(_SelectBaseMixin, FromClause):
if type(fromclause) == str:
fromclause = _TextClause(fromclause)
fromclause.accept_visitor(self.__correlator)
- fromclause._process_from_dict(self.__froms, True)
+ self._process_froms(fromclause, True)
+
def _locate_oid_column(self):
- for f in self.__froms.values():
+ for f in self.__froms:
if f is self:
# we might be in our own _froms list if a column with us as the parent is attached,
# which includes textual columns.
@@ -1572,16 +1557,11 @@ class Select(_SelectBaseMixin, FromClause):
return oid
else:
return None
- def _get_froms(self):
- return [f for f in self.__froms.values() if f is not self and (f not in self.__correlated)]
- froms = property(lambda s: s._get_froms(), doc="""a list containing all elements of the FROM clause""")
+
+ froms = property(lambda self: self.__froms.difference(self.__hide_froms).difference(self.__correlated), doc="""a collection containing all elements of the FROM clause""")
def accept_visitor(self, visitor):
- # TODO: add contextual visit_ methods
- # visit_select_whereclause, visit_select_froms, visit_select_orderby, etc.
- # which will allow the compiler to set contextual flags before traversing
- # into each thing.
- for f in self._get_froms():
+ for f in self.froms:
f.accept_visitor(visitor)
if self.whereclause is not None:
self.whereclause.accept_visitor(visitor)
@@ -1601,7 +1581,7 @@ class Select(_SelectBaseMixin, FromClause):
if self._engine is not None:
return self._engine
- for f in self.__froms.values():
+ for f in self.__froms:
if f is self:
continue
e = f.engine