# Ticket #251: q.diff

File q.diff, 3.6 KB (added by hugo, 14 years ago)

query algebra for complex queries

• ## core/meta/__init__.py

 continue if kwarg_value is None: continue if kwarg == 'complex': tables2, join_where2, where2, params2, table_count = kwarg_value.getSQL(opts, table_count) tables.extend(tables2) join_where.extend(join_where2) where.append(where2) params.extend(params2) continue if kwarg == '_or': for val in kwarg_value: tables2, join_where2, where2, params2, table_count = _parse_lookup(val, opts, table_count) continue return tables, join_where, where, params, table_count class Q_base: """ This is a base class for Q_and and Q_or. """ def __init__(self, *args): self.args = args def __repr__(self): return '(%s)' % self.operator.join([repr(el) for el in self.args]) def getSQL(self, opts, table_count): tables, join_where, where, params = [], [], [], [] for val in self.args: tables2, join_where2, where2, params2, table_count = val.getSQL(opts, table_count) tables.extend(tables2) join_where.extend(join_where2) where.extend(where2) params.extend(params2) return tables, join_where, '(%s)' % self.operator.join(where), params, table_count class Q_and(Q_base): """ This encapsulates a combined query that uses 'and'. """ operator = ' AND ' def __or__(self, other): if isinstance(other, (Q_and, Q_or, Q)): return Q_or(self, other) else: raise TypeError, other def __and__(self, other): if isinstance(other, Q_and): return Q_and(*(self.args+other.args)) elif isinstance(other, (Q, Q_or)): return Q_and(*(self.args+(other,))) else: raise TypeError, other class Q_or(Q_base): """ This encapsulates a combined query that uses 'or'. """ operator = ' OR ' def __and__(self, other): if isinstance(other, (Q_and, Q_or, Q)): return Q_and(self, other) else: raise TypeError, other def __or__(self, other): if isinstance(other, Q_or): return Q_or(*(self.args+other.args)) elif isinstance(other, (Q, Q_and)): return Q_or(*(self.args+(other,))) else: raise TypeError, other class Q: """ This is a class that encapsulates queries for the complex parameter to django model functions. """ def __init__(self, **kwargs): self.kwargs = kwargs def __repr__(self): return 'Q%r' % self.kwargs def __and__(self, other): if isinstance(other, (Q, Q_and, Q_or)): return Q_and(self, other) else: raise TypeError, other def __or__(self, other): if isinstance(other, (Q, Q_and, Q_or)): return Q_or(self, other) else: raise TypeError, other def getSQL(self, opts, table_count): return _parse_lookup(self.kwargs.items(), opts, table_count) def function_get_sql_clause(opts, **kwargs): select = ["%s.%s" % (db.db.quote_name(opts.db_table), db.db.quote_name(f.column)) for f in opts.fields] tables = [opts.db_table] + (kwargs.get('tables') and kwargs['tables'][:] or [])