################################################################################
-class Cache(object):
- def __init__(self, hashfunc=None):
- if hashfunc:
- self.hashfunc = hashfunc
- else:
- self.hashfunc = lambda x: str(x)
-
- self.data = {}
-
- def SetValue(self, keys, value):
- self.data[self.hashfunc(keys)] = value
-
- def GetValue(self, keys):
- return self.data.get(self.hashfunc(keys))
-
-################################################################################
-
class Architecture(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Architecture %s>' % self.arch_string
+def get_architecture(architecture, session=None):
+ """
+ Returns database id for given C{architecture}.
+
+ @type architecture: string
+ @param architecture: The name of the architecture
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Architecture
+ @return: Architecture object for the given arch (None if not present)
+
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Architecture).filter_by(arch_string=architecture)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class Archive(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Archive %s>' % self.name
+def get_archive(archive, session=None):
+ """
+ returns database id for given c{archive}.
+
+ @type archive: string
+ @param archive: the name of the arhive
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Archive
+ @return: Archive object for the given name (None if not present)
+
+ """
+ archive = archive.lower()
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Archive).filter_by(archive_name=archive)
+ if q.count() == 0:
+ return None
+ return q.one()
+
+
class BinAssociation(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Binary %s (%s, %s)>' % (self.package, self.version, self.architecture)
-def binary_from_id(id):
- return DBConn().session().query(Binary).filter_by(binary_id=id).one()
+def get_binary_from_id(id, session=None):
+ """
+ Returns Binary object for given C{id}
+
+ @type id: int
+ @param id: Id of the required binary
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Binary
+ @return: Binary object for the given binary (None if not present)
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Binary).filter_by(binary_id=id)
+ if q.count() == 0:
+ return None
+ return q.one()
class Component(object):
def __init__(self, *args, **kwargs):
def __repr__(self):
return '<Component %s>' % self.component_name
+def get_component(component, session=None):
+ """
+ Returns database id for given C{component}.
+
+ @type component: string
+ @param component: The name of the override type
+
+ @rtype: int
+ @return: the database id for the given component
+
+ """
+ component = component.lower()
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Component).filter_by(component_name=component)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class DBConfig(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<OverrideType %s>' % self.overridetype
+def get_override_type(override_type, session=None):
+ """
+ Returns OverrideType object for given C{override type}.
+
+ @type override_type: string
+ @param override_type: The name of the override type
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: int
+ @return: the database id for the given override type
+
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Priority).filter_by(priority=priority)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class PendingContentAssociation(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Priority %s (%s)>' % (self.priority, self.priority_id)
+def get_priority(priority, session=None):
+ """
+ Returns Priority object for given C{priority name}.
+
+ @type priority: string
+ @param priority: The name of the priority
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Priority
+ @return: Priority object for the given priority
+
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Priority).filter_by(priority=priority)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class Queue(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Section %s>' % self.section
+def get_section(section, session=None):
+ """
+ Returns Section object for given C{section name}.
+
+ @type section: string
+ @param section: The name of the section
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Section
+ @return: Section object for the given section name
+
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Section).filter_by(section=section)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class Source(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Source %s (%s)>' % (self.source, self.version)
+def get_source_in_suite(source, suite, session=None):
+ """
+ Returns list of Source objects for a combination of C{source} and C{suite}.
+
+ - B{source} - source package name, eg. I{mailfilter}, I{bbdb}, I{glibc}
+ - B{suite} - a suite name, eg. I{unstable}
+
+ @type source: string
+ @param source: source package name
+
+ @type suite: string
+ @param suite: the suite name
+
+ @rtype: string
+ @return: the version for I{source} in I{suite}
+
+ """
+ ######## TODO UP TO HERE
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Source).filter_by(source=source)
+ if q.count() == 0:
+ return None
+ return q.one()
+
+
+ return self.__get_id('source.version', s, {'suite': suite, 'source': source}, 'suite_version')
+
+
+
class SrcAssociation(object):
def __init__(self, *args, **kwargs):
pass
def __repr__(self):
return '<Suite %s>' % self.suite_name
+def get_suite(suite, session=None):
+ """
+ Returns Suite object for given C{suite name}.
+
+ @type suite: string
+ @param suite: The name of the suite
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: Suite
+ @return: Suite object for the requested suite name (None if not presenT)
+
+ """
+ if session is None:
+ session = DBConn().session()
+ q = session.query(Suite).filter_by(suite_name=suite)
+ if q.count() == 0:
+ return None
+ return q.one()
+
class SuiteArchitecture(object):
def __init__(self, *args, **kwargs):
pass
def _startup(self, *args, **kwargs):
self.__createconn()
- self.__init_caches()
def __setuptables(self):
self.tbl_architecture = Table('architecture', self.db_meta, autoload=True)
def session(self):
return self.db_smaker()
- ## Cache functions
- def __init_caches(self):
- self.caches = {'suite': Cache(),
- 'section': Cache(),
- 'priority': Cache(),
- 'override_type': Cache(),
- 'architecture': Cache(),
- 'archive': Cache(),
- 'component': Cache(),
- 'content_path_names': Cache(),
- 'content_file_names': Cache(),
- 'location': Cache(lambda x: '%s_%s_%s' % (x['location'], x['component'], x['location'])),
- 'maintainer': {}, # TODO
- 'keyring': {}, # TODO
- 'source': Cache(lambda x: '%s_%s_' % (x['source'], x['version'])),
- 'files': Cache(lambda x: '%s_%s_' % (x['filename'], x['location'])),
- 'maintainer': {}, # TODO
- 'fingerprint': {}, # TODO
- 'queue': {}, # TODO
- 'uid': {}, # TODO
- 'suite_version': Cache(lambda x: '%s_%s' % (x['source'], x['suite'])),
- }
-
- self.prepared_statements = {}
-
def prepare(self,name,statement):
if not self.prepared_statements.has_key(name):
pgc.execute(statement)
self.prepared_statements[name] = statement
- def clear_caches(self):
- self.__init_caches()
-
- ## Get functions
- def __get_id(self, retfield, selectobj, cachekey, cachename=None):
- # This is a bit of a hack but it's an internal function only
- if cachename is not None:
- res = self.caches[cachename].GetValue(cachekey)
- if res:
- return res
-
- c = selectobj.execute()
-
- if c.rowcount != 1:
- return None
-
- res = c.fetchone()
-
- if retfield not in res.keys():
- return None
-
- res = res[retfield]
-
- if cachename is not None:
- self.caches[cachename].SetValue(cachekey, res)
-
- return res
-
- def get_suite_id(self, suite):
- """
- Returns database id for given C{suite}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type suite: string
- @param suite: The name of the suite
-
- @rtype: int
- @return: the database id for the given suite
-
- """
- return int(self.__get_id('id',
- self.tbl_suite.select(self.tbl_suite.columns.suite_name == suite),
- suite,
- 'suite'))
-
- def get_section_id(self, section):
- """
- Returns database id for given C{section}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type section: string
- @param section: The name of the section
-
- @rtype: int
- @return: the database id for the given section
-
- """
- return self.__get_id('id',
- self.tbl_section.select(self.tbl_section.columns.section == section),
- section,
- 'section')
-
- def get_priority_id(self, priority):
- """
- Returns database id for given C{priority}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type priority: string
- @param priority: The name of the priority
-
- @rtype: int
- @return: the database id for the given priority
-
- """
- return self.__get_id('id',
- self.tbl_priority.select(self.tbl_priority.columns.priority == priority),
- priority,
- 'priority')
-
- def get_override_type_id(self, override_type):
- """
- Returns database id for given override C{type}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type override_type: string
- @param override_type: The name of the override type
-
- @rtype: int
- @return: the database id for the given override type
-
- """
- return self.__get_id('id',
- self.tbl_override_type.select(self.tbl_override_type.columns.type == override_type),
- override_type,
- 'override_type')
-
- def get_architecture_id(self, architecture):
- """
- Returns database id for given C{architecture}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type architecture: string
- @param architecture: The name of the override type
-
- @rtype: int
- @return: the database id for the given architecture
-
- """
- return self.__get_id('id',
- self.tbl_architecture.select(self.tbl_architecture.columns.arch_string == architecture),
- architecture,
- 'architecture')
-
- def get_archive_id(self, archive):
- """
- returns database id for given c{archive}.
- results are kept in a cache during runtime to minimize database queries.
-
- @type archive: string
- @param archive: the name of the override type
-
- @rtype: int
- @return: the database id for the given archive
-
- """
- archive = archive.lower()
- return self.__get_id('id',
- self.tbl_archive.select(self.tbl_archive.columns.name == archive),
- archive,
- 'archive')
-
- def get_component_id(self, component):
- """
- Returns database id for given C{component}.
- Results are kept in a cache during runtime to minimize database queries.
-
- @type component: string
- @param component: The name of the override type
-
- @rtype: int
- @return: the database id for the given component
-
- """
- component = component.lower()
- return self.__get_id('id',
- self.tbl_component.select(self.tbl_component.columns.name == component),
- component.lower(),
- 'component')
def get_location_id(self, location, component, archive):
"""
@type location: string
@param location: the path of the location
- @type component: string
- @param component: the name of the component
+ @type component: int
+ @param component: the id of the component
- @type archive: string
- @param archive: the name of the archive
+ @type archive: int
+ @param archive: the id of the archive
@rtype: int
@return: the database id for the location
"""
- archive = archive.lower()
- component = component.lower()
+ archive_id = self.get_archive_id(archive)
- values = {'archive': archive, 'location': location, 'component': component}
-
- s = self.tbl_location.join(self.tbl_archive).join(self.tbl_component)
-
- s = s.select(self.tbl_location.columns.path == location)
- s = s.where(self.tbl_archive.columns.name == archive)
- s = s.where(self.tbl_component.columns.name == component)
-
- return self.__get_id('location.id', s, values, 'location')
-
- def get_source_id(self, source, version):
- """
- Returns database id for the combination of C{source} and C{version}
- - B{source} - source package name, eg. I{mailfilter}, I{bbdb}, I{glibc}
- - B{version}
- Results are kept in a cache during runtime to minimize database queries.
-
- @type source: string
- @param source: source package name
-
- @type version: string
- @param version: the source version
-
- @rtype: int
- @return: the database id for the source
-
- """
- s = self.tbl_source.select()
- s = s.where(self.tbl_source.columns.source == source)
- s = s.where(self.tbl_source.columns.version == version)
-
- return self.__get_id('id', s, {'source': source, 'version': version}, 'source')
-
- def get_suite(self, suite):
- if isinstance(suite, str):
- suite_id = self.get_suite_id(suite.lower())
- elif type(suite) == int:
- suite_id = suite
-
- s = self.tbl_suite.select(self.tbl_suite.columns.id == suite_id)
- c = s.execute()
- if c.rowcount < 1:
+ if not archive_id:
return None
- else:
- return c.fetchone()
- def get_suite_version(self, source, suite):
- """
- Returns database id for a combination of C{source} and C{suite}.
-
- - B{source} - source package name, eg. I{mailfilter}, I{bbdb}, I{glibc}
- - B{suite} - a suite name, eg. I{unstable}
+ res = None
- Results are kept in a cache during runtime to minimize database queries.
-
- @type source: string
- @param source: source package name
-
- @type suite: string
- @param suite: the suite name
-
- @rtype: string
- @return: the version for I{source} in I{suite}
-
- """
- s = select([self.tbl_source.columns.source, self.tbl_source.columns.version])
-# s = self.tbl_source.join(self.tbl_src_associations).join(self.tbl_suite)
+ if component:
+ component_id = self.get_component_id(component)
+ if component_id:
+ res = self.__get_single_id("SELECT id FROM location WHERE path=%(location)s AND component=%(component)s AND archive=%(archive)s",
+ {'location': location,
+ 'archive': int(archive_id),
+ 'component': component_id}, cachename='location')
+ else:
+ res = self.__get_single_id("SELECT id FROM location WHERE path=%(location)s AND archive=%(archive)d",
+ {'location': location, 'archive': archive_id, 'component': ''}, cachename='location')
- s = s.select(self.tbl_suite.columns.suite_name == suite, use_labels=True)
- s = s.select(self.tbl_source.columns.source == source)
+ return res
- return self.__get_id('source.version', s, {'suite': suite, 'source': source}, 'suite_version')
- def get_files_id (self, filename, size, md5sum, location_id):
- """
- Returns -1, -2 or the file_id for filename, if its C{size} and C{md5sum} match an
- existing copy.
+def get_files_id (self, filename, size, md5sum, location_id):
+ """
+ Returns -1, -2 or the file_id for filename, if its C{size} and C{md5sum} match an
+ existing copy.
- The database is queried using the C{filename} and C{location_id}. If a file does exist
- at that location, the existing size and md5sum are checked against the provided
- parameters. A size or checksum mismatch returns -2. If more than one entry is
- found within the database, a -1 is returned, no result returns None, otherwise
- the file id.
+ The database is queried using the C{filename} and C{location_id}. If a file does exist
+ at that location, the existing size and md5sum are checked against the provided
+ parameters. A size or checksum mismatch returns -2. If more than one entry is
+ found within the database, a -1 is returned, no result returns None, otherwise
+ the file id.
- Results are kept in a cache during runtime to minimize database queries.
+ @type filename: string
+ @param filename: the filename of the file to check against the DB
- @type filename: string
- @param filename: the filename of the file to check against the DB
+ @type size: int
+ @param size: the size of the file to check against the DB
- @type size: int
- @param size: the size of the file to check against the DB
+ @type md5sum: string
+ @param md5sum: the md5sum of the file to check against the DB
- @type md5sum: string
- @param md5sum: the md5sum of the file to check against the DB
+ @type location_id: int
+ @param location_id: the id of the location as returned by L{get_location_id}
- @type location_id: int
- @param location_id: the id of the location as returned by L{get_location_id}
+ @rtype: int / None
+ @return: Various return values are possible:
+ - -2: size/checksum error
+ - -1: more than one file found in database
+ - None: no file found in database
+ - int: file id
- @rtype: int / None
- @return: Various return values are possible:
- - -2: size/checksum error
- - -1: more than one file found in database
- - None: no file found in database
- - int: file id
+ """
+ values = {'filename' : filename,
+ 'location' : location_id}
- """
- values = {'filename' : filename,
- 'location' : location_id}
+ if not res:
+ query = """SELECT id, size, md5sum
+ FROM files
+ WHERE filename = %(filename)s AND location = %(location)s"""
- res = self.caches['files'].GetValue( values )
+ cursor = self.db_con.cursor()
+ cursor.execute( query, values )
- if not res:
- query = """SELECT id, size, md5sum
- FROM files
- WHERE filename = %(filename)s AND location = %(location)s"""
+ if cursor.rowcount == 0:
+ res = None
- cursor = self.db_con.cursor()
- cursor.execute( query, values )
+ elif cursor.rowcount != 1:
+ res = -1
- if cursor.rowcount == 0:
- res = None
+ else:
+ row = cursor.fetchone()
- elif cursor.rowcount != 1:
- res = -1
+ if row[1] != int(size) or row[2] != md5sum:
+ res = -2
else:
- row = cursor.fetchone()
-
- if row[1] != int(size) or row[2] != md5sum:
- res = -2
-
- else:
- self.caches['files'].SetValue(values, row[0])
- res = row[0]
-
- return res
+ res = row[0]
+ return res
- def get_or_set_contents_file_id(self, filename):
- """
- Returns database id for given filename.
- Results are kept in a cache during runtime to minimize database queries.
- If no matching file is found, a row is inserted.
+def get_or_set_contents_file_id(self, filename):
+ """
+ Returns database id for given filename.
- @type filename: string
- @param filename: The filename
+ If no matching file is found, a row is inserted.
- @rtype: int
- @return: the database id for the given component
- """
- try:
- values={'value': filename}
- query = "SELECT id FROM content_file_names WHERE file = %(value)s"
- id = self.__get_single_id(query, values, cachename='content_file_names')
- if not id:
- c = self.db_con.cursor()
- c.execute( "INSERT INTO content_file_names VALUES (DEFAULT, %(value)s) RETURNING id",
- values )
-
- id = c.fetchone()[0]
- self.caches['content_file_names'].SetValue(values, id)
-
- return id
- except:
- traceback.print_exc()
- raise
-
- def get_or_set_contents_path_id(self, path):
- """
- Returns database id for given path.
+ @type filename: string
+ @param filename: The filename
- Results are kept in a cache during runtime to minimize database queries.
- If no matching file is found, a row is inserted.
+ @rtype: int
+ @return: the database id for the given component
+ """
+ try:
+ values={'value': filename}
+ query = "SELECT id FROM content_file_names WHERE file = %(value)s"
+ if not id:
+ c = self.db_con.cursor()
+ c.execute( "INSERT INTO content_file_names VALUES (DEFAULT, %(value)s) RETURNING id",
+ values )
+
+ id = c.fetchone()[0]
+
+ return id
+ except:
+ traceback.print_exc()
+ raise
+
+def get_or_set_contents_path_id(self, path):
+ """
+ Returns database id for given path.
- @type path: string
- @param path: The filename
+ If no matching file is found, a row is inserted.
- @rtype: int
- @return: the database id for the given component
- """
- try:
- values={'value': path}
- query = "SELECT id FROM content_file_paths WHERE path = %(value)s"
- id = self.__get_single_id(query, values, cachename='content_path_names')
- if not id:
- c = self.db_con.cursor()
- c.execute( "INSERT INTO content_file_paths VALUES (DEFAULT, %(value)s) RETURNING id",
- values )
-
- id = c.fetchone()[0]
- self.caches['content_path_names'].SetValue(values, id)
-
- return id
- except:
- traceback.print_exc()
- raise
-
- def get_suite_architectures(self, suite):
- """
- Returns list of architectures for C{suite}.
+ @type path: string
+ @param path: The filename
- @type suite: string, int
- @param suite: the suite name or the suite_id
+ @rtype: int
+ @return: the database id for the given component
+ """
+ try:
+ values={'value': path}
+ query = "SELECT id FROM content_file_paths WHERE path = %(value)s"
+ if not id:
+ c = self.db_con.cursor()
+ c.execute( "INSERT INTO content_file_paths VALUES (DEFAULT, %(value)s) RETURNING id",
+ values )
+
+ id = c.fetchone()[0]
+
+ return id
+ except:
+ traceback.print_exc()
+ raise
+
+def get_suite_architectures(self, suite):
+ """
+ Returns list of architectures for C{suite}.
- @rtype: list
- @return: the list of architectures for I{suite}
- """
+ @type suite: string, int
+ @param suite: the suite name or the suite_id
- suite_id = None
- if type(suite) == str:
- suite_id = self.get_suite_id(suite)
- elif type(suite) == int:
- suite_id = suite
- else:
- return None
+ @rtype: list
+ @return: the list of architectures for I{suite}
+ """
- 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 )
+ suite_id = None
+ if type(suite) == str:
+ suite_id = self.get_suite_id(suite)
+ elif type(suite) == int:
+ suite_id = suite
+ else:
+ return None
- return map(lambda x: x[0], c.fetchall())
+ 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 )
- def insert_content_paths(self, bin_id, fullpaths):
- """
- Make sure given path is associated with given binary id
+ return map(lambda x: x[0], c.fetchall())
- @type bin_id: int
- @param bin_id: the id of the binary
- @type fullpaths: list
- @param fullpaths: the list of paths of the file being associated with the binary
+def insert_content_paths(self, bin_id, fullpaths):
+ """
+ Make sure given path is associated with given binary id
- @return: True upon success
- """
+ @type bin_id: int
+ @param bin_id: the id of the binary
+ @type fullpaths: list
+ @param fullpaths: the list of paths of the file being associated with the binary
- c = self.db_con.cursor()
+ @return: True upon success
+ """
- c.execute("BEGIN WORK")
- try:
+ c = self.db_con.cursor()
- for fullpath in fullpaths:
- (path, file) = os.path.split(fullpath)
+ c.execute("BEGIN WORK")
+ try:
- if path.startswith( "./" ):
- path = path[2:]
- # Get the necessary IDs ...
- file_id = self.get_or_set_contents_file_id(file)
- path_id = self.get_or_set_contents_path_id(path)
+ for fullpath in fullpaths:
+ (path, file) = os.path.split(fullpath)
- c.execute("""INSERT INTO content_associations
- (binary_pkg, filepath, filename)
- VALUES ( '%d', '%d', '%d')""" % (bin_id, path_id, file_id) )
+ # Get the necessary IDs ...
+ file_id = self.get_or_set_contents_file_id(file)
+ path_id = self.get_or_set_contents_path_id(path)
- c.execute("COMMIT")
- return True
- except:
- traceback.print_exc()
- c.execute("ROLLBACK")
- return False
+ c.execute("""INSERT INTO content_associations
+ (binary_pkg, filepath, filename)
+ VALUES ( '%d', '%d', '%d')""" % (bin_id, path_id, file_id) )
- def insert_pending_content_paths(self, package, fullpaths):
- """
- Make sure given paths are temporarily associated with given
- package
+ c.execute("COMMIT")
+ return True
+ except:
+ traceback.print_exc()
+ c.execute("ROLLBACK")
+ return False
- @type package: dict
- @param package: the package to associate with should have been read in from the binary control file
- @type fullpaths: list
- @param fullpaths: the list of paths of the file being associated with the binary
+def insert_pending_content_paths(self, package, fullpaths):
+ """
+ Make sure given paths are temporarily associated with given
+ package
- @return: True upon success
- """
+ @type package: dict
+ @param package: the package to associate with should have been read in from the binary control file
+ @type fullpaths: list
+ @param fullpaths: the list of paths of the file being associated with the binary
- c = self.db_con.cursor()
-
- c.execute("BEGIN WORK")
- try:
- arch_id = self.get_architecture_id(package['Architecture'])
-
- # Remove any already existing recorded files for this package
- c.execute("""DELETE FROM pending_content_associations
- WHERE package=%(Package)s
- AND version=%(Version)s
- AND architecture=%(ArchID)s""", {'Package': package['Package'],
- 'Version': package['Version'],
- 'ArchID': arch_id})
-
- for fullpath in fullpaths:
- (path, file) = os.path.split(fullpath)
-
- if path.startswith( "./" ):
- path = path[2:]
- # Get the necessary IDs ...
- file_id = self.get_or_set_contents_file_id(file)
- path_id = self.get_or_set_contents_path_id(path)
-
- c.execute("""INSERT INTO pending_content_associations
- (package, version, architecture, filepath, filename)
- VALUES (%%(Package)s, %%(Version)s, '%d', '%d', '%d')"""
- % (arch_id, path_id, file_id), package )
-
- c.execute("COMMIT")
- return True
- except:
- traceback.print_exc()
- c.execute("ROLLBACK")
- return False
+ @return: True upon success
+ """
+ c = self.db_con.cursor()
+
+ c.execute("BEGIN WORK")
+ try:
+ arch_id = self.get_architecture_id(package['Architecture'])
+
+ # Remove any already existing recorded files for this package
+ c.execute("""DELETE FROM pending_content_associations
+ WHERE package=%(Package)s
+ AND version=%(Version)s
+ AND architecture=%(ArchID)s""", {'Package': package['Package'],
+ 'Version': package['Version'],
+ 'ArchID': arch_id})
+
+ for fullpath in fullpaths:
+ (path, file) = os.path.split(fullpath)
+
+ if path.startswith( "./" ):
+ path = path[2:]
+ # Get the necessary IDs ...
+ file_id = self.get_or_set_contents_file_id(file)
+ path_id = self.get_or_set_contents_path_id(path)
+
+ c.execute("""INSERT INTO pending_content_associations
+ (package, version, architecture, filepath, filename)
+ VALUES (%%(Package)s, %%(Version)s, '%d', '%d', '%d')"""
+ % (arch_id, path_id, file_id), package )
+
+ c.execute("COMMIT")
+ return True
+ except:
+ traceback.print_exc()
+ c.execute("ROLLBACK")
+ return False