commit-gnue
[Top][All Lists]
Advanced

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

r6682 - in trunk: gnue-appserver/src gnue-common/src/datasources gnue-co


From: johannes
Subject: r6682 - in trunk: gnue-appserver/src gnue-common/src/datasources gnue-common/src/datasources/drivers/Base gnue-common/src/datasources/drivers/Base/Schema/Creation gnue-common/src/datasources/drivers/DBSIG2 gnue-common/src/datasources/drivers/appserver/appserver gnue-common/src/schema/scripter gnue-forms/src
Date: Tue, 16 Nov 2004 09:13:09 -0600 (CST)

Author: johannes
Date: 2004-11-16 09:13:08 -0600 (Tue, 16 Nov 2004)
New Revision: 6682

Modified:
   trunk/gnue-appserver/src/data.py
   trunk/gnue-appserver/src/geasList.py
   trunk/gnue-appserver/src/geasSession.py
   trunk/gnue-common/src/datasources/GConnections.py
   trunk/gnue-common/src/datasources/GDataSource.py
   trunk/gnue-common/src/datasources/drivers/Base/Connection.py
   trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
   trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
   trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
   trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
   trunk/gnue-common/src/schema/scripter/Scripter.py
   trunk/gnue-forms/src/GFClient.py
Log:
Fixed some memory leaks and connections now really get closed after form is 
closed


Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py    2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-appserver/src/data.py    2004-11-16 15:13:08 UTC (rev 6682)
@@ -607,10 +607,17 @@
       # not yet cached, need to load from database
       resultSet = _find (self.__connections, self.__database, table, row,
                          uncachedFields)
-      if resultSet.current is None:
-        return None
-      r = record (self.__cache, self.__connections, self.__database, table, 
row)
-      r._fill (None, uncachedFields, resultSet.current)
+      try:
+        if resultSet.current is None:
+          return None
+
+        r = record (self.__cache, self.__connections, self.__database, table,
+                    row)
+        r._fill (None, uncachedFields, resultSet.current)
+
+      finally:
+        resultSet.close ()
+
     return r
 
   # ---------------------------------------------------------------------------
@@ -632,13 +639,17 @@
         resultSet = _createEmptyResultSet (self.__connections,
                                            self.__database,
                                            table, fields.keys ())
-        resultSet.insertRecord ()
+        try:
+          resultSet.insertRecord ()
 
-        for (field, value) in fields.items ():
-           resultSet.current.setField (field, value)
+          for (field, value) in fields.items ():
+             resultSet.current.setField (field, value)
 
-        resultSet.post ()
+          resultSet.post ()
 
+        finally:
+          resultSet.close ()
+
     self.__inserted         = []
     self.__confirmedInserts = []
 
@@ -654,11 +665,15 @@
           resultSet = _find (self.__connections, self.__database, table, row,
                              [u'gnue_id'] + fields.keys ())
 
-          for (field, value) in fields.items ():
-            resultSet.current.setField (field, value)
+          try:
+            for (field, value) in fields.items ():
+              resultSet.current.setField (field, value)
 
-          resultSet.post ()
+            resultSet.post ()
 
+          finally:
+            resultSet.close ()
+
     # perform all deletes
     for (table, row) in self.__deleted:
       # TODO: gnue-common should provide a method for deleting a record
@@ -666,9 +681,13 @@
       # temporary resultSet for every record we delete
       resultSet = _find (self.__connections, self.__database, table, row,
                          [u'gnue_id'])
-      resultSet.current.delete ()
-      resultSet.post ()
+      try:
+        resultSet.current.delete ()
+        resultSet.post ()
 
+      finally:
+        resultSet.close ()
+
     self.__deleted = []
     self.__confirmedDeletes = []
 
@@ -853,6 +872,23 @@
     else:
       return self.__buildRecords ()
 
+
+  # ---------------------------------------------------------------------------
+  # Close the record set
+  # ---------------------------------------------------------------------------
+
+  def close (self):
+    """
+    This function closes a record set which is no longer needed. It closes the
+    underlying result set and clears it's cache.
+    """
+
+    if self.__resultSet is not None:
+      self.__resultSet.close ()
+    self.__resultSet = None
+    self.__cache.clear ()
+
+
 # =============================================================================
 # Record class
 # =============================================================================
@@ -926,13 +962,18 @@
       # Not found in cache, so get it from the db
       resultSet = _find (self.__connections, self.__database, self.__table,
                          self.__row, [field])
