From: Sascha Silbe <sascha@silbe.org>
Subject: [PATCH] add and use type information for "known" properties (#1437)
Bug #1342 has shown that it's necessary to know (and convert/check) the type
of known properties (as we need to use xapian.sortable_serialise() on numeric
types). This patch does that (but doesn't fix #1342 yet, that will be done on
top of it).
Signed-off-by: Sascha Silbe <sascha@silbe.org>
---
src/carquinyol/indexstore.py | 21 ++++++++++++---------
1 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/carquinyol/indexstore.py b/src/carquinyol/indexstore.py
index 1a9f838..09914e9 100644
a
|
b
|
_QUERY_TERM_MAP = { |
56 | 56 | } |
57 | 57 | |
58 | 58 | _QUERY_VALUE_MAP = { |
59 | | 'timestamp': _VALUE_TIMESTAMP, |
| 59 | 'timestamp': {'number': _VALUE_TIMESTAMP, 'type': float}, |
60 | 60 | } |
61 | 61 | |
62 | 62 | |
… |
… |
class QueryParser (xapian.QueryParser): |
132 | 132 | else: |
133 | 133 | return Query(_PREFIX_NONE + str(value)) |
134 | 134 | |
135 | | def _parse_query_value_range(self, name, value, value_no): |
| 135 | def _parse_query_value_range(self, name, info, value): |
136 | 136 | if len(value) != 2: |
137 | 137 | raise TypeError( |
138 | 138 | 'Only tuples of size 2 have a defined meaning. ' |
139 | 139 | 'Did you mean to pass a list instead?') |
140 | 140 | |
141 | 141 | start, end = value |
142 | | return Query(Query.OP_VALUE_RANGE, value_no, str(start), str(end)) |
| 142 | return Query(Query.OP_VALUE_RANGE, info['number'], |
| 143 | self._convert_value(info, start), self._convert_value(info, end)) |
143 | 144 | |
144 | | def _parse_query_value(self, name, value_no, value): |
| 145 | def _convert_value(self, info, value): |
| 146 | return str(info['type'](value)) |
| 147 | |
| 148 | def _parse_query_value(self, name, info, value): |
145 | 149 | if isinstance(value, list): |
146 | | subqueries = [self._parse_query_value(name, value_no, word) |
| 150 | subqueries = [self._parse_query_value(name, info, word) |
147 | 151 | for word in value] |
148 | 152 | return Query(Query.OP_OR, subqueries) |
149 | 153 | |
150 | 154 | elif isinstance(value, tuple): |
151 | | return self._parse_query_value_range(name, value, value_no) |
| 155 | return self._parse_query_value_range(name, info, value) |
152 | 156 | |
153 | 157 | elif isinstance(value, dict): |
154 | 158 | # compatibility option for timestamp: {'start': 0, 'end': 1} |
155 | 159 | start = value.get('start', 0) |
156 | 160 | end = value.get('end', sys.maxint) |
157 | | return self._parse_query_value_range(name, (start, end), value_no) |
| 161 | return self._parse_query_value_range(name, info, (start, end)) |
158 | 162 | |
159 | 163 | else: |
160 | | return Query(Query.OP_VALUE_RANGE, |
161 | | _QUERY_VALUE_MAP[name], str(value), str(value)) |
| 164 | return self._parse_query_value_range(name, info, (value, value)) |
162 | 165 | |
163 | 166 | def _parse_query_xapian(self, query_str): |
164 | 167 | try: |