X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fdbconn.py;h=c7ecdc189cb3125b132fb350fb4756193ce655ca;hb=adc359dad427790fefd1de5f01caac9a51b5a5c8;hp=94884d5c6f1f92216ed878815673085e5049a795;hpb=a4b3758ff560961d45155225a3af66a3c45fe8be;p=dak.git diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 94884d5c..c7ecdc18 100755 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -34,6 +34,7 @@ ################################################################################ import os +from os.path import normpath import re import psycopg2 import traceback @@ -49,6 +50,8 @@ except: from datetime import datetime, timedelta from errno import ENOENT from tempfile import mkstemp, mkdtemp +from subprocess import Popen, PIPE +from tarfile import TarFile from inspect import getargspec @@ -502,6 +505,26 @@ class DBBinary(ORMObject): def get_component_name(self): return self.poolfile.location.component.component_name + def scan_contents(self): + ''' + Yields the contents of the package. Only regular files are yielded and + the path names are normalized after converting them from either utf-8 or + iso8859-1 encoding. + ''' + fullpath = self.poolfile.fullpath + dpkg = Popen(['dpkg-deb', '--fsys-tarfile', fullpath], stdout = PIPE) + tar = TarFile.open(fileobj = dpkg.stdout, mode = 'r|') + for member in tar.getmembers(): + if member.isfile(): + try: + name = member.name.decode('utf-8') + except UnicodeDecodeError: + name = member.name.decode('iso8859-1') + yield normpath(name) + tar.close() + dpkg.stdout.close() + dpkg.wait() + __all__.append('DBBinary') @session_wrapper @@ -911,8 +934,8 @@ class Component(ORMObject): return NotImplemented def properties(self): - return ['component_name', 'component_id', 'description', 'location', \ - 'meets_dfsg'] + return ['component_name', 'component_id', 'description', \ + 'location_count', 'meets_dfsg', 'overrides_count'] def not_null_constraints(self): return ['component_name'] @@ -1814,12 +1837,22 @@ __all__.append('get_new_comments') ################################################################################ -class Override(object): - def __init__(self, *args, **kwargs): - pass +class Override(ORMObject): + def __init__(self, package = None, suite = None, component = None, overridetype = None, \ + section = None, priority = None): + self.package = package + self.suite = suite + self.component = component + self.overridetype = overridetype + self.section = section + self.priority = priority - def __repr__(self): - return '' % (self.package, self.suite_id) + def properties(self): + return ['package', 'suite', 'component', 'overridetype', 'section', \ + 'priority'] + + def not_null_constraints(self): + return ['package', 'suite', 'component', 'overridetype', 'section'] __all__.append('Override') @@ -1873,12 +1906,15 @@ __all__.append('get_override') ################################################################################ -class OverrideType(object): - def __init__(self, *args, **kwargs): - pass +class OverrideType(ORMObject): + def __init__(self, overridetype = None): + self.overridetype = overridetype - def __repr__(self): - return '' % self.overridetype + def properties(self): + return ['overridetype', 'overridetype_id', 'overrides_count'] + + def not_null_constraints(self): + return ['overridetype'] __all__.append('OverrideType') @@ -2075,9 +2111,16 @@ __all__.append('get_policy_queue_from_path') ################################################################################ -class Priority(object): - def __init__(self, *args, **kwargs): - pass +class Priority(ORMObject): + def __init__(self, priority = None, level = None): + self.priority = priority + self.level = level + + def properties(self): + return ['priority', 'priority_id', 'level', 'overrides_count'] + + def not_null_constraints(self): + return ['priority', 'level'] def __eq__(self, val): if isinstance(val, str): @@ -2091,9 +2134,6 @@ class Priority(object): # This signals to use the normal comparison operator return NotImplemented - def __repr__(self): - return '' % (self.priority, self.priority_id) - __all__.append('Priority') @session_wrapper @@ -2145,9 +2185,15 @@ __all__.append('get_priorities') ################################################################################ -class Section(object): - def __init__(self, *args, **kwargs): - pass +class Section(ORMObject): + def __init__(self, section = None): + self.section = section + + def properties(self): + return ['section', 'section_id', 'overrides_count'] + + def not_null_constraints(self): + return ['section'] def __eq__(self, val): if isinstance(val, str): @@ -2161,9 +2207,6 @@ class Section(object): # This signals to use the normal comparison operator return NotImplemented - def __repr__(self): - return '
' % self.section - __all__.append('Section') @session_wrapper @@ -2281,9 +2324,9 @@ def source_exists(source, source_version, suites = ["any"], session=None): maps = [ (x[1], x[2]) for x in maps if x[0] == "map" or x[0] == "silent-map" ] s = [suite] - for x in maps: - if x[1] in s and x[0] not in s: - s.append(x[0]) + for (from_, to) in maps: + if from_ in s and to not in s: + s.append(to) q = q.filter(DBSource.suites.any(Suite.suite_name.in_(s))) @@ -2606,7 +2649,8 @@ class Suite(ORMObject): self.version = version def properties(self): - return ['suite_name', 'version', 'sources_count', 'binaries_count'] + return ['suite_name', 'version', 'sources_count', 'binaries_count', \ + 'overrides_count'] def not_null_constraints(self): return ['suite_name', 'version'] @@ -2876,7 +2920,9 @@ class DBConn(object): 'binary_acl', 'binary_acl_map', 'build_queue', + 'build_queue_files', 'changelogs_text', + 'changes', 'component', 'config', 'changes_pending_binaries', @@ -2903,11 +2949,6 @@ 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 = ( @@ -2915,14 +2956,12 @@ class DBConn(object): 'changes_pending_source_files', 'changes_pool_files', 'deb_contents', + # TODO: the maintainer column in table override should be removed. 'override', 'suite_architectures', 'suite_src_formats', 'suite_build_queue_copy', 'udeb_contents', - # see the comment above - #'changes', - #'build_queue_files', ) views = ( @@ -3140,8 +3179,7 @@ class DBConn(object): mapper(Location, self.tbl_location, properties = dict(location_id = self.tbl_location.c.id, component_id = self.tbl_location.c.component, - component = relation(Component, \ - backref=backref('location', uselist = False)), + component = relation(Component, backref='location'), archive_id = self.tbl_location.c.archive, archive = relation(Archive), # FIXME: the 'type' column is old cruft and @@ -3162,16 +3200,21 @@ class DBConn(object): mapper(Override, self.tbl_override, properties = dict(suite_id = self.tbl_override.c.suite, - suite = relation(Suite), + suite = relation(Suite, \ + backref=backref('overrides', lazy='dynamic')), package = self.tbl_override.c.package, component_id = self.tbl_override.c.component, - component = relation(Component), + component = relation(Component, \ + backref=backref('overrides', lazy='dynamic')), priority_id = self.tbl_override.c.priority, - priority = relation(Priority), + priority = relation(Priority, \ + backref=backref('overrides', lazy='dynamic')), section_id = self.tbl_override.c.section, - section = relation(Section), + section = relation(Section, \ + backref=backref('overrides', lazy='dynamic')), overridetype_id = self.tbl_override.c.type, - overridetype = relation(OverrideType))) + overridetype = relation(OverrideType, \ + backref=backref('overrides', lazy='dynamic')))) mapper(OverrideType, self.tbl_override_type, properties = dict(overridetype = self.tbl_override_type.c.type, @@ -3245,7 +3288,7 @@ class DBConn(object): mapper(BinContents, self.tbl_bin_contents, properties = dict( binary = relation(DBBinary, - backref=backref('contents', lazy='dynamic')), + backref=backref('contents', lazy='dynamic', cascade='all')), file = self.tbl_bin_contents.c.file)) ## Connection functions @@ -3264,7 +3307,16 @@ class DBConn(object): if cnf["DB::Port"] and cnf["DB::Port"] != "-1": connstr += "?port=%s" % cnf["DB::Port"] - self.db_pg = create_engine(connstr, echo=self.debug) + engine_args = { 'echo': self.debug } + if cnf.has_key('DB::PoolSize'): + engine_args['pool_size'] = int(cnf['DB::PoolSize']) + if cnf.has_key('DB::MaxOverflow'): + engine_args['max_overflow'] = int(cnf['DB::MaxOverflow']) + if sa_major_version >= 0.6 and cnf.has_key('DB::Unicode') and \ + cnf['DB::Unicode'] == 'false': + engine_args['use_native_unicode'] = False + + self.db_pg = create_engine(connstr, **engine_args) self.db_meta = MetaData() self.db_meta.bind = self.db_pg self.db_smaker = sessionmaker(bind=self.db_pg,