Web · Wiki · Activities · Blog · Lists · Chat · Meeting · Bugs · Git · Translate · Archive · People · Donate

Commit 41afb73b7ecb5e5e3e3d0c0d8916554367170c59

fsemulation: don't try to duplicate data store / Xapian matching

_matches_root_query() was meant to verify that a requested entity has
actually been exported by the user (using root_query). But in order to
do that, a lot of the matching functionality in the data store
(usually implemented using Xapian) would have to be duplicated for any
except the most basic export selections to work. E.g. exporting based
on tags needs to work on parts (words) of a single value, rather than
an exact match on the full string.

Instead, let the data store do the verification by using its searching
API even if we already know the object id. There's some performance
impact to this, but it's not clear a reasonably functional
_matches_root_query() would be much faster.
  
135135 Only return the latest version of each entry for data stores with
136136 version support.
137137 """
138 query = dict(query or {})
139 query.update(self._root_query)
138 query = self._merge_root_query(query)
139
140140 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
141141 options = {'metadata': ['tree_id', 'version_id'],
142142 'order_by': ['-timestamp']}
165165
166166 Returns a list of tuples containing the object_id and metadata.
167167 """
168 query = dict(query or {})
169 query.update(self._root_query)
168 query = self._merge_root_query(query)
170169
171170 properties = list(_USEFUL_PROPS)
172171 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
204204 @synchronised
205205 def list_tree_ids(self, query=None):
206206 """Retrieve the tree_ids of all (matching) data store entries"""
207 query = self._merge_root_query(query)
207208 return [unicode(entry[0]) for entry in self.list_object_ids(query)]
208209
209210 @synchronised
210211 def list_property_values(self, name, query=None):
211212 """Return all unique values of the given property"""
212213 assert isinstance(name, unicode)
214 query = self._merge_root_query(query)
213215
214 query = dict(query or {})
215 query.update(self._root_query)
216216 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
217217 options = {'metadata': [name], 'all_versions': True}
218218 entries = self._data_store.find(query, options,
238238 return False
239239 raise
240240
241 return self._matches_root_query(entry)
241 return True
242242
243243 @synchronised
244244 def check_tree_id(self, tree_id):
305305 else:
306306 assert isinstance(object_id, unicode)
307307
308 query['uid'] = object_id
309 results = self._data_store.find(query, names or [],
310 timeout=DBUS_TIMEOUT_MAX,
311 byte_arrays=True)[0]
312
308313 metadata = self._data_store.get_properties(object_id,
309314 byte_arrays=True)
310 if not self._matches_root_query(metadata):
315 if not results:
311316 raise ValueError('Object %r does not exist' % (object_id, ))
312317
318 metadata = results[0]
313319 metadata['uid'] = object_id
314320 if names:
315321 metadata = dict([(name, metadata[name]) for name in names
474474 timeout=DBUS_TIMEOUT_MAX)
475475 return unicode(object_id)
476476
477 def _matches_root_query(self, metadata):
478 """Return True if metadata matches the root query"""
479 return not [True for key, value in self._root_query.items()
480 if metadata.get(key) != value]
477 def _merge_root_query(self, query):
478 query = dict(query or {})
479 xapian_query = query.get('query', '')
480 query.update(self._root_query)
481 if ('query' in self._root_query) and xapian_query:
482 query['query'] = '(%s) AND (%s)' % (self._root_query['query'],
483 xapian_query)
484 return query
481485
482486 def _convert_metadata(self, metadata):
483487 """Convert metadata (as returned by the data store) to a unicode dict