Source

buglink / web / models.py

Full commit
""" The DB models """

from sqlalchemy.orm import relationship
from sqlalchemy import Table, Column, Integer, String, Boolean, ForeignKey

import hashlib

from common.models import DBModel, Issue, Changeset, Repository
# Current version described in this file
DBModel.version = 5

build_has_changeset = Table('build_has_changeset', DBModel.metadata,
    Column('changeset_id', Integer, ForeignKey('changeset.id'),
           primary_key=True),
    Column('build_number', Integer, ForeignKey('build.number'),
           primary_key=True),
)

class Build(DBModel):
    __tablename__ = "build"

    number = Column(Integer, primary_key=True)
    changesets = relationship("Changeset", backref='builds',
                              secondary='build_has_changeset')
    binaries = relationship("Binary", backref='build')

class Module(DBModel):
    __tablename__ = "module"
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    binaries = relationship('Binary', backref='module')

class Binary(DBModel):
    __tablename__ = "binary"
    id = Column(Integer, primary_key=True)
    module_id = Column(Integer, ForeignKey('module.id'), nullable=False)
    build_number = Column(Integer, ForeignKey('build.number'), nullable=False)

    def __str__(self):
        return self.module.name + '-' + str(self.build.number)

release_has_binary = Table('release_has_binary', DBModel.metadata,
    Column('release_id', Integer, ForeignKey('release.id'), primary_key=True),
    Column('binary_id', Integer, ForeignKey('binary.id'), primary_key=True),
)

release_has_changeset = Table('release_has_changeset', DBModel.metadata,
    Column('changeset_id', Integer, ForeignKey('changeset.id'),
           primary_key=True),
    Column('release_id', Integer, ForeignKey('release.id'), primary_key=True),
)

class Release(DBModel):
    """ A release. ref and rc should be enough to identify it"""
    __tablename__ = "release"
    id = Column(Integer, primary_key=True)
    ref = Column(String, nullable=False)
    rc = Column(Integer)
    project = Column(String)    # For special releases
    final = Column(Boolean, nullable=False)
    binaries = relationship("Binary", backref='releases',
                            secondary=release_has_binary)
    changesets = relationship("Changeset", backref='releases',
                              secondary=release_has_changeset)

    def __str__(self):
        res = self.ref
        if self.final:
            res += "-FINAL"
        elif self.rc:
            res += "-rc%d" % int(self.rc)
        if self.project and self.project != 'general':
            res += " (%s)" % self.project
        return res

    @property
    def identifier(self):
        """ Uniquely identify a release """
        s = self.ref + str(self.rc) + str(self.project)
        # We explicitely don't include 'final' as it can change after release
        #     (False -> True)
        for b in sorted(self.binaries, key=lambda k: "%s%d" % (k.module.name, k.build.number)):
            s += b.module.name + str(b.build.number)
        for c in sorted(self.changesets, key=lambda k: "%s%s" % (k.repository.path, k.hash)):
            s += c.repository.path + c.hash
        return hashlib.sha1(s).hexdigest()[:12]