|
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)
|