commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

r5854 - in trunk/gnue-appserver: . src


From: johannes
Subject: r5854 - in trunk/gnue-appserver: . src
Date: Wed, 2 Jun 2004 07:42:36 -0500 (CDT)

Author: johannes
Date: 2004-06-02 07:42:35 -0500 (Wed, 02 Jun 2004)
New Revision: 5854

Modified:
   trunk/gnue-appserver/BUGS
   trunk/gnue-appserver/src/data.py
   trunk/gnue-appserver/src/geasSession.py
Log:
Operations on the session manager interface are now atomic.


Modified: trunk/gnue-appserver/BUGS
===================================================================
--- trunk/gnue-appserver/BUGS   2004-06-02 07:04:23 UTC (rev 5853)
+++ trunk/gnue-appserver/BUGS   2004-06-02 12:42:35 UTC (rev 5854)
@@ -3,5 +3,3 @@
 * Time fields are broken in some dbdrivers. Depending on the driver, it's
   possible that the "Meeting Time" field in the sample doesn't work.
 
-* Operations on the Session Manager interface are not atomar
-

Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py    2004-06-02 07:04:23 UTC (rev 5853)
+++ trunk/gnue-appserver/src/data.py    2004-06-02 12:42:35 UTC (rev 5854)
@@ -25,6 +25,7 @@
 
 import string
 import whrandom
+import copy
 
 from gnue.common.datasources import GDataSource, GConditions, GConnections
 
@@ -337,6 +338,10 @@
     self.__inserted    = []
     self.__deleted     = []
 
+    self.__confirmedCache   = None
+    self.__confirmedInserts = []
+    self.__confirmedDeletes = []
+
   # ---------------------------------------------------------------------------
   # Create a recordset from a query
   # ---------------------------------------------------------------------------
@@ -510,7 +515,8 @@
 
       resultSet.post ()
 
-    self.__inserted = []
+    self.__inserted         = []
+    self.__confirmedInserts = []
 
     # second perform all updates
     for (table, rows) in tables.items ():
@@ -540,6 +546,7 @@
       resultSet.post ()
 
     self.__deleted = []
+    self.__confirmedDeletes = []
 
 
     # Commit the whole transaction
@@ -548,6 +555,7 @@
     # The transaction has ended. Changes from other transactions could become
     # valid in this moment, so we have to clear the whole cache.
     self.__cache.clear ()
+    self.__confirmedCache = None
 
   # ---------------------------------------------------------------------------
   # Undo all changes
@@ -560,6 +568,8 @@
 
     self.__inserted = []
     self.__deleted  = []
+    self.__confirmedInserts = []
+    self.__confirmedDeletes = []
 
     # Send the rollback to the database. Although we have (most probably) not
     # written anything yet, we have to tell the database that a new transaction
@@ -570,6 +580,7 @@
     # The transaction has ended. Changes from other transactions could become
     # valid in this moment, so we have to clear the whole cache.
     self.__cache.clear ()
+    self.__confirmedCache = None
 
   # ---------------------------------------------------------------------------
   # Close the connection
@@ -582,6 +593,39 @@
 
     self.__connections.closeAll ()
 
+
+  # ---------------------------------------------------------------------------
+  # confirm all recent changes
+  # ---------------------------------------------------------------------------
+
+  def confirmChanges (self):
+    """
+    This function confirms all changes to be safe, so a subsequent call of the
+    cancelChanges () function restores to this state.
+    """
+    self.__confirmedCache   = copy.deepcopy (self.__cache)
+    self.__confiremdInserts = copy.deepcopy (self.__inserted)
+    self.__confiremdDeletes = copy.deepcopy (self.__deleted)
+
+
+  # ---------------------------------------------------------------------------
+  # revoke all changes up the the last confirm
+  # ---------------------------------------------------------------------------
+
+  def cancelChanges (self):
+    """
+    This function revokes all changes up to the last call of the
+    confirmChanges () function.
+    """
+    if self.__confirmedCache is not None:
+      self.__cache = copy.deepcopy (self.__confirmedCache)
+    else:
+      self.__cache.clear ()
+
+    self.__inserted = copy.deepcopy (self.__confirmedInserts)
+    self.__deleted  = copy.deepcopy (self.__confirmedDeletes)
+
+
 # =============================================================================
 # Recordset class
 # =============================================================================

Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py     2004-06-02 07:04:23 UTC (rev 
5853)
+++ trunk/gnue-appserver/src/geasSession.py     2004-06-02 12:42:35 UTC (rev 
5854)
@@ -78,6 +78,7 @@
     self.__authAdapter    = authAdapter
     self.__connection     = None
     self.__dirtyInstances = {}
+    self.__operation      = None
 
     self.sm = sm                        # The session manager
     self.id = id                        # The session id
@@ -155,8 +156,45 @@
         for child in condition._children:
           self.__convertCondition (classdef, child, contentdict)
 
