From 3f7a84f11ee274acf1e24cf9ef1a71501972bf79 Mon Sep 17 00:00:00 2001
From: Hendrik Buschmeier <hbuschme@uni-bielefeld.de>
Date: Tue, 3 Sep 2013 10:54:35 +0200
Subject: [PATCH] ipaaca-py: first attempt of context-manager based batch
 payload updates.

---
 ipaacalib/python/src/ipaaca/__init__.py | 35 ++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/ipaacalib/python/src/ipaaca/__init__.py b/ipaacalib/python/src/ipaaca/__init__.py
index 0381304..77f4d53 100755
--- a/ipaacalib/python/src/ipaaca/__init__.py
+++ b/ipaacalib/python/src/ipaaca/__init__.py
@@ -144,10 +144,14 @@ class Payload(dict):
 		# NOTE omit_init_update_message is necessary to prevent checking for
 		#   exceptions and sending updates in the case where we just receive
 		#   a whole new payload from the remote side and overwrite it locally.
-		if (not omit_init_update_message) and (self.iu.buffer is not None):
-			self.iu._modify_payload(is_delta=False, new_items=pl, keys_to_remove=[], writer_name=writer_name)
 		for k, v in pl.items():
 			dict.__setitem__(self, k, v)
+		if (not omit_init_update_message) and (self.iu.buffer is not None):
+			self.iu._modify_payload(is_delta=False, new_items=pl, keys_to_remove=[], writer_name=writer_name)
+		self._update_on_every_change = True
+		self._collected_modifications = {}
+		self._collected_removals = []
+
 
 	def merge(self, payload, writer_name=None):
 		for k, v in payload:
@@ -163,16 +167,35 @@ class Payload(dict):
 			k=unicode(k,'utf8')
 		if type(v)==str:
 			v=unicode(v,'utf8')
-		self.iu._modify_payload(is_delta=True, new_items={k:v}, keys_to_remove=[], writer_name=writer_name)
-		result = dict.__setitem__(self, k, v)
+		if self._update_on_every_change:
+			self.iu._modify_payload(is_delta=True, new_items={k:v}, keys_to_remove=[], writer_name=writer_name)
+		else: # Collect additions/modifications
+			self._collected_modifications[k] = v
+		return dict.__setitem__(self, k, v)
+
 	def __delitem__(self, k, writer_name=None):
 		if type(k)==str:
 			k=unicode(k,'utf8')
-		self.iu._modify_payload(is_delta=True, new_items={}, keys_to_remove=[k], writer_name=writer_name)
-		result = dict.__delitem__(self, k)
+		if self._update_on_every_change:
+			self.iu._modify_payload(is_delta=True, new_items={}, keys_to_remove=[k], writer_name=writer_name)
+		else: # Collect additions/modifications
+			self._collected_removals.append(k)
+		return dict.__delitem__(self, k)
+	
+	# Context-manager based batch updates, not yet thread-safe (on remote updates)	
+	#def __enter__(self):
+	#	self._update_on_every_change = False
+	#
+	#def __exit__(self, type, value, traceback):
+	#	self.iu._modify_payload(is_delta=True, new_items=self._collected_modifications, keys_to_remove=self._collected_removals, writer_name=None)
+	#	self._collected_modifications = {}
+	#	self._collected_removals = []
+	#	self._update_on_every_change = True
+
 	def _remotely_enforced_setitem(self, k, v):
 		"""Sets an item when requested remotely."""
 		return dict.__setitem__(self, k, v)
+
 	def _remotely_enforced_delitem(self, k):
 		"""Deletes an item when requested remotely."""
 		return dict.__delitem__(self, k)
-- 
GitLab