]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/dbconn.py
Convert dbconn.py to db upgrade #41.
[dak.git] / daklib / dbconn.py
index e8a68390c5989bfdffbc655785c413c1d550f33f..f0049a1a0c1addb7422bef47841cfff45218c9f9 100755 (executable)
@@ -55,7 +55,7 @@ from inspect import getargspec
 import sqlalchemy
 from sqlalchemy import create_engine, Table, MetaData, Column, Integer, desc
 from sqlalchemy.orm import sessionmaker, mapper, relation, object_session, \
-    backref, MapperExtension, EXT_CONTINUE
+    backref, MapperExtension, EXT_CONTINUE, object_mapper
 from sqlalchemy import types as sqltypes
 
 # Don't remove this, we re-export the exceptions to scripts which import us
@@ -287,6 +287,50 @@ class ORMObject(object):
         '''
         return session.query(cls).get(primary_key)
 
+    def session(self, replace = False):
+        '''
+        Returns the current session that is associated with the object. May
+        return None is object is in detached state.
+        '''
+
+        return object_session(self)
+
+    def clone(self, session = None):
+        '''
+        Clones the current object in a new session and returns the new clone. A
+        fresh session is created if the optional session parameter is not
+        provided. The function will fail if a session is provided and has
+        unflushed changes.
+
+        RATIONALE: SQLAlchemy's session is not thread safe. This method clones
+        an existing object to allow several threads to work with their own
+        instances of an ORMObject.
+
+        WARNING: Only persistent (committed) objects can be cloned. Changes
+        made to the original object that are not committed yet will get lost.
+        The session of the new object will always be rolled back to avoid
+        ressource leaks.
+        '''
+
+        if self.session() is None:
+            raise RuntimeError( \
+                'Method clone() failed for detached object:\n%s' % self)
+        self.session().flush()
+        mapper = object_mapper(self)
+        primary_key = mapper.primary_key_from_instance(self)
+        object_class = self.__class__
+        if session is None:
+            session = DBConn().session()
+        elif len(session.new) + len(session.dirty) + len(session.deleted) > 0:
+            raise RuntimeError( \
+                'Method clone() failed due to unflushed changes in session.')
+        new_object = session.query(object_class).get(primary_key)
+        session.rollback()
+        if new_object is None:
+            raise RuntimeError( \
+                'Method clone() failed for non-persistent object:\n%s' % self)
+        return new_object
+
 __all__.append('ORMObject')
 
 ################################################################################
@@ -1161,7 +1205,7 @@ class PoolFile(ORMObject):
     def fullpath(self):
         return os.path.join(self.location.path, self.filename)
 
-    def is_valid(self, filesize = -1, md5sum = None):\
+    def is_valid(self, filesize = -1, md5sum = None):
         return self.filesize == long(filesize) and self.md5sum == md5sum
 
     def properties(self):
@@ -1583,7 +1627,8 @@ class Location(ORMObject):
         self.archive_type = 'pool'
 
     def properties(self):
-        return ['path', 'archive_type', 'component', 'files_count']
+        return ['path', 'location_id', 'archive_type', 'component', \
+            'files_count']
 
     def not_null_constraints(self):
         return ['path', 'archive_type']
@@ -2859,8 +2904,8 @@ class DBConn(object):
             # The following tables have primary keys but sqlalchemy
             # version 0.5 fails to reflect them correctly with database
             # versions before upgrade #41.
-            #'changes',
-            #'build_queue_files',
+            'changes',
+            'build_queue_files',
         )
 
         tables_no_primary = (
@@ -2875,8 +2920,8 @@ class DBConn(object):
             'suite_build_queue_copy',
             'udeb_contents',
             # see the comment above
-            'changes',
-            'build_queue_files',
+            #'changes',
+            #'build_queue_files',
         )
 
         views = (