+  # ---------------------------------------------------------------------------
+  # Start a new 'atomic' operation if not already started
+  # ---------------------------------------------------------------------------
 
+  def __startOperation (self, operation):
+    if self.__operation is None:
+      self.__operation = operation
+      return True
+    else:
+      return False
+
+
+
   # ---------------------------------------------------------------------------
+  # Cancel all changes of an operation
+  # ---------------------------------------------------------------------------
+
+  def __cancelOperation (self, operation):
+    if self.__operation == operation:
+      try:
+        self.__connection.cancelChanges ()
+
+      finally:
+        self.__operation = None
+
+  # ---------------------------------------------------------------------------
+  # Confirm all changes of an operation
+  # ---------------------------------------------------------------------------
+
+  def __confirmOperation (self, operation):
+    if self.__operation == operation:
+      try:
+        self.__connection.confirmChanges ()
+
+      finally:
+        self.__operation = None
+
+
+  # ---------------------------------------------------------------------------
   # Log into the application server
   # ---------------------------------------------------------------------------
 
@@ -342,58 +380,94 @@
 
   def store (self, classname, obj_id_list, propertylist, data):
 
-    classdef = self.__getClassdef (classname)
+    opControl = self.__startOperation ('store')
 
-    result = []
-    i = 0
-    for object_id in obj_id_list:
-      if object_id:
-        instance = self.__findInstance (classdef, object_id, [])
-        new_object_id = object_id
-      else:
-        instance = self.__newInstance (classdef)
-        new_object_id = instance.get ([u'gnue_id']) [0]
-      instance.put (propertylist, data [i])
-      i += 1
-      result.append (new_object_id)
-      self.__dirtyInstances [new_object_id] = instance
+    try:
+      classdef = self.__getClassdef (classname)
 
+      result = []
+      i = 0
+      for object_id in obj_id_list:
+        if object_id:
+          instance = self.__findInstance (classdef, object_id, [])
+          new_object_id = object_id
+        else:
+          instance = self.__newInstance (classdef)
+          new_object_id = instance.get ([u'gnue_id']) [0]
+        instance.put (propertylist, data [i])
+        i += 1
+        result.append (new_object_id)
+        self.__dirtyInstances [new_object_id] = instance
+
+    except:
+      if opControl:
+        self.__cancelOperation ('store')
+      raise
+
+    else:
+      if opControl:
+        self.__confirmOperation ('store')
+
     return result
 
+
   # ---------------------------------------------------------------------------
   # Delete business objects
   # ---------------------------------------------------------------------------
 
   def delete (self, classname, obj_id_list):
 
-    classdef = self.__getClassdef (classname)
+    opControl = self.__startOperation ('delete')
 
-    for objectId in obj_id_list:
-      instance = self.__findInstance (classdef, objectId, [])
-      for proc in classdef.procedures.values ():
-        if proc.gnue_name.upper () == 'ONDELETE':
-          instance.call (proc, None)
+    try:
+      classdef = self.__getClassdef (classname)
 
-    for object_id in obj_id_list:
-      self.__connection.deleteRecord (classdef.table, object_id)
-      if self.__dirtyInstances.has_key (object_id):
-        del self.__dirtyInstances [object_id]
+      for objectId in obj_id_list:
+        instance = self.__findInstance (classdef, objectId, [])
+        for proc in classdef.procedures.values ():
+          if proc.gnue_name.upper () == 'ONDELETE':
+            instance.call (proc, None)
 
+      for object_id in obj_id_list:
+        self.__connection.deleteRecord (classdef.table, object_id)
+        if self.__dirtyInstances.has_key (object_id):
+          del self.__dirtyInstances [object_id]
 
+    except:
+      if opControl:
+        self.__cancelOperation ('delete')
+      raise
+
+    else:
+      if opControl:
+        self.__confirmOperation ('delete')
+
+
   # ---------------------------------------------------------------------------
   # Call a procedure of business objects
   # ---------------------------------------------------------------------------
 
   def call (self, classname, obj_id_list, procedurename, parameters):
 
-    classdef = self.__getClassdef (classname)
-    procdef  = self.__getProcdef (classdef, procedurename)
+    opControl = self.__startOperation ('call')
 
-    result = []
-    for object_id in obj_id_list:
-      instance = self.__findInstance (classdef, object_id, [])
-      result.append (instance.call (procdef, parameters))
+    try:
+      classdef = self.__getClassdef (classname)
+      procdef  = self.__getProcdef (classdef, procedurename)
 
+      result = []
+      for object_id in obj_id_list:
+        instance = self.__findInstance (classdef, object_id, [])
+        result.append (instance.call (procdef, parameters))
+
+    except:
+      if opControl:
+        self.__cancelOperation ('call')
+
+    else:
+      if opControl:
+        self.__confirmOperation ('call')
+
     return result
 
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]