-      if resultSet.current is not None:
-        value = resultSet.current [field]
-        self.__cache.write (self.__table, self.__row, field, value, 0)
-        return value
-      else:
-        return None
+      try:
+        if resultSet.current is not None:
+          value = resultSet.current [field]
+          self.__cache.write (self.__table, self.__row, field, value, 0)
+          return value
+        else:
+          return None
 
+      finally:
+        resultSet.close ()
+
+
   # ---------------------------------------------------------------------------
   # Put the value for a field
   # ---------------------------------------------------------------------------
@@ -1054,6 +1095,11 @@
   c.commit ()
   print 'Ok'
 
+  print 'closing record set ...',
+  rs.close ()
+  print 'Ok'
+
+
   print 'connection.query for previously inserted record ...',
   content = {None: (u'address_person', None, None, [u'address_name'])}
   rs = c.query (content,
@@ -1107,6 +1153,10 @@
   c.commit ()
   print 'Ok'
 
+  print 'closing result set ...',
+  rs.close ()
+  print 'Ok'
+
   print 'check if the record is really gone now ...',
   content = {None: (u'address_person', None, None, [u'address_name'])}
   rs = c.query (content,
@@ -1117,6 +1167,10 @@
     raise Exception
   print 'Ok'
 
+  print 'closing result set ...',
+  rs.close ()
+  print 'Ok'
+
   print 'connection.close ...',
   c.close ()
   print 'Ok'

Modified: trunk/gnue-appserver/src/geasList.py
===================================================================
--- trunk/gnue-appserver/src/geasList.py        2004-11-16 11:05:10 UTC (rev 
6681)
+++ trunk/gnue-appserver/src/geasList.py        2004-11-16 15:13:08 UTC (rev 
6682)
@@ -47,11 +47,22 @@
     self.__isComplete = False
     self.__dsSorting  = dsSort          # sorted by datasource 
     self.__asSorting  = asSort          # additional sortorder of this list
+    self.__isClosed   = False
 
+
+
+  # ---------------------------------------------------------------------------
+  # Call the apropriate fillup function
+  # ---------------------------------------------------------------------------
+
+  def __fillupFunc (self, count):
+    """
+    """
+
     if len (self.__asSorting):
-      self.__fillup = self.__fillupSorted
+      return self.__fillupSorted (count)
     else:
-      self.__fillup = self.__fillupUnsorted
+      return self.__fillupUnsorted (count)
 
 
   # ---------------------------------------------------------------------------
@@ -155,6 +166,8 @@
       return instance
 
     else:
+      self.__recordset.close ()
+      self.__isClosed = True
       return None
 
 
@@ -196,7 +209,7 @@
     This function returns the number of instances available in this list.
     """
     if self.__condition is not None:
-      self.__fillup (0)
+      self.__fillupFunc (0)
       return len (self.__instances)
     else:
       return self.__recordset.count ()
@@ -213,9 +226,9 @@
     """
 
     if start < 0:
-      self.__fillup (0)
+      self.__fillupFunc (0)
     else:
-      self.__fillup (start + count)
+      self.__fillupFunc (start + count)
 
     result = []
     for pos in range (start, min (start + count, len (self.__instances))):
@@ -224,3 +237,18 @@
     return result
 
 
+  # ---------------------------------------------------------------------------
+  # Close the list instance
+  # ---------------------------------------------------------------------------
+
+  def close (self):
+    """
+    This function closes the list by freeing all references and resources
+    maintained by the list.
+    """
+
+    if not self.__isClosed:
+      self.__recordset.close ()
+
+    self.__instances  = []
+    self.__unsorted   = []

Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py     2004-11-16 11:05:10 UTC (rev 
6681)
+++ trunk/gnue-appserver/src/geasSession.py     2004-11-16 15:13:08 UTC (rev 
6682)
@@ -91,7 +91,7 @@
   # Initalize
   # ---------------------------------------------------------------------------
 
-  def __init__ (self, connections, authAdapter, sm, id, params):
+  def __init__ (self, connections, authAdapter, sm, sid, params):
 
     self.loggedIn = 0
     self.connections = connections
@@ -108,7 +108,7 @@
     self.__operation      = None
 
     self.sm     = sm                        # The session manager
-    self.id     = id                        # The session id
+    self.id     = sid                       # The session id
     self.parameters = params
     self.locale  = params.get ('language')
     self.user    = None
@@ -254,10 +254,25 @@
     if self.locale:
       i18n.setcurrentlocale (self.locale)
 
+    for item in self.__lists.values ():
+      item.close ()
+
+    self.__lists          = {}
+    self.__listcount      = 0
+    self.__dirtyInstances = {}
+    self.filters          = {}
+
     # FIXME: should the authAdapter be contacted?
     self.__connection.close ()
     self.loggedIn = 0
 
+    self.__connection     = None
+    self.__operation      = None
+
+    self.sm               = None
+    self.parameters       = None
+
+
   # ---------------------------------------------------------------------------
   # Commit the active transaction
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-common/src/datasources/GConnections.py
===================================================================
--- trunk/gnue-common/src/datasources/GConnections.py   2004-11-16 11:05:10 UTC 
(rev 6681)
+++ trunk/gnue-common/src/datasources/GConnections.py   2004-11-16 15:13:08 UTC 
(rev 6682)
@@ -275,12 +275,6 @@
 
     conn.introspector = behavior (conn)
 
-    # Create the schema creator instance
-    if hasattr (conn, 'defaultCreator'):
-      conn.schemaCreator = conn.defaultCreator (conn, conn.introspector)
-    else:
-      conn.schemaCreator = None
-
     if login:
       self.loginToConnection (conn)
 
@@ -479,6 +473,7 @@
     connection.__connected = True
 
 
+
   def getAuthenticatedUser(self, connection=None):
     try:
       if connection == None:
@@ -510,5 +505,9 @@
     This function closes all open connections.
     """
     for connection in self._openConnections.values():
-      connection.close()
+      connection.close ()
+
+      if self._authenticatedUsers.has_key (connection):
+        del self._authenticatedUsers [connection]
+
     self._openConnections = {}

Modified: trunk/gnue-common/src/datasources/GDataSource.py
===================================================================
--- trunk/gnue-common/src/datasources/GDataSource.py    2004-11-16 11:05:10 UTC 
(rev 6681)
+++ trunk/gnue-common/src/datasources/GDataSource.py    2004-11-16 15:13:08 UTC 
(rev 6682)
@@ -690,7 +690,7 @@
     return self._dataObject._connection.introspector
 
   def getSchemaCreator (self):
-    return self._dataObject._connection.schemaCreator
+    return self._dataObject._connection.getSchemaCreator ()
 
 
 # =============================================================================

Modified: trunk/gnue-common/src/datasources/drivers/Base/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/Connection.py        
2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-common/src/datasources/drivers/Base/Connection.py        
2004-11-16 15:13:08 UTC (rev 6682)
@@ -70,6 +70,22 @@
 
 
   # ---------------------------------------------------------------------------
+  # Create a new instance of the associated schema creator
+  # ---------------------------------------------------------------------------
+
+  def getSchemaCreator (self):
+    """
+    This function creates a new instance of the schema creator associated with
+    this driver or None if no creator is available.
+    """
+
+    if hasattr (self, 'defaultCreator') and self.defaultCreator:
+      return self.defaultCreator (self)
+    else:
+      return None
+
+
+  # ---------------------------------------------------------------------------
   # update the schema definition 
   # ---------------------------------------------------------------------------
 
@@ -89,118 +105,123 @@
 
     result = ([], [], [])
 
-    if self.schemaCreator is None:
+    schemaCreator = self.getSchemaCreator ()
+
+    if schemaCreator is None:
       return result
 
-    workingSet    = copy.copy (definition)
-    constraintSet = {}
+    try:
+      workingSet    = copy.copy (definition)
+      constraintSet = {}
 
-    # before any actions are performed, validate the given definitions
-    for table in definition:
-      self.schemaCreator.validate (table)
+      # before any actions are performed, validate the given definitions
+      for table in definition:
+        schemaCreator.validate (table)
 
-    # in a first run we remove all constraint definitions from the tables, so
-    # we can add or alter all tables without having troubles with order of
-    # occurence.
-    for table in workingSet:
-      # Do we have already a table with that name?
-      res = self.introspector.find (name = table ['name'])
+      # in a first run we remove all constraint definitions from the tables, so
+      # we can add or alter all tables without having troubles with order of
+      # occurence.
+      for table in workingSet:
+        # Do we have already a table with that name?
+        res = self.introspector.find (name = table ['name'])
 
-      if res is not None:
-        method = self.schemaCreator.modifyTable
-        # Please note: we keep existingFields sequence in all lowercase
-        existingFields = [f.name.lower () for f in res [0].fields ()]
+        if res is not None:
+          method = schemaCreator.modifyTable
+          # Please note: we keep existingFields sequence in all lowercase
+          existingFields = [f.name.lower () for f in res [0].fields ()]
 
-        # keep only new fields
-        keep = []
-        for field in table ['fields']:
-          if not field ['name'].lower () in existingFields:
-            keep.append (field)
+          # keep only new fields
+          keep = []
+          for field in table ['fields']:
+            if not field ['name'].lower () in existingFields:
+              keep.append (field)
 
-        table ['fields'] = keep
+          table ['fields'] = keep
 
-        # on updates of a table we cannot use a primary key
-        if table.has_key ('primarykey'):
-          del table ['primarykey']
+          # on updates of a table we cannot use a primary key
+          if table.has_key ('primarykey'):
+            del table ['primarykey']
+  
+          # keep modified or new indices only
+          if table.has_key ('indices'):
+            keep = []
 
-        # keep modified or new indices only
-        if table.has_key ('indices'):
-          keep = []
+            # if driver supports index-introspection we'll use it
+            if hasattr (res [0], 'indices'):
+              for index in table ['indices']:
+                oldIndex = None
+                for (name, value) in res [0].indices.items ():
+                  if name.lower () == index ['name'].lower ():
+                    oldIndex = value
 
-          # if driver supports index-introspection we'll use it
-          if hasattr (res [0], 'indices'):
-            for index in table ['indices']:
-              oldIndex = None
-              for (name, value) in res [0].indices.items ():
-                if name.lower () == index ['name'].lower ():
-                  oldIndex = value
+                if oldIndex is None:
+                  keep.append (index)
+                else:
+                  old = [f.lower () for f in oldIndex ['fields']]
+                  new = [f.lower () for f in index ['fields']]
 
-              if oldIndex is None:
-                keep.append (index)
-              else:
-                old = [f.lower () for f in oldIndex ['fields']]
-                new = [f.lower () for f in index ['fields']]
+                  if oldIndex ['unique'] != index ['unique'] or old != new:
 
-                if oldIndex ['unique'] != index ['unique'] or old != new:
+                    # make sure the backend has a possibility to remove the old
+                    # index before changing it
+                    if not table.has_key ('old_indices'):
+                      table ['old_indices'] = []
+                    table ['old_indices'].append (index ['name'])
 
-                  # make sure the backend has a possibility to remove the old
-                  # index before changing it
-                  if not table.has_key ('old_indices'):
-                    table ['old_indices'] = []
-                  table ['old_indices'].append (index ['name'])
+                    keep.append (index)
+            else:
+              # if no index-introspection available we only keep an index, if 
it
+              # has new fields
+              for index in table ['indices']:
+                for field in index ['fields']:
+                  if not field.lower () in existingFields:
+                    # make sure the backend has a possibility to remove the old
+                    # index before changing it
+                    if not table.has_key ('old_indices'):
+                      table ['old_indices'] = []
+                    table ['old_indices'].append (index ['name'])
 
-                  keep.append (index)
-          else:
-            # if no index-introspection available we only keep an index, if it
-            # has new fields
-            for index in table ['indices']:
-              for field in index ['fields']:
-                if not field.lower () in existingFields:
-                  # make sure the backend has a possibility to remove the old
-                  # index before changing it
-                  if not table.has_key ('old_indices'):
-                    table ['old_indices'] = []
-                  table ['old_indices'].append (index ['name'])
+                    keep.append (index)
+                    break
 
-                  keep.append (index)
-                  break
+            table ['indices'] = keep
 
-          table ['indices'] = keep
+          # we create a constraint on a table update only if it contains new
+          # fields
+          if table.has_key ('constraints'):
+            keep = []
 
-        # we create a constraint on a table update only if it contains new
-        # fields
-        if table.has_key ('constraints'):
-          keep = []
+            for constraint in table ['constraints']:
+              for field in constraint ['fields']:
+                if not field.lower () in existingFields:
+                  keep.append (constraint)
+                  break
 
-          for constraint in table ['constraints']:
-            for field in constraint ['fields']:
-              if not field.lower () in existingFields:
-                keep.append (constraint)
-                break
+            table ['constraints'] = keep
 
-          table ['constraints'] = keep
+        else:
+          method = schemaCreator.createTable
 
-      else:
-        method = self.schemaCreator.createTable
-
-      if table.has_key ('constraints'):
-        constraintSet [table ['name']] = {'name':        table ['name'],
+        if table.has_key ('constraints'):
+          constraintSet [table ['name']] = {'name':        table ['name'],
                                           'constraints': table ['constraints']}
-        del table ['constraints']
+          del table ['constraints']
 
-      # before we execute the planned action, have a look if there's still work
-      # to be done
-      perform = table.has_key ('fields') and len (table ['fields'])
-      perform = perform or table.has_key ('primarykey')
-      perform = perform or (table.has_key ('indices') and \
-                            len (table ['indices']))
+        # before we execute the planned action, have a look if there's still
+        # work to be done
+        perform = table.has_key ('fields') and len (table ['fields'])
+        perform = perform or table.has_key ('primarykey')
+        perform = perform or (table.has_key ('indices') and \
+                              len (table ['indices']))
 
-      if perform:
-        self.schemaCreator.mergeTuple (result, method (table, codeOnly))
+        if perform:
+          schemaCreator.mergeTuple (result, method (table, codeOnly))
 
-    # on the second run we process all constraints
-    for table in constraintSet.values ():
-      self.schemaCreator.mergeTuple (result,
-                              self.schemaCreator.createTable (table, codeOnly))
+      # on the second run we process all constraints
+      for table in constraintSet.values ():
+        schemaCreator.mergeTuple (result,
+                                schemaCreator.createTable (table, codeOnly))
+      return result
 
-    return result
+    finally:
+      schemaCreator.close ()

Modified: trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2004-11-16 
11:05:10 UTC (rev 6681)
+++ trunk/gnue-common/src/datasources/drivers/Base/ResultSet.py 2004-11-16 
15:13:08 UTC (rev 6682)
@@ -222,7 +222,24 @@
       self.__notifyListeners ()
       return self.current
 
+  # ---------------------------------------------------------------------------
+  # Close the result set
+  # ---------------------------------------------------------------------------
 
+  def close (self):
+    """
+    This function should be closed, if a result set is no longer needed. It
+    breaks up reference cycles so garbage collection can do it's job.
+    """
+
+    for item in self._cachedRecords:
+      item._parent = None
+
+    self._dataObject    = None
+    self._cachedRecords = []
+    self.__listeners    = []
+
+
   def duplicateRecord(self, exclude=(), include=()):
     current = self.current
     inserted = self.insertRecord()

Modified: 
trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py  
2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py  
2004-11-16 15:13:08 UTC (rev 6682)
@@ -329,7 +329,20 @@
         self._validateConstraint (tableName, constraint)
 
 
+  # ---------------------------------------------------------------------------
+  # Make sure to release all references
+  # ---------------------------------------------------------------------------
 
+  def close (self):
+    """
+    This function releases all circular references held by the creator instance
+    """
+
+    self.introspector = None
+    self.connection   = None
+    self.lookup       = {}
+
+
   # ---------------------------------------------------------------------------
   # Call the appropriate method for a type-transformation
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py      
2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-common/src/datasources/drivers/DBSIG2/Connection.py      
2004-11-16 15:13:08 UTC (rev 6682)
@@ -100,7 +100,8 @@
     """
     Close the DBSIG2 Connection.
     """
-    self.native.close()
+    if hasattr (self, 'native') and self.native is not None:
+      self.native.close ()
     
     
   def _beginTransaction(self):

Modified: 
trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py 
2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py 
2004-11-16 15:13:08 UTC (rev 6682)
@@ -144,7 +144,8 @@
   # ---------------------------------------------------------------------------
 
   def close (self):
-    self._sm.close (self._sess_id, False)
+    if self._sm is not None:
+      self._sm.close (self._sess_id, False)
 
   # Can be removed after the call to _dataConnection.cursor() is removed from
   # the Base driver
@@ -206,7 +207,6 @@
             break
 
         if not found:
-          print "shit"
           raise Exceptions.LoginError, \
               u_("'%(value)s' is not a valid filter-value for '%(filter)s'") \
               % {'value': value,

Modified: trunk/gnue-common/src/schema/scripter/Scripter.py
===================================================================
--- trunk/gnue-common/src/schema/scripter/Scripter.py   2004-11-16 11:05:10 UTC 
(rev 6681)
+++ trunk/gnue-common/src/schema/scripter/Scripter.py   2004-11-16 15:13:08 UTC 
(rev 6682)
@@ -140,9 +140,14 @@
           self.verifyDataKeys ()
 
         if self.OPTIONS ['createdb']:
-          if self.connection.schemaCreator is not None:
-            self.connection.schemaCreator.createDatabase ()
+          creator = self.connection.getSchemaCreator ()
+          if creator is not None:
+            try:
+              creator.createDatabase ()
 
+            finally:
+              creator.close ()
+
         if self.__doSchema:
           self.executeAndGenerateCode ()
 

Modified: trunk/gnue-forms/src/GFClient.py
===================================================================
--- trunk/gnue-forms/src/GFClient.py    2004-11-16 11:05:10 UTC (rev 6681)
+++ trunk/gnue-forms/src/GFClient.py    2004-11-16 15:13:08 UTC (rev 6682)
@@ -158,7 +158,9 @@
     instance.addDialogs ()
     instance.activate ()
 
+    self.getConnectionManager ().closeAll ()
 
+
   # ---------------------------------------------------------------------------
   # List all available user interfaces
   # ---------------------------------------------------------------------------





reply via email to

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