]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/dbconn.py
make it safer to do from daklib.dbconn import *
[dak.git] / daklib / dbconn.py
index 3a11c2a1de531c11230f2638ddf3bee02d23e94e..f1988ca649d22b5cc6ed6e5b82fbb610ffa13beb 100755 (executable)
@@ -40,10 +40,17 @@ import traceback
 from sqlalchemy import create_engine, Table, MetaData, select
 from sqlalchemy.orm import sessionmaker, mapper, relation
 
+# Don't remove this, we re-export the exceptions to scripts which import us
+from sqlalchemy.exc import *
+
 from singleton import Singleton
 
 ################################################################################
 
+__all__ = []
+
+################################################################################
+
 class Architecture(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -51,6 +58,8 @@ class Architecture(object):
     def __repr__(self):
         return '<Architecture %s>' % self.arch_string
 
+__all__.append('Architecture')
+
 def get_architecture(architecture, session=None):
     """
     Returns database id for given C{architecture}.
@@ -73,6 +82,33 @@ def get_architecture(architecture, session=None):
         return None
     return q.one()
 
+__all__.append('get_architecture')
+
+def get_architecture_suites(architecture, session=None):
+    """
+    Returns list of Suite objects for given C{architecture} name
+
+    @type source: str
+    @param source: Architecture name to search for
+
+    @type session: Session
+    @param session: Optional SQL session object (a temporary one will be
+    generated if not supplied)
+
+    @rtype: list
+    @return: list of Suite objects for the given name (may be empty)
+    """
+
+    if session is None:
+        session = DBConn().session()
+
+    q = session.query(Suite)
+    q = q.join(SuiteArchitecture)
+    q = q.join(Architecture).filter_by(arch_string=architecture).order_by('suite_name')
+    return q.all()
+
+__all__.append('get_architecture_suites')
+
 class Archive(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -80,6 +116,8 @@ class Archive(object):
     def __repr__(self):
         return '<Archive %s>' % self.name
 
+__all__.append('Archive')
+
 def get_archive(archive, session=None):
     """
     returns database id for given c{archive}.
@@ -103,6 +141,7 @@ def get_archive(archive, session=None):
         return None
     return q.one()
 
+__all__.append('get_archive')
 
 class BinAssociation(object):
     def __init__(self, *args, **kwargs):
@@ -111,6 +150,8 @@ class BinAssociation(object):
     def __repr__(self):
         return '<BinAssociation %s (%s, %s)>' % (self.ba_id, self.binary, self.suite)
 
+__all__.append('BinAssociation')
+
 class Binary(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -118,6 +159,8 @@ class Binary(object):
     def __repr__(self):
         return '<Binary %s (%s, %s)>' % (self.package, self.version, self.architecture)
 
+__all__.append('Binary')
+
 def get_binary_from_id(id, session=None):
     """
     Returns Binary object for given C{id}
@@ -139,6 +182,28 @@ def get_binary_from_id(id, session=None):
         return None
     return q.one()
 
+__all__.append('get_binary_from_id')
+
+def get_binaries_from_name(package, session=None):
+    """
+    Returns list of Binary objects for given C{package} name
+
+    @type package: str
+    @param package: Binary package name to search for
+
+    @type session: Session
+    @param session: Optional SQL session object (a temporary one will be
+    generated if not supplied)
+
+    @rtype: list
+    @return: list of Binary objects for the given name (may be empty)
+    """
+    if session is None:
+        session = DBConn().session()
+    return session.query(Binary).filter_by(package=package).all()
+
+__all__.append('get_binaries_from_name')
+
 class Component(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -146,6 +211,9 @@ class Component(object):
     def __repr__(self):
         return '<Component %s>' % self.component_name
 
+
+__all__.append('Component')
+
 def get_component(component, session=None):
     """
     Returns database id for given C{component}.
@@ -165,6 +233,8 @@ def get_component(component, session=None):
         return None
     return q.one()
 
+__all__.append('get_component')
+
 class DBConfig(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -172,6 +242,8 @@ class DBConfig(object):
     def __repr__(self):
         return '<DBConfig %s>' % self.name
 
+__all__.append('DBConfig')
+
 class ContentFilename(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -179,6 +251,8 @@ class ContentFilename(object):
     def __repr__(self):
         return '<ContentFilename %s>' % self.filename
 
+__all__.append('ContentFilename')
+
 class ContentFilepath(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -186,13 +260,17 @@ class ContentFilepath(object):
     def __repr__(self):
         return '<ContentFilepath %s>' % self.filepath
 
-class ContentAssociations(object):
+__all__.append('ContentFilepath')
+
+class ContentAssociation(object):
     def __init__(self, *args, **kwargs):
         pass
 
     def __repr__(self):
         return '<ContentAssociation %s>' % self.ca_id
 
+__all__.append('ContentAssociation')
+
 class DSCFile(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -200,6 +278,8 @@ class DSCFile(object):
     def __repr__(self):
         return '<DSCFile %s>' % self.dscfile_id
 
+__all__.append('DSCFile')
+
 class PoolFile(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -207,6 +287,8 @@ class PoolFile(object):
     def __repr__(self):
         return '<PoolFile %s>' % self.filename
 
+__all__.append('PoolFile')
+
 class Fingerprint(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -214,6 +296,8 @@ class Fingerprint(object):
     def __repr__(self):
         return '<Fingerprint %s>' % self.fingerprint
 
+__all__.append('Fingerprint')
+
 class Keyring(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -221,6 +305,8 @@ class Keyring(object):
     def __repr__(self):
         return '<Keyring %s>' % self.keyring_name
 
+__all__.append('Keyring')
+
 class Location(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -228,6 +314,8 @@ class Location(object):
     def __repr__(self):
         return '<Location %s (%s)>' % (self.path, self.location_id)
 
+__all__.append('Location')
+
 class Maintainer(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -235,6 +323,8 @@ class Maintainer(object):
     def __repr__(self):
         return '''<Maintainer '%s' (%s)>''' % (self.name, self.maintainer_id)
 
+__all__.append('Maintainer')
+
 class Override(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -242,6 +332,8 @@ class Override(object):
     def __repr__(self):
         return '<Override %s (%s)>' % (self.package, self.suite_id)
 
+__all__.append('Override')
+
 class OverrideType(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -249,6 +341,8 @@ class OverrideType(object):
     def __repr__(self):
         return '<OverrideType %s>' % self.overridetype
 
+__all__.append('OverrideType')
+
 def get_override_type(override_type, session=None):
     """
     Returns OverrideType object for given C{override type}.
@@ -271,6 +365,8 @@ def get_override_type(override_type, session=None):
         return None
     return q.one()
 
+__all__.append('get_override_type')
+
 class PendingContentAssociation(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -278,6 +374,8 @@ class PendingContentAssociation(object):
     def __repr__(self):
         return '<PendingContentAssociation %s>' % self.pca_id
 
+__all__.append('PendingContentAssociation')
+
 class Priority(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -285,6 +383,8 @@ class Priority(object):
     def __repr__(self):
         return '<Priority %s (%s)>' % (self.priority, self.priority_id)
 
+__all__.append('Priority')
+
 def get_priority(priority, session=None):
     """
     Returns Priority object for given C{priority name}.
@@ -307,6 +407,8 @@ def get_priority(priority, session=None):
         return None
     return q.one()
 
+__all__.append('get_priority')
+
 class Queue(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -314,6 +416,8 @@ class Queue(object):
     def __repr__(self):
         return '<Queue %s>' % self.queue_name
 
+__all__.append('Queue')
+
 class QueueBuild(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -321,6 +425,8 @@ class QueueBuild(object):
     def __repr__(self):
         return '<QueueBuild %s (%s)>' % (self.filename, self.queue_id)
 
+__all__.append('QueueBuild')
+
 class Section(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -328,6 +434,8 @@ class Section(object):
     def __repr__(self):
         return '<Section %s>' % self.section
 
+__all__.append('Section')
+
 def get_section(section, session=None):
     """
     Returns Section object for given C{section name}.
@@ -350,6 +458,8 @@ def get_section(section, session=None):
         return None
     return q.one()
 
+__all__.append('get_section')
+
 class Source(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -357,6 +467,28 @@ class Source(object):
     def __repr__(self):
         return '<Source %s (%s)>' % (self.source, self.version)
 
+__all__.append('Source')
+
+def get_sources_from_name(source, session=None):
+    """
+    Returns list of Source objects for given C{source} name
+
+    @type source: str
+    @param source: Source package name to search for
+
+    @type session: Session
+    @param session: Optional SQL session object (a temporary one will be
+    generated if not supplied)
+
+    @rtype: list
+    @return: list of Source objects for the given name (may be empty)
+    """
+    if session is None:
+        session = DBConn().session()
+    return session.query(Source).filter_by(source=source).all()
+
+__all__.append('get_sources_from_name')
+
 def get_source_in_suite(source, suite, session=None):
     """
     Returns list of Source objects for a combination of C{source} and C{suite}.
@@ -384,6 +516,8 @@ def get_source_in_suite(source, suite, session=None):
     # ???: Maybe we should just return the SrcAssociation object instead
     return q.one().source
 
+__all__.append('get_source_in_suite')
+
 class SrcAssociation(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -391,6 +525,8 @@ class SrcAssociation(object):
     def __repr__(self):
         return '<SrcAssociation %s (%s, %s)>' % (self.sa_id, self.source, self.suite)
 
+__all__.append('SrcAssociation')
+
 class SrcUploader(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -398,6 +534,8 @@ class SrcUploader(object):
     def __repr__(self):
         return '<SrcUploader %s>' % self.uploader_id
 
+__all__.append('SrcUploader')
+
 class Suite(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -405,6 +543,39 @@ class Suite(object):
     def __repr__(self):
         return '<Suite %s>' % self.suite_name
 
+__all__.append('Suite')
+
+def get_suite_architecture(suite, architecture, session=None):
+    """
+    Returns a SuiteArchitecture object given C{suite} and ${arch} or None if it
+    doesn't exist
+
+    @type suite: str
+    @param suite: Suite name to search for
+
+    @type architecture: str
+    @param architecture: Architecture name to search for
+
+    @type session: Session
+    @param session: Optional SQL session object (a temporary one will be
+    generated if not supplied)
+
+    @rtype: SuiteArchitecture
+    @return: the SuiteArchitecture object or None
+    """
+
+    if session is None:
+        session = DBConn().session()
+
+    q = session.query(SuiteArchitecture)
+    q = q.join(Architecture).filter_by(arch_string=architecture)
+    q = q.join(Suite).filter_by(suite_name=suite)
+    if q.count() == 0:
+        return None
+    return q.one()
+
+__all__.append('get_suite_architecture')
+
 def get_suite(suite, session=None):
     """
     Returns Suite object for given C{suite name}.
@@ -427,6 +598,8 @@ def get_suite(suite, session=None):
         return None
     return q.one()
 
+__all__.append('get_suite')
+
 class SuiteArchitecture(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -434,6 +607,33 @@ class SuiteArchitecture(object):
     def __repr__(self):
         return '<SuiteArchitecture (%s, %s)>' % (self.suite_id, self.arch_id)
 
+__all__.append('SuiteArchitecture')
+
+def get_suite_architectures(suite, session=None):
+    """
+    Returns list of Architecture objects for given C{suite} name
+
+    @type source: str
+    @param source: Suite name to search for
+
+    @type session: Session
+    @param session: Optional SQL session object (a temporary one will be
+    generated if not supplied)
+
+    @rtype: list
+    @return: list of Architecture objects for the given name (may be empty)
+    """
+
+    if session is None:
+        session = DBConn().session()
+
+    q = session.query(Architecture)
+    q = q.join(SuiteArchitecture)
+    q = q.join(Suite).filter_by(suite_name=suite).order_by('arch_string')
+    return q.all()
+
+__all__.append('get_suite_architectures')
+
 class Uid(object):
     def __init__(self, *args, **kwargs):
         pass
@@ -441,6 +641,8 @@ class Uid(object):
     def __repr__(self):
         return '<Uid %s (%s)>' % (self.uid, self.name)
 
+__all__.append('Uid')
+
 ################################################################################
 
 class DBConn(Singleton):
@@ -527,7 +729,7 @@ class DBConn(Singleton):
         mapper(DBConfig, self.tbl_config,
                properties = dict(config_id = self.tbl_config.c.id))
 
-        mapper(ContentAssociations, self.tbl_content_associations,
+        mapper(ContentAssociation, self.tbl_content_associations,
                properties = dict(ca_id = self.tbl_content_associations.c.id,
                                  filename_id = self.tbl_content_associations.c.filename,
                                  filename    = relation(ContentFilename),
@@ -684,7 +886,7 @@ class DBConn(Singleton):
         self.db_meta.bind = self.db_pg
         self.db_smaker = sessionmaker(bind=self.db_pg,
                                       autoflush=True,
-                                      transactional=True)
+                                      autocommit=False)
 
         self.__setuptables()
         self.__setupmappers()
@@ -856,31 +1058,6 @@ def get_or_set_contents_path_id(self, path):
         traceback.print_exc()
         raise
 
-def get_suite_architectures(self, suite):
-    """
-    Returns list of architectures for C{suite}.
-
-    @type suite: string, int
-    @param suite: the suite name or the suite_id
-
-    @rtype: list
-    @return: the list of architectures for I{suite}
-    """
-
-    suite_id = None
-    if type(suite) == str:
-        suite_id = self.get_suite_id(suite)
-    elif type(suite) == int:
-        suite_id = suite
-    else:
-        return None
-
-    c = self.db_con.cursor()
-    c.execute( """SELECT a.arch_string FROM suite_architectures sa
-                  JOIN architecture a ON (a.id = sa.architecture)
-                  WHERE suite='%s'""" % suite_id )
-
-    return map(lambda x: x[0], c.fetchall())
 
 def insert_content_paths(self, bin_id, fullpaths):
     """