Blame progit/model.py

Pierre-Yves Chibon ae4136
#-*- coding: utf-8 -*-
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
"""
Pierre-Yves Chibon ae4136
 (c) 2014 - Copyright Red Hat Inc
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
 Authors:
Pierre-Yves Chibon ae4136
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
"""
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
Pierre-Yves Chibon ae4136
import pkg_resources
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
import datetime
Pierre-Yves Chibon ae4136
import logging
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
import sqlalchemy as sa
Pierre-Yves Chibon ae4136
from sqlalchemy import create_engine
Pierre-Yves Chibon ae4136
from sqlalchemy.ext.declarative import declarative_base
Pierre-Yves Chibon ae4136
from sqlalchemy.orm import sessionmaker
Pierre-Yves Chibon ae4136
from sqlalchemy.orm import scoped_session
Pierre-Yves Chibon ae4136
from sqlalchemy.orm import relation
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
BASE = declarative_base()
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
ERROR_LOG = logging.getLogger('progit.model')
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
def create_tables(db_url, alembic_ini=None, debug=False):
Pierre-Yves Chibon ae4136
    """ Create the tables in the database using the information from the
Pierre-Yves Chibon ae4136
    url obtained.
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    :arg db_url, URL used to connect to the database. The URL contains
Pierre-Yves Chibon ae4136
        information with regards to the database engine, the host to
Pierre-Yves Chibon ae4136
        connect to, the user and password and the database name.
Pierre-Yves Chibon ae4136
          ie: <engine>://<user>:<password>@<host>/<dbname></dbname></host></password></user></engine>
Pierre-Yves Chibon ae4136
    :kwarg alembic_ini, path to the alembic ini file. This is necessary
Pierre-Yves Chibon ae4136
        to be able to use alembic correctly, but not for the unit-tests.
Pierre-Yves Chibon ae4136
    :kwarg debug, a boolean specifying wether we should have the verbose
Pierre-Yves Chibon ae4136
        output of sqlalchemy or not.
Pierre-Yves Chibon ae4136
    :return a session that can be used to query the database.
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    """
Pierre-Yves Chibon ae4136
    engine = create_engine(db_url, echo=debug)
Pierre-Yves Chibon ae4136
    BASE.metadata.create_all(engine)
Pierre-Yves Chibon ae4136
    #engine.execute(collection_package_create_view(driver=engine.driver))
Pierre-Yves Chibon ae4136
    if db_url.startswith('sqlite:'):
Pierre-Yves Chibon ae4136
        ## Ignore the warning about con_record
Pierre-Yves Chibon ae4136
        # pylint: disable=W0613
Pierre-Yves Chibon ae4136
        def _fk_pragma_on_connect(dbapi_con, con_record):
Pierre-Yves Chibon ae4136
            ''' Tries to enforce referential constraints on sqlite. '''
Pierre-Yves Chibon ae4136
            dbapi_con.execute('pragma foreign_keys=ON')
Pierre-Yves Chibon ae4136
        sa.event.listen(engine, 'connect', _fk_pragma_on_connect)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    if alembic_ini is not None:  # pragma: no cover
Pierre-Yves Chibon ae4136
        # then, load the Alembic configuration and generate the
Pierre-Yves Chibon ae4136
        # version table, "stamping" it with the most recent rev:
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
        ## Ignore the warning missing alembic
Pierre-Yves Chibon ae4136
        # pylint: disable=F0401
Pierre-Yves Chibon ae4136
        from alembic.config import Config
Pierre-Yves Chibon ae4136
        from alembic import command
Pierre-Yves Chibon ae4136
        alembic_cfg = Config(alembic_ini)
Pierre-Yves Chibon ae4136
        command.stamp(alembic_cfg, "head")
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    scopedsession = scoped_session(sessionmaker(bind=engine))
Pierre-Yves Chibon ae4136
    return scopedsession
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
class Project(BASE):
Pierre-Yves Chibon ae4136
    """ Stores the projects.
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    Table -- projects
Pierre-Yves Chibon ae4136
    """
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    __tablename__ = 'projects'
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon a9a740
    user = sa.Column(sa.String(32), nullable=False)
Pierre-Yves Chibon ae4136
    name = sa.Column(sa.String(32), nullable=False, index=True)
Pierre-Yves Chibon d688cf
    description = sa.Column(sa.Text, nullable=True)
