X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fdbconn.py;h=6948cf6c27902528030c17f0f8f602811a3b79dc;hb=9b218664cdb36874fb393a00e4a37f50aed3d7e3;hp=47e2b130645fd582df973432bf33cb4c6d7bb04d;hpb=fdd9528a381f1472a93f52877e75858e6ed8570b;p=dak.git diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 47e2b130..6948cf6c 100755 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -703,6 +703,7 @@ class BuildQueue(object): try: # Grab files we want to include newer = session.query(BuildQueueFile).filter_by(build_queue_id = self.queue_id).filter(BuildQueueFile.lastused + timedelta(seconds=self.stay_of_execution) > starttime).all() + newer += session.query(BuildQueuePolicyFile).filter_by(build_queue_id = self.queue_id).filter(BuildQueuePolicyFile.lastused + timedelta(seconds=self.stay_of_execution) > starttime).all() # Write file list with newer files (fl_fd, fl_name) = mkstemp() for n in newer: @@ -795,6 +796,7 @@ class BuildQueue(object): # Grab files older than our execution time older = session.query(BuildQueueFile).filter_by(build_queue_id = self.queue_id).filter(BuildQueueFile.lastused + timedelta(seconds=self.stay_of_execution) <= starttime).all() + older += session.query(BuildQueuePolicyFile).filter_by(build_queue_id = self.queue_id).filter(BuildQueuePolicyFile.lastused + timedelta(seconds=self.stay_of_execution) <= starttime).all() for o in older: killdb = False @@ -822,9 +824,7 @@ class BuildQueue(object): if f.startswith('Packages') or f.startswith('Source') or f.startswith('Release') or f.startswith('advisory'): continue - try: - r = session.query(BuildQueueFile).filter_by(build_queue_id = self.queue_id).filter_by(filename = f).one() - except NoResultFound: + if not self.contains_filename(f): fp = os.path.join(self.path, f) if dryrun: Logger.log(["I: Would remove unused link %s" % fp]) @@ -835,6 +835,18 @@ class BuildQueue(object): except OSError: Logger.log(["E: Failed to unlink unreferenced file %s" % r.fullpath]) + def contains_filename(self, filename): + """ + @rtype Boolean + @returns True if filename is supposed to be in the queue; False otherwise + """ + session = DBConn().session().object_session(self) + if session.query(BuildQueueFile).filter_by(build_queue_id = self.queue_id, filename = filename).count() > 0: + return True + elif session.query(BuildQueuePolicyFile).filter_by(build_queue = self, filename = filename).count() > 0: + return True + return False + def add_file_from_pool(self, poolfile): """Copies a file into the pool. Assumes that the PoolFile object is attached to the same SQLAlchemy session as the Queue object is. @@ -879,6 +891,61 @@ class BuildQueue(object): return qf + def add_changes_from_policy_queue(self, policyqueue, changes): + """ + Copies a changes from a policy queue together with its poolfiles. + + @type policyqueue: PolicyQueue + @param policyqueue: policy queue to copy the changes from + + @type changes: DBChange + @param changes: changes to copy to this build queue + """ + for policyqueuefile in changes.files: + self.add_file_from_policy_queue(policyqueue, policyqueuefile) + for poolfile in changes.poolfiles: + self.add_file_from_pool(poolfile) + + def add_file_from_policy_queue(self, policyqueue, policyqueuefile): + """ + Copies a file from a policy queue. + Assumes that the policyqueuefile is attached to the same SQLAlchemy + session as the Queue object is. The caller is responsible for + committing after calling this function. + + @type policyqueue: PolicyQueue + @param policyqueue: policy queue to copy the file from + + @type policyqueuefile: ChangePendingFile + @param policyqueuefile: file to be added to the build queue + """ + session = DBConn().session().object_session(policyqueuefile) + + # Is the file already there? + try: + f = session.query(BuildQueuePolicyFile).filter_by(build_queue=self, file=policyqueuefile).one() + f.lastused = datetime.now() + return f + except NoResultFound: + pass # continue below + + # We have to add the file. + f = BuildQueuePolicyFile() + f.build_queue = self + f.file = policyqueuefile + f.filename = policyqueuefile.filename + + source = os.path.join(policyqueue.path, policyqueuefile.filename) + target = f.fullpath + try: + # Always copy files from policy queues as they might move around. + import utils + utils.copy(source, target) + except OSError: + return None + + session.add(f) + return f __all__.append('BuildQueue') @@ -911,6 +978,10 @@ __all__.append('get_build_queue') ################################################################################ class BuildQueueFile(object): + """ + BuildQueueFile represents a file in a build queue coming from a pool. + """ + def __init__(self, *args, **kwargs): pass @@ -926,6 +997,27 @@ __all__.append('BuildQueueFile') ################################################################################ +class BuildQueuePolicyFile(object): + """ + BuildQueuePolicyFile represents a file in a build queue that comes from a + policy queue (and not a pool). + """ + + def __init__(self, *args, **kwargs): + pass + + #@property + #def filename(self): + # return self.file.filename + + @property + def fullpath(self): + return os.path.join(self.build_queue.path, self.filename) + +__all__.append('BuildQueuePolicyFile') + +################################################################################ + class ChangePendingBinary(object): def __init__(self, *args, **kwargs): pass @@ -3027,6 +3119,33 @@ __all__.append('SourceMetadata') ################################################################################ +class VersionCheck(ORMObject): + def __init__(self, *args, **kwargs): + pass + + def properties(self): + #return ['suite_id', 'check', 'reference_id'] + return ['check'] + + def not_null_constraints(self): + return ['suite', 'check', 'reference'] + +__all__.append('VersionCheck') + +@session_wrapper +def get_version_checks(suite_name, check = None, session = None): + suite = get_suite(suite_name, session) + if not suite: + return None + q = session.query(VersionCheck).filter_by(suite=suite) + if check: + q = q.filter_by(check=check) + return q.all() + +__all__.append('get_version_checks') + +################################################################################ + class DBConn(object): """ database module init. @@ -3053,6 +3172,7 @@ class DBConn(object): 'binary_acl_map', 'build_queue', 'build_queue_files', + 'build_queue_policy_files', 'changelogs_text', 'changes', 'component', @@ -3092,13 +3212,13 @@ class DBConn(object): 'suite_src_formats', 'uid', 'upload_blocks', + 'version_check', ) 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', @@ -3146,6 +3266,11 @@ class DBConn(object): properties = dict(buildqueue = relation(BuildQueue, backref='queuefiles'), poolfile = relation(PoolFile, backref='buildqueueinstances'))) + mapper(BuildQueuePolicyFile, self.tbl_build_queue_policy_files, + properties = dict( + build_queue = relation(BuildQueue, backref='policy_queue_files'), + file = relation(ChangePendingFile, lazy='joined'))) + mapper(DBBinary, self.tbl_binaries, properties = dict(binary_id = self.tbl_binaries.c.id, package = self.tbl_binaries.c.package, @@ -3406,6 +3531,13 @@ class DBConn(object): key = relation(MetadataKey), value = self.tbl_source_metadata.c.value)) + mapper(VersionCheck, self.tbl_version_check, + properties = dict( + suite_id = self.tbl_version_check.c.suite, + suite = relation(Suite, primaryjoin=self.tbl_version_check.c.suite==self.tbl_suite.c.id), + reference_id = self.tbl_version_check.c.reference, + reference = relation(Suite, primaryjoin=self.tbl_version_check.c.reference==self.tbl_suite.c.id, lazy='joined'))) + ## Connection functions def __createconn(self): from config import Config @@ -3458,12 +3590,21 @@ class DBConn(object): self.__setupmappers() self.pid = os.getpid() - def session(self): + def session(self, work_mem = 0): + ''' + Returns a new session object. If a work_mem parameter is provided a new + transaction is started and the work_mem parameter is set for this + transaction. The work_mem parameter is measured in MB. A default value + will be used if the parameter is not set. + ''' # reinitialize DBConn in new processes if self.pid != os.getpid(): clear_mappers() self.__createconn() - return self.db_smaker() + session = self.db_smaker() + if work_mem > 0: + session.execute("SET LOCAL work_mem TO '%d MB'" % work_mem) + return session __all__.append('DBConn')