X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fdbconn.py;h=72453f643d26dc35b768395d5d9886264d49b3eb;hb=4830d9be143c7645ea932b53fae095e275ad7814;hp=786aebded82e5c35a5c51a057a7b682d2ab7900b;hpb=ec257c02a5d62fd27844c70814acd9616b24b4c8;p=dak.git diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 786aebde..72453f64 100755 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -46,7 +46,7 @@ from inspect import getargspec import sqlalchemy from sqlalchemy import create_engine, Table, MetaData, Column, Integer -from sqlalchemy.orm import sessionmaker, mapper, relation +from sqlalchemy.orm import sessionmaker, mapper, relation, object_session from sqlalchemy import types as sqltypes # Don't remove this, we re-export the exceptions to scripts which import us @@ -59,19 +59,39 @@ from config import Config from textutils import fix_maintainer from dak_exceptions import NoSourceFieldError +# suppress some deprecation warnings in squeeze related to sqlalchemy +import warnings +warnings.filterwarnings('ignore', \ + "The SQLAlchemy PostgreSQL dialect has been renamed from 'postgres' to 'postgresql'.*", \ + SADeprecationWarning) +# TODO: sqlalchemy needs some extra configuration to correctly reflect +# the ind_deb_contents_* indexes - we ignore the warnings at the moment +warnings.filterwarnings("ignore", 'Predicate of partial index', SAWarning) + + ################################################################################ # Patch in support for the debversion field type so that it works during # reflection -class DebVersion(sqltypes.Text): - """ - Support the debversion type - """ +try: + # that is for sqlalchemy 0.6 + UserDefinedType = sqltypes.UserDefinedType +except: + # this one for sqlalchemy 0.5 + UserDefinedType = sqltypes.TypeEngine +class DebVersion(UserDefinedType): def get_col_spec(self): return "DEBVERSION" + def bind_processor(self, dialect): + return None + + # ' = None' is needed for sqlalchemy 0.5: + def result_processor(self, dialect, coltype = None): + return None + sa_major_version = sqlalchemy.__version__[0:3] if sa_major_version in ["0.5", "0.6"]: from sqlalchemy.databases import postgres @@ -81,7 +101,7 @@ else: ################################################################################ -__all__ = ['IntegrityError', 'SQLAlchemyError'] +__all__ = ['IntegrityError', 'SQLAlchemyError', 'DebVersion'] ################################################################################ @@ -137,8 +157,9 @@ __all__.append('session_wrapper') ################################################################################ class Architecture(object): - def __init__(self, *args, **kwargs): - pass + def __init__(self, arch_string = None, description = None): + self.arch_string = arch_string + self.description = description def __eq__(self, val): if isinstance(val, str): @@ -182,6 +203,7 @@ def get_architecture(architecture, session=None): __all__.append('get_architecture') +# TODO: should be removed because the implementation is too trivial @session_wrapper def get_architecture_suites(architecture, session=None): """ @@ -198,13 +220,7 @@ def get_architecture_suites(architecture, session=None): @return: list of Suite objects for the given name (may be empty) """ - q = session.query(Suite) - q = q.join(SuiteArchitecture) - q = q.join(Architecture).filter_by(arch_string=architecture).order_by('suite_name') - - ret = q.all() - - return ret + return get_architecture(architecture, session).suites __all__.append('get_architecture_suites') @@ -1216,8 +1232,8 @@ __all__.append('add_poolfile') ################################################################################ class Fingerprint(object): - def __init__(self, *args, **kwargs): - pass + def __init__(self, fingerprint = None): + self.fingerprint = fingerprint def __repr__(self): return '' % self.fingerprint @@ -2491,8 +2507,9 @@ SUITE_FIELDS = [ ('SuiteName', 'suite_name'), ('OverrideSuite', 'overridesuite')] class Suite(object): - def __init__(self, *args, **kwargs): - pass + def __init__(self, suite_name = None, version = None): + self.suite_name = suite_name + self.version = version def __repr__(self): return '' % self.suite_name @@ -2518,38 +2535,31 @@ class Suite(object): return "\n".join(ret) -__all__.append('Suite') + def get_architectures(self, skipsrc=False, skipall=False): + """ + Returns list of Architecture objects -@session_wrapper -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 skipsrc: boolean + @param skipsrc: Whether to skip returning the 'source' architecture entry + (Default False) - @type suite: str - @param suite: Suite name to search for + @type skipall: boolean + @param skipall: Whether to skip returning the 'all' architecture entry + (Default False) - @type architecture: str - @param architecture: Architecture name to search for + @rtype: list + @return: list of Architecture objects for the given name (may be empty) + """ - @type session: Session - @param session: Optional SQL session object (a temporary one will be - generated if not supplied) + q = object_session(self).query(Architecture). \ + filter(Architecture.suites.contains(self)) + if skipsrc: + q = q.filter(Architecture.arch_string != 'source') + if skipall: + q = q.filter(Architecture.arch_string != 'all') + return q.order_by(Architecture.arch_string).all() - @rtype: SuiteArchitecture - @return: the SuiteArchitecture object or None - """ - - q = session.query(SuiteArchitecture) - q = q.join(Architecture).filter_by(arch_string=architecture) - q = q.join(Suite).filter_by(suite_name=suite) - - try: - return q.one() - except NoResultFound: - return None - -__all__.append('get_suite_architecture') +__all__.append('Suite') @session_wrapper def get_suite(suite, session=None): @@ -2578,15 +2588,7 @@ __all__.append('get_suite') ################################################################################ -class SuiteArchitecture(object): - def __init__(self, *args, **kwargs): - pass - - def __repr__(self): - return '' % (self.suite_id, self.arch_id) - -__all__.append('SuiteArchitecture') - +# TODO: should be removed because the implementation is too trivial @session_wrapper def get_suite_architectures(suite, skipsrc=False, skipall=False, session=None): """ @@ -2611,19 +2613,7 @@ def get_suite_architectures(suite, skipsrc=False, skipall=False, session=None): @return: list of Architecture objects for the given name (may be empty) """ - q = session.query(Architecture) - q = q.join(SuiteArchitecture) - q = q.join(Suite).filter_by(suite_name=suite) - - if skipsrc: - q = q.filter(Architecture.arch_string != 'source') - - if skipall: - q = q.filter(Architecture.arch_string != 'all') - - q = q.order_by('arch_string') - - return q.all() + return get_suite(suite, session).get_architectures(skipsrc, skipall) __all__.append('get_suite_architectures') @@ -2666,8 +2656,9 @@ __all__.append('get_suite_src_formats') ################################################################################ class Uid(object): - def __init__(self, *args, **kwargs): - pass + def __init__(self, uid = None, name = None): + self.uid = uid + self.name = name def __eq__(self, val): if isinstance(val, str): @@ -2768,7 +2759,6 @@ class DBConn(object): 'binary_acl', 'binary_acl_map', 'build_queue', - 'build_queue_files', 'changelogs_text', 'component', 'config', @@ -2779,7 +2769,6 @@ class DBConn(object): 'files', 'fingerprint', 'keyrings', - 'changes', 'keyring_acl_map', 'location', 'maintainer', @@ -2797,6 +2786,11 @@ class DBConn(object): 'suite', 'uid', 'upload_blocks', + # 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', ) tables_no_primary = ( @@ -2810,11 +2804,38 @@ class DBConn(object): 'suite_src_formats', 'suite_build_queue_copy', 'udeb_contents', + # see the comment above + 'changes', + 'build_queue_files', + ) + + views = ( + 'almost_obsolete_all_associations', + 'almost_obsolete_src_associations', + 'any_associations_source', + 'bin_assoc_by_arch', + 'bin_associations_binaries', + 'binaries_suite_arch', + 'binfiles_suite_component_arch', + 'changelogs', + 'file_arch_suite', + 'newest_all_associations', + 'newest_any_associations', + 'newest_source', + 'newest_src_association', + 'obsolete_all_associations', + 'obsolete_any_associations', + 'obsolete_any_by_all_associations', + 'obsolete_src_associations', + 'source_suite', + 'src_associations_bin', + 'src_associations_src', + 'suite_arch_by_name', ) - # Sqlalchemy fails to reflect the SERIAL type correctly and that - # is why we have to use a workaround. It can be removed as soon - # as we switch to version 0.6. + # Sqlalchemy version 0.5 fails to reflect the SERIAL type + # correctly and that is why we have to use a workaround. It can + # be removed as soon as we switch to version 0.6. for table_name in tables_with_primary: table = Table(table_name, self.db_meta, \ Column('id', Integer, primary_key = True), \ @@ -2825,9 +2846,14 @@ class DBConn(object): table = Table(table_name, self.db_meta, autoload=True) setattr(self, 'tbl_%s' % table_name, table) + for view_name in views: + view = Table(view_name, self.db_meta, autoload=True) + setattr(self, 'view_%s' % view_name, view) + def __setupmappers(self): mapper(Architecture, self.tbl_architecture, - properties = dict(arch_id = self.tbl_architecture.c.id)) + properties = dict(arch_id = self.tbl_architecture.c.id, + suites = relation(Suite, secondary=self.tbl_suite_architectures, backref='architectures', order_by='suite_name'))) mapper(Archive, self.tbl_archive, properties = dict(archive_id = self.tbl_archive.c.id, @@ -3071,12 +3097,6 @@ class DBConn(object): policy_queue = relation(PolicyQueue), copy_queues = relation(BuildQueue, secondary=self.tbl_suite_build_queue_copy))) - mapper(SuiteArchitecture, self.tbl_suite_architectures, - properties = dict(suite_id = self.tbl_suite_architectures.c.suite, - suite = relation(Suite, backref='suitearchitectures'), - arch_id = self.tbl_suite_architectures.c.architecture, - architecture = relation(Architecture))) - mapper(SuiteSrcFormat, self.tbl_suite_src_formats, properties = dict(suite_id = self.tbl_suite_src_formats.c.suite, suite = relation(Suite, backref='suitesrcformats'),