def put(self, path, id, data): """Put a value at a given path and id. If the path/id combo doesn't exist, the path is created. Example: model = {'abc': { } } put('abc/def', 'hij', {'hello': 'world'}) model == {'abc': { 'def': { 'hij': { 'hello': 'world' } } } } Arguments: path: The path to the location of the value id: The key of the value to insert data: The value to insert """ mutation_data_obj = path_utils.follow_path(self.data_tree, path, create_missing=True) if mutation_data_obj is not None: mutation_data_obj[id] = data mutation_paths_obj = path_utils.follow_path(self.path_tree, path, create_missing=True) if mutation_paths_obj is not None: mutation_paths_obj[id] = 'put' if self.additional is None: return local_data_obj = path_utils.follow_path(self.additional, path, create_missing=True) if local_data_obj is not None: local_data_obj[id] = data
def delete(self, path, id): """Delete a value at a given path and id. If the path/id combo doesn't exist, nothing happens. Example: model = {'abc': { 'def': { 'hij': { 'hello': 'world' } } } } delete('abc/def', 'hij') model == {'abc': { 'def': { } } Arguments: path: The path to the location of the value id: The id of the value to delete """ mutation_data_obj = path_utils.follow_path(self.data_tree, path, create_missing=True) if mutation_data_obj is not None and id in mutation_data_obj: del mutation_data_obj[id] mutation_paths_obj = path_utils.follow_path(self.path_tree, path, create_missing=True) if mutation_paths_obj is not None: mutation_paths_obj[id] = 'delete' if self.additional is None: return local_data_obj = path_utils.follow_path(self.additional, path) if local_data_obj is not None and id in local_data_obj: del local_data_obj[id]
def patch(self, path, data): """Patches a list of changes at a path. If the path/id combo doesn't exist, the path is created. Example: model = {'abc': { 'def': { 'foo': 'bar' } } } patch('abc/def', {'hij': {'hello': 'world'}, 'klm': 'mno'}) model == {'abc': { 'def': { 'foo': 'bar', hij': { 'hello': 'world' }, 'klm': 'mno' } } } Arguments: path: The path at which to apply the patches data: The values to insert. A dict of ids(or sub paths) to values """ for key, value in data.iteritems(): mutation_data_obj = path_utils.follow_path( self.data_tree, path_utils.join_paths(path, path_utils.drop_last(key)), create_missing=True) if mutation_data_obj is not None: mutation_data_obj[path_utils.last(key)] = value mutation_paths_obj = path_utils.follow_path( self.path_tree, path_utils.join_paths(path, path_utils.drop_last(key)), create_missing=True) if mutation_paths_obj is not None: mutation_paths_obj[path_utils.last(key)] = 'patch' if self.additional is None: continue local_data_obj = path_utils.follow_path( self.additional, path_utils.join_paths(path, path_utils.drop_last(key)), create_missing=True) if local_data_obj is not None: local_data_obj[path_utils.last(key)] = value
def get(self, path, id, local_instance=True): """Get data from the model. Getting data from the local instance and the remove instance is the same with some exceptions: - Remote fetches don't have mutations from an unclosed transaction, local fetches do. Arguments: path: The path to get id: The id of the value to get at the path local_instance: If true, gets the data from the local copy, if false, gets the data from the remote copy. """ if not local_instance: print "getting accessor_mutex" accessor_mutex.acquire() data = self.firebase.get(path, id) print "releasing accessor_mutex" accessor_mutex.release() return data full_path = path_utils.join_paths(path, id) obj = path_utils.follow_path(self.instance, path_utils.drop_last(full_path)) if obj is None: return None return obj.get(path_utils.last(full_path))
def batch_mutation(self): batch_mutataion = {} all_paths = path_utils.crawl_paths(self.path_tree) for path in all_paths: leading_slash_path = '/' + path data_obj = path_utils.follow_path( self.data_tree, path_utils.drop_last(leading_slash_path)) batch_mutataion[leading_slash_path] = data_obj.get( path_utils.last(leading_slash_path)) return batch_mutataion