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

Commit 50c35b7a071de620e6e4505d8afb98f0e94a21b7

fsemulation: add support for root query

The root query is used to restrict the file system view to a certain subset of
the data store.
  
9494
9595
9696class DataStore(object):
97 def __init__(self):
97 def __init__(self, root_query):
98 self._root_query = root_query
9899 self.supports_versions = False
99100 self._lock = threading.RLock()
100101 self._data_store_version = 0
135135 Only return the latest version of each entry for data stores with
136136 version support.
137137 """
138 query = query or {}
138 query = dict(query or {})
139 query.update(self._root_query)
139140 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
140141 options = {'metadata': ['tree_id', 'version_id'],
141142 'order_by': ['-timestamp']}
165165
166166 Returns a list of tuples containing the object_id and metadata.
167167 """
168 query = query or {}
168 query = dict(query or {})
169 query.update(self._root_query)
169170
170171 properties = list(_USEFUL_PROPS)
171172 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
195195 @synchronised
196196 def list_versions(self, tree_id):
197197 """Retrieve all version_ids of the given data store entry"""
198 query = dict(self._root_query)
199 query['tree_id'] = tree_id
198200 options = {'all_versions': True, 'order_by': ['-timestamp']}
199201 return [unicode(entry['version_id'])
200 for entry in self._data_store.find({'tree_id': tree_id},
202 for entry in self._data_store.find(query,
201203 options, timeout=DBUS_TIMEOUT_MAX, byte_arrays=True)[0]]
202204
203205 @synchronised
212212 """Return all unique values of the given property"""
213213 assert isinstance(name, unicode)
214214
215 query = query or {}
215 query = dict(query or {})
216 query.update(self._root_query)
216217 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
217218 options = {'metadata': [name], 'all_versions': True}
218219 entries = self._data_store.find(query, options,
233233 def check_object_id(self, object_id):
234234 """Return True if the given object_id identifies a data store entry"""
235235 try:
236 self.get_properties(object_id, [u'uid'])
236 entry = self.get_properties(object_id, self._root_query.keys())
237237 except dbus.DBusException, exception:
238238 if exception.get_dbus_name() == DBUS_PYTHON_VALUE_ERROR:
239239 return False
240240 raise
241241
242 return True
242 return self._matches_root_query(entry)
243243
244244 @synchronised
245245 def check_tree_id(self, tree_id):
246246 """Return True if the given tree_id identifies a data store entry"""
247247 assert isinstance(tree_id, unicode)
248 results = self._data_store.find({'tree_id': tree_id}, {},
248 query = dict(self._root_query)
249 query['tree_id'] = tree_id
250 results = self._data_store.find(query, {},
249251 timeout=DBUS_TIMEOUT_MAX,
250252 byte_arrays=True)[0]
251253 return bool(results)
261261 assert isinstance(word, unicode)
262262
263263 query_string = u'%s:"%s"' % (name, word.replace(u'"', u''))
264 query = dict(self._root_query)
264265 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
265266 options = {'limit': 1}
266 results = self._data_store.text_search({}, query_string, options,
267 results = self._data_store.text_search(query, query_string,
268 options,
267269 timeout=DBUS_TIMEOUT_MAX,
268270 byte_arrays=True)[0]
269271 else:
270 query = {'query': query_string, 'limit': 1}
272 query['query'] = query_string
273 query['limit'] = 1
271274 results = self._data_store.find(query, [name],
272275 timeout=DBUS_TIMEOUT_MAX,
273276 byte_arrays=True)[0]
283283
284284 Returns a dictionary with unicode strings as keys and values.
285285 """
286 query = dict(self._root_query)
286287 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
287288 tree_id, version_id = object_id
288289 assert isinstance(tree_id, unicode)
289290 assert isinstance(version_id, unicode)
290291
291 query = {'tree_id': tree_id, 'version_id': version_id}
292 query['tree_id'] = tree_id
293 query['version_id'] = version_id
292294 options = {}
293295 if names:
294296 options['metadata'] = names
308308
309309 metadata = self._data_store.get_properties(object_id,
310310 byte_arrays=True)
311 if not self._matches_root_query(metadata):
312 raise ValueError('Object %r does not exist' % (object_id, ))
313
311314 metadata['uid'] = object_id
312315 if names:
313316 metadata = dict([(name, metadata[name]) for name in names
385385 @synchronised
386386 def remove_entry(self, object_id):
387387 """Remove a single (version of a) data store entry"""
388 # Make sure we don't allow deleting entries that don't match
389 # the root query.
390 if not self.check_object_id(object_id):
391 raise ValueError('Object %r does not exist' % (object_id, ))
392
388393 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
389394 tree_id, version_id = object_id
390 assert isinstance(tree_id, unicode)
391 assert isinstance(version_id, unicode)
392
393395 self._data_store.delete(tree_id, version_id,
394396 timeout=DBUS_TIMEOUT_MAX)
395397
396398 else:
397 assert isinstance(object_id, unicode)
398399 self._data_store.delete(object_id, timeout=DBUS_TIMEOUT_MAX)
399400
400401 @synchronised
419419 @synchronised
420420 def get_data(self, object_id):
421421 """Return path to data for data store entry identified by object_id."""
422 # Make sure we don't allow deleting entries that don't match
423 # the root query.
424 if not self.check_object_id(object_id):
425 raise ValueError('Object %r does not exist' % (object_id, ))
426
422427 if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
423428 tree_id, version_id = object_id
424 assert isinstance(tree_id, unicode)
425 assert isinstance(version_id, unicode)
426429 return self._data_store.get_data(tree_id, version_id,
427430 byte_arrays=True)
428431
429432 else:
430 assert isinstance(object_id, unicode)
431433 return self._data_store.get_filename(object_id, byte_arrays=True)
432434
433435 @synchronised
469469 timeout=DBUS_TIMEOUT_MAX)
470470 return unicode(object_id)
471471
472 def _matches_root_query(self, metadata):
473 """Return True if metadata matches the root query"""
474 return not [True for key, value in self._root_query.items()
475 if metadata.get(key) != value]
476
472477 def _convert_metadata(self, metadata):
473478 """Convert metadata (as returned by the data store) to a unicode dict
474479
962962
963963 # public API
964964
965 def __init__(self):
966 self.data_store = DataStore()
965 def __init__(self, root_query=None):
966 self.data_store = DataStore(root_query or {})
967967 # FIXME: determine good LRU size
968968 self._cache = _LRU(500)
969969 self._root_dir = RootDirectory(self, 0550)