Pierre-Yves Chibon ae4136
    parent_id = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Integer,
Pierre-Yves Chibon ae4136
        sa.ForeignKey('projects.id', onupdate='CASCADE'),
Pierre-Yves Chibon ae4136
        nullable=True)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    date_created = sa.Column(sa.DateTime, nullable=False,
Pierre-Yves Chibon ae4136
                             default=datetime.datetime.utcnow)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon d35f35
    parent = relation('Project', remote_side=[id])
Pierre-Yves Chibon 334ada
Mathieu Bridon b0b97e
    @property
Mathieu Bridon b0b97e
    def path(self):
Pierre-Yves Chibon 0c862c
        ''' Return the name of the git repo on the filesystem. '''
Mathieu Bridon b0b97e
        return "%s.git" % self.name
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon b393e8
    @property
Pierre-Yves Chibon 49feff
    def fork(self):
Pierre-Yves Chibon 49feff
        ''' Return a boolean specifying if the project is a fork or not '''
Pierre-Yves Chibon 3a95ee
        return self.parent_id is not None
Pierre-Yves Chibon 49feff
Pierre-Yves Chibon 49feff
    @property
Pierre-Yves Chibon b393e8
    def fullname(self):
Pierre-Yves Chibon b393e8
        ''' Return the name of the git repo as user/project if it is a
Pierre-Yves Chibon b393e8
        project forked, otherwise it returns the project name.
Pierre-Yves Chibon b393e8
        '''
Pierre-Yves Chibon b393e8
        str_name = self.name
Pierre-Yves Chibon 3a95ee
        if self.parent_id:
Pierre-Yves Chibon b393e8
            str_name = "%s/%s" % (self.user, str_name)
Pierre-Yves Chibon b393e8
        return str_name
Pierre-Yves Chibon b393e8
Pierre-Yves Chibon 2f8732
Pierre-Yves Chibon ae4136
class Comment(BASE):
Pierre-Yves Chibon ae4136
    """ Stores the comments made on a commit/file.
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    Table -- comments
Pierre-Yves Chibon ae4136
    """
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    __tablename__ = 'comments'
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon ae4136
    project_id = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Integer,
Pierre-Yves Chibon ae4136
        sa.ForeignKey(
Pierre-Yves Chibon ae4136
            'projects.id', ondelete='CASCADE', onupdate='CASCADE'),
Pierre-Yves Chibon ae4136
        nullable=False)
Pierre-Yves Chibon ae4136
    commit_id = sa.Column(
Pierre-Yves Chibon ae4136
        sa.String(40),
Pierre-Yves Chibon ae4136
        nullable=False,
Pierre-Yves Chibon ae4136
        index=True)
Pierre-Yves Chibon ae4136
    line = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Integer,
Pierre-Yves Chibon ae4136
        nullable=True)
Pierre-Yves Chibon ae4136
    comment = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Text(),
Pierre-Yves Chibon ae4136
        nullable=False)
Pierre-Yves Chibon ae4136
    parent_id = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Integer,
Pierre-Yves Chibon ae4136
        sa.ForeignKey('comments.id', onupdate='CASCADE'),
Pierre-Yves Chibon ae4136
        nullable=True)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    date_created = sa.Column(sa.DateTime, nullable=False,
Pierre-Yves Chibon ae4136
                             default=datetime.datetime.utcnow)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
class Issue(BASE):
Pierre-Yves Chibon ae4136
    """ Stores the issues reported on a project.
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    Table -- issues
Pierre-Yves Chibon ae4136
    """
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    __tablename__ = 'issues'
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon ae4136
    project_id = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Integer,
Pierre-Yves Chibon ae4136
        sa.ForeignKey(
Pierre-Yves Chibon ae4136
            'projects.id', ondelete='CASCADE', onupdate='CASCADE'),
Pierre-Yves Chibon ae4136
        nullable=False)
Pierre-Yves Chibon ae4136
    title = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Text,
Pierre-Yves Chibon ae4136
        nullable=False)
Pierre-Yves Chibon ae4136
    content = sa.Column(
Pierre-Yves Chibon ae4136
        sa.Text(),
Pierre-Yves Chibon ae4136
        nullable=False)
Pierre-Yves Chibon ae4136
Pierre-Yves Chibon ae4136
    date_created = sa.Column(sa.DateTime, nullable=False,
Pierre-Yves Chibon ae4136
                             default=datetime.datetime.utcnow)