[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5854 - in trunk/gnue-appserver: . src,
johannes <=