summaryrefslogtreecommitdiff
path: root/django/db/models/sql/datastructures.py
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-04-27 02:50:16 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-04-27 02:50:16 +0000
commit9c52d56f6f8a9cdafb231adf9f4110473099c9b5 (patch)
treeeeded174bec983e4415f5f52f187b3d5d9a1882d /django/db/models/sql/datastructures.py
parentc91a30f00fd182faf8ca5c03cd7dbcf8b735b458 (diff)
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing code. Also adds a couple of new features. Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658 git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/sql/datastructures.py')
-rw-r--r--django/db/models/sql/datastructures.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/django/db/models/sql/datastructures.py b/django/db/models/sql/datastructures.py
new file mode 100644
index 0000000000..cb54a564f8
--- /dev/null
+++ b/django/db/models/sql/datastructures.py
@@ -0,0 +1,103 @@
+"""
+Useful auxilliary data structures for query construction. Not useful outside
+the SQL domain.
+"""
+
+class EmptyResultSet(Exception):
+ pass
+
+class FullResultSet(Exception):
+ pass
+
+class MultiJoin(Exception):
+ """
+ Used by join construction code to indicate the point at which a
+ multi-valued join was attempted (if the caller wants to treat that
+ exceptionally).
+ """
+ def __init__(self, level):
+ self.level = level
+
+class Empty(object):
+ pass
+
+class RawValue(object):
+ def __init__(self, value):
+ self.value = value
+
+class Aggregate(object):
+ """
+ Base class for all aggregate-related classes (min, max, avg, count, sum).
+ """
+ def relabel_aliases(self, change_map):
+ """
+ Relabel the column alias, if necessary. Must be implemented by
+ subclasses.
+ """
+ raise NotImplementedError
+
+ def as_sql(self, quote_func=None):
+ """
+ Returns the SQL string fragment for this object.
+
+ The quote_func function is used to quote the column components. If
+ None, it defaults to doing nothing.
+
+ Must be implemented by subclasses.
+ """
+ raise NotImplementedError
+
+class Count(Aggregate):
+ """
+ Perform a count on the given column.
+ """
+ def __init__(self, col='*', distinct=False):
+ """
+ Set the column to count on (defaults to '*') and set whether the count
+ should be distinct or not.
+ """
+ self.col = col
+ self.distinct = distinct
+
+ def relabel_aliases(self, change_map):
+ c = self.col
+ if isinstance(c, (list, tuple)):
+ self.col = (change_map.get(c[0], c[0]), c[1])
+
+ def as_sql(self, quote_func=None):
+ if not quote_func:
+ quote_func = lambda x: x
+ if isinstance(self.col, (list, tuple)):
+ col = ('%s.%s' % tuple([quote_func(c) for c in self.col]))
+ elif hasattr(self.col, 'as_sql'):
+ col = self.col.as_sql(quote_func)
+ else:
+ col = self.col
+ if self.distinct:
+ return 'COUNT(DISTINCT %s)' % col
+ else:
+ return 'COUNT(%s)' % col
+
+class Date(object):
+ """
+ Add a date selection column.
+ """
+ def __init__(self, col, lookup_type, date_sql_func):
+ self.col = col
+ self.lookup_type = lookup_type
+ self.date_sql_func= date_sql_func
+
+ def relabel_aliases(self, change_map):
+ c = self.col
+ if isinstance(c, (list, tuple)):
+ self.col = (change_map.get(c[0], c[0]), c[1])
+
+ def as_sql(self, quote_func=None):
+ if not quote_func:
+ quote_func = lambda x: x
+ if isinstance(self.col, (list, tuple)):
+ col = '%s.%s' % tuple([quote_func(c) for c in self.col])
+ else:
+ col = self.col
+ return self.date_sql_func(self.lookup_type, col)
+