diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-04-27 02:50:16 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-04-27 02:50:16 +0000 |
| commit | 9c52d56f6f8a9cdafb231adf9f4110473099c9b5 (patch) | |
| tree | eeded174bec983e4415f5f52f187b3d5d9a1882d /django/db/models/sql/datastructures.py | |
| parent | c91a30f00fd182faf8ca5c03cd7dbcf8b735b458 (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.py | 103 |
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) + |
