Commit 5678e65c authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

pithos: Fix metadata copying

Copy/move operations set/update the metadata
of the resulted object.
Metadata of other domains should be kept.
This commit restores this behavior broken
from a previous commit.
parent 7691cd27
......@@ -1020,6 +1020,17 @@ class Node(DBWorker):
return hash, size
def attribute_get_domains(self, serial, node=None):
node = node or select([self.versions.c.node],
self.versions.c.serial == serial)
s = select([self.attributes.c.domain],
and_(self.attributes.c.serial == serial,
self.attributes.c.node == node)).distinct()
r = self.conn.execute(s)
l = r.fetchall()
r.close()
return [d[0] for d in l]
def attribute_get(self, serial, domain, keys=()):
"""Return a list of (key, value) pairs of the specific version.
......
......@@ -756,6 +756,22 @@ class Node(DBWorker):
self.nodes_set_latest_version(node, props[0])
return hash, size
def attribute_get_domains(self, serial, node=None):
q = ("select distinct domain from attributes "
"where serial = ? ")
args = [serial]
if node is not None:
q += ("and node = ?")
args += [node]
else:
q += ("and node = "
"(select node from versions where serial = ?)")
args += [serial]
execute = self.execute
execute(q, args)
return [d[0] for d in self.fetchall()]
def attribute_get(self, serial, domain, keys=()):
"""Return a list of (key, value) pairs of the specific version.
......
......@@ -1087,6 +1087,8 @@ class ModularBackend(BaseBackend):
src_version_id, dest_version_id = self._put_metadata(
user, node, domain, meta, replace,
update_statistics_ancestors_depth=1)
self._copy_metadata(src_version_id, dest_version_id, node,
exclude_domain=domain, src_node=node)
self._apply_versioning(account, container, src_version_id,
update_statistics_ancestors_depth=1)
return dest_version_id
......@@ -1242,6 +1244,21 @@ class ModularBackend(BaseBackend):
return props[self.IS_SNAPSHOT], props[self.SIZE], \
self._get_object_hashmap(props, update_available=True)
def _copy_metadata(self, src_version, dest_version, dest_node,
exclude_domain, src_node=None):
domains = self.node.attribute_get_domains(src_version,
node=src_node)
try:
domains.remove(exclude_domain)
except ValueError: # domain is not in the list
pass
for d in domains:
existing = dict(self.node.attribute_get(src_version, d))
self._put_metadata_duplicate(
src_version, dest_version, d, dest_node, meta=existing,
replace=True)
def _update_object_hash(self, user, account, container, name, size, type,
hash, checksum, domain, meta, replace_meta,
permissions, src_node=None, src_version_id=None,
......@@ -1272,6 +1289,8 @@ class ModularBackend(BaseBackend):
# Handle meta.
if src_version_id is None:
src_version_id = pre_version_id
self._copy_metadata(src_version_id, dest_version_id, node,
exclude_domain=domain, src_node=src_node)
self._put_metadata_duplicate(
src_version_id, dest_version_id, domain, node, meta, replace_meta)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment