+ def _update_object_hash(self, user, account, container, name, size, hash, meta={}, replace_meta=False, permissions=None):
+ if permissions is not None and user != account:
+ raise NotAllowedError
+ self._can_write(user, account, container, name)
+ if permissions is not None:
+ path = '/'.join((account, container, name))
+ self._check_permissions(path, permissions)
+
+ account_path, account_node = self._lookup_account(account, True)
+ container_path, container_node = self._lookup_container(account, container)
+ path, node = self._put_object_node(container_path, container_node, name)
+ src_version_id, dest_version_id = self._put_version_duplicate(user, node, size, hash)
+
+ # Check quota.
+ size_delta = size # Change with versioning.
+ if size_delta > 0:
+ account_quota = long(self._get_policy(account_node)['quota'])
+ container_quota = long(self._get_policy(container_node)['quota'])
+ if (account_quota > 0 and self._get_statistics(account_node)[1] + size_delta > account_quota) or \
+ (container_quota > 0 and self._get_statistics(container_node)[1] + size_delta > container_quota):
+ # This must be executed in a transaction, so the version is never created if it fails.
+ raise QuotaError
+
+ if not replace_meta and src_version_id is not None:
+ self.node.attribute_copy(src_version_id, dest_version_id)
+ self.node.attribute_set(dest_version_id, ((k, v) for k, v in meta.iteritems()))
+ if permissions is not None:
+ self.permissions.access_set(path, permissions)
+ return dest_version_id
+