Changeset - 72c525a7e7ad
rhodecode/__init__.py
Show inline comments
 
@@ -19,25 +19,25 @@
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import sys
 
import platform
 

	
 
VERSION = (1, 3, 0, 'beta')
 
__version__ = '.'.join((str(each) for each in VERSION[:4]))
 
__dbversion__ = 4  # defines current db version for migrations
 
__dbversion__ = 5  # defines current db version for migrations
 
__platform__ = platform.system()
 
__license__ = 'GPLv3'
 
__py_version__ = sys.version_info
 

	
 
PLATFORM_WIN = ('Windows')
 
PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
 

	
 
requirements = [
 
    "Pylons==1.0.0",
 
    "Beaker==1.6.2",
 
    "WebHelpers>=1.2",
 
    "formencode==1.2.4",
rhodecode/lib/auth.py
Show inline comments
 
@@ -217,26 +217,26 @@ def authenticate(username, password):
 
                (user_dn, ldap_attrs) = aldap.authenticate_ldap(username,
 
                                                                password)
 
                log.debug('Got ldap DN response %s' % user_dn)
 

	
 
                get_ldap_attr = lambda k: ldap_attrs.get(ldap_settings\
 
                                                           .get(k), [''])[0]
 

	
 
                user_attrs = {
 
                 'name': safe_unicode(get_ldap_attr('ldap_attr_firstname')),
 
                 'lastname': safe_unicode(get_ldap_attr('ldap_attr_lastname')),
 
                 'email': get_ldap_attr('ldap_attr_email'),
 
                }
 
                
 
                # don't store LDAP password since we don't need it. Override 
 

	
 
                # don't store LDAP password since we don't need it. Override
 
                # with some random generated password
 
                _password = PasswordGenerator().gen_password(length=8)
 
                # create this user on the fly if it doesn't exist in rhodecode
 
                # database
 
                if user_model.create_ldap(username, _password, user_dn,
 
                                          user_attrs):
 
                    log.info('created new ldap user %s' % username)
 

	
 
                Session.commit()
 
                return True
 
            except (LdapUsernameError, LdapPasswordError,):
 
                pass
rhodecode/lib/db_manage.py
Show inline comments
 
@@ -162,36 +162,39 @@ class DbManage(object):
 
                self.klass.fix_default_user()
 

	
 
                log.info('Changing ui settings')
 
                self.klass.create_ui_settings()
 

	
 
            def step_3(self):
 
                print ('Adding additional settings into RhodeCode db')
 
                self.klass.fix_settings()
 
                print ('Adding ldap defaults')
 
                self.klass.create_ldap_options(skip_existing=True)
 

	
 
            def step_4(self):
 
                print ('TODO:')
 
                print ('create permissions and fix groups')
 
                self.klass.create_permissions()
 
                self.klass.fixup_groups()
 

	
 
            def step_5(self):
 
                pass
 
            
 
        upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
 

	
 
        # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
 
        for step in upgrade_steps:
 
            print ('performing upgrade step %s' % step)
 
            getattr(UpgradeSteps(self), 'step_%s' % step)()
 
            self.sa.commit()
 
            
 

	
 
    def fix_repo_paths(self):
 
        """
 
        Fixes a old rhodecode version path into new one without a '*'
 
        """
 

	
 
        paths = self.sa.query(RhodeCodeUi)\
 
                .filter(RhodeCodeUi.ui_key == '/')\
 
                .scalar()
 

	
 
        paths.ui_value = paths.ui_value.replace('*', '')
 

	
 
        try:
rhodecode/lib/dbmigrate/migrate/changeset/ansisql.py
Show inline comments
 
@@ -8,41 +8,37 @@ import StringIO
 

	
 
import sqlalchemy as sa
 
from sqlalchemy.schema import SchemaVisitor
 
from sqlalchemy.engine.default import DefaultDialect
 
from sqlalchemy.sql import ClauseElement
 
from sqlalchemy.schema import (ForeignKeyConstraint,
 
                               PrimaryKeyConstraint,
 
                               CheckConstraint,
 
                               UniqueConstraint,
 
                               Index)
 

	
 
from rhodecode.lib.dbmigrate.migrate import exceptions
 
from rhodecode.lib.dbmigrate.migrate.changeset import constraint, SQLA_06
 
from rhodecode.lib.dbmigrate.migrate.changeset import constraint
 

	
 
if not SQLA_06:
 
    from sqlalchemy.sql.compiler import SchemaGenerator, SchemaDropper
 
else:
 
    from sqlalchemy.schema import AddConstraint, DropConstraint
 
    from sqlalchemy.sql.compiler import DDLCompiler
 
    SchemaGenerator = SchemaDropper = DDLCompiler
 
from sqlalchemy.schema import AddConstraint, DropConstraint
 
from sqlalchemy.sql.compiler import DDLCompiler
 
SchemaGenerator = SchemaDropper = DDLCompiler
 

	
 

	
 
class AlterTableVisitor(SchemaVisitor):
 
    """Common operations for ``ALTER TABLE`` statements."""
 

	
 
    if SQLA_06:
 
        # engine.Compiler looks for .statement
 
        # when it spawns off a new compiler
 
        statement = ClauseElement()
 
    # engine.Compiler looks for .statement
 
    # when it spawns off a new compiler
 
    statement = ClauseElement()
 

	
 
    def append(self, s):
 
        """Append content to the SchemaIterator's query buffer."""
 

	
 
        self.buffer.write(s)
 

	
 
    def execute(self):
 
        """Execute the contents of the SchemaIterator's buffer."""
 
        try:
 
            return self.connection.execute(self.buffer.getvalue())
 
        finally:
 
            self.buffer.truncate(0)
 
@@ -114,27 +110,26 @@ class ANSIColumnGenerator(AlterTableVisi
 
                                        name=column.unique_name).create()
 

	
 
        # SA bounds FK constraints to table, add manually
 
        for fk in column.foreign_keys:
 
            self.add_foreignkey(fk.constraint)
 

	
 
        # add primary key constraint if needed
 
        if column.primary_key_name:
 
            cons = constraint.PrimaryKeyConstraint(column,
 
                                                   name=column.primary_key_name)
 
            cons.create()
 

	
 
    if SQLA_06:
 
        def add_foreignkey(self, fk):
 
            self.connection.execute(AddConstraint(fk))
 
    def add_foreignkey(self, fk):
 
        self.connection.execute(AddConstraint(fk))
 

	
 
class ANSIColumnDropper(AlterTableVisitor, SchemaDropper):
 
    """Extends ANSI SQL dropper for column dropping (``ALTER TABLE
 
    DROP COLUMN``).
 
    """
 

	
 
    def visit_column(self, column):
 
        """Drop a column from its table.
 

	
 
        :param column: the column object
 
        :type column: :class:`sqlalchemy.Column`
 
        """
 
@@ -223,28 +218,25 @@ class ANSISchemaChanger(AlterTableVisito
 
        else:
 
            self.append("SET NOT NULL")
 

	
 
    def _visit_column_default(self, table, column, delta):
 
        default_text = self.get_column_default_string(column)
 
        if default_text is not None:
 
            self.append("SET DEFAULT %s" % default_text)
 
        else:
 
            self.append("DROP DEFAULT")
 

	
 
    def _visit_column_type(self, table, column, delta):
 
        type_ = delta['type']
 
        if SQLA_06:
 
            type_text = str(type_.compile(dialect=self.dialect))
 
        else:
 
            type_text = type_.dialect_impl(self.dialect).get_col_spec()
 
        type_text = str(type_.compile(dialect=self.dialect))
 
        self.append("TYPE %s" % type_text)
 

	
 
    def _visit_column_name(self, table, column, delta):
 
        self.start_alter_table(table)
 
        col_name = self.preparer.quote(delta.current_name, table.quote)
 
        new_name = self.preparer.format_column(delta.result_column)
 
        self.append('RENAME COLUMN %s TO %s' % (col_name, new_name))
 

	
 

	
 
class ANSIConstraintCommon(AlterTableVisitor):
 
    """
 
    Migrate's constraints require a separate creation function from
 
@@ -270,89 +262,31 @@ class ANSIConstraintCommon(AlterTableVis
 
    def visit_migrate_primary_key_constraint(self, *p, **k):
 
        self._visit_constraint(*p, **k)
 

	
 
    def visit_migrate_foreign_key_constraint(self, *p, **k):
 
        self._visit_constraint(*p, **k)
 

	
 
    def visit_migrate_check_constraint(self, *p, **k):
 
        self._visit_constraint(*p, **k)
 

	
 
    def visit_migrate_unique_constraint(self, *p, **k):
 
        self._visit_constraint(*p, **k)
 

	
 
if SQLA_06:
 
    class ANSIConstraintGenerator(ANSIConstraintCommon, SchemaGenerator):
 
        def _visit_constraint(self, constraint):
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append(self.process(AddConstraint(constraint)))
 
            self.execute()
 

	
 
    class ANSIConstraintDropper(ANSIConstraintCommon, SchemaDropper):
 
        def _visit_constraint(self, constraint):
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append(self.process(DropConstraint(constraint, cascade=constraint.cascade)))
 
            self.execute()
 

	
 
else:
 
    class ANSIConstraintGenerator(ANSIConstraintCommon, SchemaGenerator):
 

	
 
        def get_constraint_specification(self, cons, **kwargs):
 
            """Constaint SQL generators.
 

	
 
            We cannot use SA visitors because they append comma.
 
            """
 
class ANSIConstraintGenerator(ANSIConstraintCommon, SchemaGenerator):
 
    def _visit_constraint(self, constraint):
 
        constraint.name = self.get_constraint_name(constraint)
 
        self.append(self.process(AddConstraint(constraint)))
 
        self.execute()
 

	
 
            if isinstance(cons, PrimaryKeyConstraint):
 
                if cons.name is not None:
 
                    self.append("CONSTRAINT %s " % self.preparer.format_constraint(cons))
 
                self.append("PRIMARY KEY ")
 
                self.append("(%s)" % ', '.join(self.preparer.quote(c.name, c.quote)
 
                                               for c in cons))
 
                self.define_constraint_deferrability(cons)
 
            elif isinstance(cons, ForeignKeyConstraint):
 
                self.define_foreign_key(cons)
 
            elif isinstance(cons, CheckConstraint):
 
                if cons.name is not None:
 
                    self.append("CONSTRAINT %s " %
 
                                self.preparer.format_constraint(cons))
 
                self.append("CHECK (%s)" % cons.sqltext)
 
                self.define_constraint_deferrability(cons)
 
            elif isinstance(cons, UniqueConstraint):
 
                if cons.name is not None:
 
                    self.append("CONSTRAINT %s " %
 
                                self.preparer.format_constraint(cons))
 
                self.append("UNIQUE (%s)" % \
 
                    (', '.join(self.preparer.quote(c.name, c.quote) for c in cons)))
 
                self.define_constraint_deferrability(cons)
 
            else:
 
                raise exceptions.InvalidConstraintError(cons)
 

	
 
        def _visit_constraint(self, constraint):
 

	
 
            table = self.start_alter_table(constraint)
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append("ADD ")
 
            self.get_constraint_specification(constraint)
 
            self.execute()
 

	
 

	
 
    class ANSIConstraintDropper(ANSIConstraintCommon, SchemaDropper):
 

	
 
        def _visit_constraint(self, constraint):
 
            self.start_alter_table(constraint)
 
            self.append("DROP CONSTRAINT ")
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append(self.preparer.format_constraint(constraint))
 
            if constraint.cascade:
 
                self.cascade_constraint(constraint)
 
            self.execute()
 

	
 
        def cascade_constraint(self, constraint):
 
            self.append(" CASCADE")
 
class ANSIConstraintDropper(ANSIConstraintCommon, SchemaDropper):
 
    def _visit_constraint(self, constraint):
 
        constraint.name = self.get_constraint_name(constraint)
 
        self.append(self.process(DropConstraint(constraint, cascade=constraint.cascade)))
 
        self.execute()
 

	
 

	
 
class ANSIDialect(DefaultDialect):
 
    columngenerator = ANSIColumnGenerator
 
    columndropper = ANSIColumnDropper
 
    schemachanger = ANSISchemaChanger
 
    constraintgenerator = ANSIConstraintGenerator
 
    constraintdropper = ANSIConstraintDropper
rhodecode/lib/dbmigrate/migrate/changeset/constraint.py
Show inline comments
 
"""
 
   This module defines standalone schema constraint classes.
 
"""
 
from sqlalchemy import schema
 

	
 
from rhodecode.lib.dbmigrate.migrate.exceptions import *
 
from rhodecode.lib.dbmigrate.migrate.changeset import SQLA_06
 

	
 

	
 
class ConstraintChangeset(object):
 
    """Base class for Constraint classes."""
 

	
 
    def _normalize_columns(self, cols, table_name=False):
 
        """Given: column objects or names; return col names and
 
        (maybe) a table"""
 
        colnames = []
 
        table = None
 
        for col in cols:
 
            if isinstance(col, schema.Column):
 
                if col.table is not None and table is None:
 
@@ -76,25 +76,24 @@ class PrimaryKeyConstraint(ConstraintCha
 
    :type cols: strings or Column instances
 
    """
 

	
 
    __migrate_visit_name__ = 'migrate_primary_key_constraint'
 

	
 
    def __init__(self, *cols, **kwargs):
 
        colnames, table = self._normalize_columns(cols)
 
        table = kwargs.pop('table', table)
 
        super(PrimaryKeyConstraint, self).__init__(*colnames, **kwargs)
 
        if table is not None:
 
            self._set_parent(table)
 

	
 

	
 
    def autoname(self):
 
        """Mimic the database's automatic constraint names"""
 
        return "%s_pkey" % self.table.name
 

	
 

	
 
class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint):
 
    """Construct ForeignKeyConstraint
 

	
 
    Migrate's additional parameters:
 

	
 
    :param columns: Columns in constraint
 
    :param refcolumns: Columns that this FK reffers to in another table.
 
@@ -102,26 +101,27 @@ class ForeignKeyConstraint(ConstraintCha
 
    :type table: Table instance
 
    :type columns: list of strings or Column instances
 
    :type refcolumns: list of strings or Column instances
 
    """
 

	
 
    __migrate_visit_name__ = 'migrate_foreign_key_constraint'
 

	
 
    def __init__(self, columns, refcolumns, *args, **kwargs):
 
        colnames, table = self._normalize_columns(columns)
 
        table = kwargs.pop('table', table)
 
        refcolnames, reftable = self._normalize_columns(refcolumns,
 
                                                        table_name=True)
 
        super(ForeignKeyConstraint, self).__init__(colnames, refcolnames, *args,
 
                                                   **kwargs)
 
        super(ForeignKeyConstraint, self).__init__(
 
            colnames, refcolnames, *args,**kwargs
 
        )
 
        if table is not None:
 
            self._set_parent(table)
 

	
 
    @property
 
    def referenced(self):
 
        return [e.column for e in self.elements]
 

	
 
    @property
 
    def reftable(self):
 
        return self.referenced[0].table
 

	
 
    def autoname(self):
 
@@ -156,26 +156,24 @@ class CheckConstraint(ConstraintChangese
 

	
 
    __migrate_visit_name__ = 'migrate_check_constraint'
 

	
 
    def __init__(self, sqltext, *args, **kwargs):
 
        cols = kwargs.pop('columns', [])
 
        if not cols and not kwargs.get('name', False):
 
            raise InvalidConstraintError('You must either set "name"'
 
                'parameter or "columns" to autogenarate it.')
 
        colnames, table = self._normalize_columns(cols)
 
        table = kwargs.pop('table', table)
 
        schema.CheckConstraint.__init__(self, sqltext, *args, **kwargs)
 
        if table is not None:
 
            if not SQLA_06:
 
                self.table = table
 
            self._set_parent(table)
 
        self.colnames = colnames
 

	
 
    def autoname(self):
 
        return "%(table)s_%(cols)s_check" % \
 
            dict(table=self.table.name, cols="_".join(self.colnames))
 

	
 

	
 
class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint):
 
    """Construct UniqueConstraint
 

	
 
    Migrate's additional parameters:
 
@@ -190,13 +188,13 @@ class UniqueConstraint(ConstraintChanges
 

	
 
    __migrate_visit_name__ = 'migrate_unique_constraint'
 

	
 
    def __init__(self, *cols, **kwargs):
 
        self.colnames, table = self._normalize_columns(cols)
 
        table = kwargs.pop('table', table)
 
        super(UniqueConstraint, self).__init__(*self.colnames, **kwargs)
 
        if table is not None:
 
            self._set_parent(table)
 

	
 
    def autoname(self):
 
        """Mimic the database's automatic constraint names"""
 
        return "%s_%s_key" % (self.table.name, self.colnames[0])
 
        return "%s_%s_key" % (self.table.name, '_'.join(self.colnames))
rhodecode/lib/dbmigrate/migrate/changeset/databases/firebird.py
Show inline comments
 
"""
 
   Firebird database specific implementations of changeset classes.
 
"""
 
from sqlalchemy.databases import firebird as sa_base
 
from sqlalchemy.schema import PrimaryKeyConstraint
 
from rhodecode.lib.dbmigrate.migrate import exceptions
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql, SQLA_06
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql
 

	
 

	
 
if SQLA_06:
 
    FBSchemaGenerator = sa_base.FBDDLCompiler
 
else:
 
    FBSchemaGenerator = sa_base.FBSchemaGenerator
 
FBSchemaGenerator = sa_base.FBDDLCompiler
 

	
 
class FBColumnGenerator(FBSchemaGenerator, ansisql.ANSIColumnGenerator):
 
    """Firebird column generator implementation."""
 

	
 

	
 
class FBColumnDropper(ansisql.ANSIColumnDropper):
 
    """Firebird column dropper implementation."""
 

	
 
    def visit_column(self, column):
 
        """Firebird supports 'DROP col' instead of 'DROP COLUMN col' syntax
 

	
 
        Drop primary key and unique constraints if dropped column is referencing it."""
 
@@ -32,28 +29,25 @@ class FBColumnDropper(ansisql.ANSIColumn
 
            # "column in index.columns" causes problems as all
 
            # column objects compare equal and return a SQL expression
 
            if column.name in [col.name for col in index.columns]:
 
                index.drop()
 
                # TODO: recreate index if it references more than this column
 

	
 
        for cons in column.table.constraints:
 
            if isinstance(cons,PrimaryKeyConstraint):
 
                # will be deleted only when the column its on
 
                # is deleted!
 
                continue
 

	
 
            if SQLA_06:
 
                should_drop = column.name in cons.columns
 
            else:
 
                should_drop = cons.contains_column(column) and cons.name
 
            should_drop = column.name in cons.columns
 
            if should_drop:
 
                self.start_alter_table(column)
 
                self.append("DROP CONSTRAINT ")
 
                self.append(self.preparer.format_constraint(cons))
 
                self.execute()
 
            # TODO: recreate unique constraint if it refenrences more than this column
 

	
 
        self.start_alter_table(column)
 
        self.append('DROP %s' % self.preparer.format_column(column))
 
        self.execute()
 

	
 

	
rhodecode/lib/dbmigrate/migrate/changeset/databases/mysql.py
Show inline comments
 
"""
 
   MySQL database specific implementations of changeset classes.
 
"""
 

	
 
from sqlalchemy.databases import mysql as sa_base
 
from sqlalchemy import types as sqltypes
 

	
 
from rhodecode.lib.dbmigrate.migrate import exceptions
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql, SQLA_06
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql
 

	
 

	
 
if not SQLA_06:
 
    MySQLSchemaGenerator = sa_base.MySQLSchemaGenerator
 
else:
 
    MySQLSchemaGenerator = sa_base.MySQLDDLCompiler
 
MySQLSchemaGenerator = sa_base.MySQLDDLCompiler
 

	
 
class MySQLColumnGenerator(MySQLSchemaGenerator, ansisql.ANSIColumnGenerator):
 
    pass
 

	
 

	
 
class MySQLColumnDropper(ansisql.ANSIColumnDropper):
 
    pass
 

	
 

	
 
class MySQLSchemaChanger(MySQLSchemaGenerator, ansisql.ANSISchemaChanger):
 

	
 
    def visit_column(self, delta):
 
@@ -44,51 +41,25 @@ class MySQLSchemaChanger(MySQLSchemaGene
 
        self.append("CHANGE COLUMN %s " % old_col_name)
 
        self.append(colspec)
 
        self.execute()
 

	
 
    def visit_index(self, param):
 
        # If MySQL can do this, I can't find how
 
        raise exceptions.NotSupportedError("MySQL cannot rename indexes")
 

	
 

	
 
class MySQLConstraintGenerator(ansisql.ANSIConstraintGenerator):
 
    pass
 

	
 
if SQLA_06:
 
    class MySQLConstraintDropper(MySQLSchemaGenerator, ansisql.ANSIConstraintDropper):
 
        def visit_migrate_check_constraint(self, *p, **k):
 
            raise exceptions.NotSupportedError("MySQL does not support CHECK"
 
                " constraints, use triggers instead.")
 

	
 
else:
 
    class MySQLConstraintDropper(ansisql.ANSIConstraintDropper):
 

	
 
        def visit_migrate_primary_key_constraint(self, constraint):
 
            self.start_alter_table(constraint)
 
            self.append("DROP PRIMARY KEY")
 
            self.execute()
 

	
 
        def visit_migrate_foreign_key_constraint(self, constraint):
 
            self.start_alter_table(constraint)
 
            self.append("DROP FOREIGN KEY ")
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append(self.preparer.format_constraint(constraint))
 
            self.execute()
 

	
 
        def visit_migrate_check_constraint(self, *p, **k):
 
            raise exceptions.NotSupportedError("MySQL does not support CHECK"
 
                " constraints, use triggers instead.")
 

	
 
        def visit_migrate_unique_constraint(self, constraint, *p, **k):
 
            self.start_alter_table(constraint)
 
            self.append('DROP INDEX ')
 
            constraint.name = self.get_constraint_name(constraint)
 
            self.append(self.preparer.format_constraint(constraint))
 
            self.execute()
 
class MySQLConstraintDropper(MySQLSchemaGenerator, ansisql.ANSIConstraintDropper):
 
    def visit_migrate_check_constraint(self, *p, **k):
 
        raise exceptions.NotSupportedError("MySQL does not support CHECK"
 
            " constraints, use triggers instead.")
 

	
 

	
 
class MySQLDialect(ansisql.ANSIDialect):
 
    columngenerator = MySQLColumnGenerator
 
    columndropper = MySQLColumnDropper
 
    schemachanger = MySQLSchemaChanger
 
    constraintgenerator = MySQLConstraintGenerator
 
    constraintdropper = MySQLConstraintDropper
rhodecode/lib/dbmigrate/migrate/changeset/databases/postgres.py
Show inline comments
 
"""
 
   `PostgreSQL`_ database specific implementations of changeset classes.
 

	
 
   .. _`PostgreSQL`: http://www.postgresql.org/
 
"""
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql, SQLA_06
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql
 

	
 

	
 
if not SQLA_06:
 
    from sqlalchemy.databases import postgres as sa_base
 
    PGSchemaGenerator = sa_base.PGSchemaGenerator
 
else:
 
    from sqlalchemy.databases import postgresql as sa_base
 
    PGSchemaGenerator = sa_base.PGDDLCompiler
 
from sqlalchemy.databases import postgresql as sa_base
 
PGSchemaGenerator = sa_base.PGDDLCompiler
 

	
 

	
 
class PGColumnGenerator(PGSchemaGenerator, ansisql.ANSIColumnGenerator):
 
    """PostgreSQL column generator implementation."""
 
    pass
 

	
 

	
 
class PGColumnDropper(ansisql.ANSIColumnDropper):
 
    """PostgreSQL column dropper implementation."""
 
    pass
 

	
 

	
rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py
Show inline comments
 
@@ -2,29 +2,26 @@
 
   `SQLite`_ database specific implementations of changeset classes.
 

	
 
   .. _`SQLite`: http://www.sqlite.org/
 
"""
 
from UserDict import DictMixin
 
from copy import copy
 

	
 
from sqlalchemy.databases import sqlite as sa_base
 

	
 
from rhodecode.lib.dbmigrate.migrate import exceptions
 
from rhodecode.lib.dbmigrate.migrate.changeset import ansisql, SQLA_06
 

	
 
SQLiteSchemaGenerator = sa_base.SQLiteDDLCompiler
 

	
 
if not SQLA_06:
 
    SQLiteSchemaGenerator = sa_base.SQLiteSchemaGenerator
 
else:
 
    SQLiteSchemaGenerator = sa_base.SQLiteDDLCompiler
 

	
 
class SQLiteCommon(object):
 

	
 
    def _not_supported(self, op):
 
        raise exceptions.NotSupportedError("SQLite does not support "
 
            "%s; see http://www.sqlite.org/lang_altertable.html" % op)
 

	
 

	
 
class SQLiteHelper(SQLiteCommon):
 

	
 
    def recreate_table(self,table,column=None,delta=None):
 
        table_name = self.preparer.format_table(table)
rhodecode/lib/dbmigrate/migrate/changeset/schema.py
Show inline comments
 
@@ -340,46 +340,40 @@ class ColumnDelta(DictMixin, sqlalchemy.
 
            else:
 
                break
 

	
 
        if len(p):
 
            new_col = column.copy_fixed()
 
            new_col._init_items(*p)
 
            k = self.compare_2_columns(column, new_col, **k)
 
        return k
 

	
 
    def process_column(self, column):
 
        """Processes default values for column"""
 
        # XXX: this is a snippet from SA processing of positional parameters
 
        if not SQLA_06 and column.args:
 
            toinit = list(column.args)
 
        else:
 
            toinit = list()
 
        toinit = list()
 

	
 
        if column.server_default is not None:
 
            if isinstance(column.server_default, sqlalchemy.FetchedValue):
 
                toinit.append(column.server_default)
 
            else:
 
                toinit.append(sqlalchemy.DefaultClause(column.server_default))
 
        if column.server_onupdate is not None:
 
            if isinstance(column.server_onupdate, FetchedValue):
 
                toinit.append(column.server_default)
 
            else:
 
                toinit.append(sqlalchemy.DefaultClause(column.server_onupdate,
 
                                            for_update=True))
 
        if toinit:
 
            column._init_items(*toinit)
 

	
 
        if not SQLA_06:
 
            column.args = []
 

	
 
    def _get_table(self):
 
        return getattr(self, '_table', None)
 

	
 
    def _set_table(self, table):
 
        if isinstance(table, basestring):
 
            if self.alter_metadata:
 
                if not self.meta:
 
                    raise ValueError("metadata must be specified for table"
 
                        " reflection when using alter_metadata")
 
                meta = self.meta
 
                if self.engine:
 
                    meta.bind = self.engine
 
@@ -460,32 +454,36 @@ class ChangesetTable(object):
 
        """
 
        engine = self.bind
 
        self.new_name = name
 
        visitorcallable = get_engine_visitor(engine, 'schemachanger')
 
        run_single_visitor(engine, visitorcallable, self, connection, **kwargs)
 

	
 
        # Fix metadata registration
 
        self.name = name
 
        self.deregister()
 
        self._set_parent(self.metadata)
 

	
 
    def _meta_key(self):
 
        """Get the meta key for this table."""
 
        return sqlalchemy.schema._get_table_key(self.name, self.schema)
 

	
 
    def deregister(self):
 
        """Remove this table from its metadata"""
 
        key = self._meta_key()
 
        meta = self.metadata
 
        if key in meta.tables:
 
            del meta.tables[key]
 
        if SQLA_07:
 
            self.metadata._remove_table(self.name, self.schema)
 
        else:
 
            key = self._meta_key()
 
            meta = self.metadata
 
            if key in meta.tables:
 
                del meta.tables[key]
 

	
 

	
 
class ChangesetColumn(object):
 
    """Changeset extensions to SQLAlchemy columns."""
 

	
 
    def alter(self, *p, **k):
 
        """Makes a call to :func:`alter_column` for the column this
 
        method is called on.
 
        """
 
        if 'table' not in k:
 
            k['table'] = self.table
 
        if 'engine' not in k:
rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py
Show inline comments
 
@@ -30,25 +30,25 @@ def getDiffOfModelAgainstDatabase(metada
 
                      labelA='model',
 
                      labelB='database',
 
                      excludeTables=excludeTables)
 

	
 

	
 
def getDiffOfModelAgainstModel(metadataA, metadataB, excludeTables=None):
 
    """
 
    Return differences of model against another model.
 

	
 
    :return: object which will evaluate to :keyword:`True` if there \
 
      are differences else :keyword:`False`.
 
    """
 
    return SchemaDiff(metadataA, metadataB, excludeTables)
 
    return SchemaDiff(metadataA, metadataB, excludeTables=excludeTables)
 

	
 

	
 
class ColDiff(object):
 
    """
 
    Container for differences in one :class:`~sqlalchemy.schema.Column`
 
    between two :class:`~sqlalchemy.schema.Table` instances, ``A``
 
    and ``B``.
 

	
 
    .. attribute:: col_A
 

	
 
      The :class:`~sqlalchemy.schema.Column` object for A.
 

	
rhodecode/lib/dbmigrate/migrate/versioning/util/__init__.py
Show inline comments
 
@@ -149,26 +149,26 @@ def with_engine(f, *a, **kw):
 

	
 
    Engine is disposed after wrapped function is executed.
 

	
 
    .. versionadded: 0.6.0
 
    """
 
    url = a[0]
 
    engine = construct_engine(url, **kw)
 

	
 
    try:
 
        kw['engine'] = engine
 
        return f(*a, **kw)
 
    finally:
 
        if isinstance(engine, Engine):
 
            log.debug('Disposing SQLAlchemy engine %s' % engine)
 
        if isinstance(engine, Engine) and engine is not url:
 
            log.debug('Disposing SQLAlchemy engine %s', engine)
 
            engine.dispose()
 

	
 

	
 
class Memoize:
 
    """Memoize(fn) - an instance which acts like fn but memoizes its arguments
 
       Will only work on functions with non-mutable arguments
 

	
 
       ActiveState Code 52201
 
    """
 
    def __init__(self, fn):
 
        self.fn = fn
 
        self.memo = {}
rhodecode/lib/dbmigrate/schema/db_1_2_0.py
Show inline comments
 
@@ -918,24 +918,25 @@ class UsersGroupRepoToPerm(Base, BaseMod
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    users_group = relationship('UsersGroup')
 
    permission = relationship('Permission')
 
    repository = relationship('Repository')
 

	
 
    def __repr__(self):
 
        return '<userGroup:%s => %s >' % (self.users_group, self.repository)
 

	
 
class UsersGroupToPerm(Base, BaseModel):
 
    __tablename__ = 'users_group_to_perm'
 
    __table_args__ = {'extend_existing':True}
 
    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    users_group = relationship('UsersGroup')
 
    permission = relationship('Permission')
 

	
 

	
 
    @classmethod
 
    def has_perm(cls, users_group_id, perm):
 
        if not isinstance(perm, Permission):
 
            raise Exception('perm needs to be an instance of Permission class')
rhodecode/lib/dbmigrate/schema/db_1_3_0.py
Show inline comments
 
@@ -13,12 +13,16 @@
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
#TODO: when branch 1.3 is finished replacem with db.py content
 

	
 
from rhodecode.model.db import *
rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py
Show inline comments
 
@@ -3,24 +3,25 @@ import datetime
 

	
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper
 
from sqlalchemy.orm.session import Session
 
from rhodecode.model.meta import Base
 

	
 
from rhodecode.lib.dbmigrate.migrate import *
 
from rhodecode.lib.dbmigrate.migrate.changeset import *
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """ Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 

	
 
    #==========================================================================
 
    # Upgrade of `users` table
 
    #==========================================================================
 
    tblname = 'users'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
@@ -35,26 +36,24 @@ def upgrade(migrate_engine):
 
    #==========================================================================
 

	
 
    tblname = 'users'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
    #ADD revision column
 
    revision = Column('revision', TEXT(length=None, convert_unicode=False,
 
                                       assert_unicode=None),
 
                      nullable=True, unique=None, default=None)
 
    revision.create(tbl)
 

	
 

	
 

	
 
    #==========================================================================
 
    # Upgrade of `repositories` table
 
    #==========================================================================
 
    tblname = 'repositories'
 
    tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 

	
 
    #ADD repo_type column#
 
    repo_type = Column("repo_type", String(length=None, convert_unicode=False,
 
                                           assert_unicode=None),
 
                       nullable=True, unique=False, default='hg')
 

	
 
@@ -71,15 +70,16 @@ def upgrade(migrate_engine):
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_1_0 import UserFollowing
 
    UserFollowing().__table__.create()
 

	
 
    #==========================================================================
 
    # Add table `cache_invalidation`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_1_0 import CacheInvalidation
 
    CacheInvalidation().__table__.create()
 

	
 
    return
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
rhodecode/lib/dbmigrate/versions/003_version_1_2_0.py
Show inline comments
 
@@ -4,24 +4,25 @@ import datetime
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper
 
from sqlalchemy.orm.session import Session
 

	
 
from rhodecode.lib.dbmigrate.migrate import *
 
from rhodecode.lib.dbmigrate.migrate.changeset import *
 

	
 
from rhodecode.model.meta import Base
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """ Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 

	
 
    #==========================================================================
 
    # Add table `groups``
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_2_0 import RepoGroup as Group
 
    Group().__table__.create()
 

	
 
    #==========================================================================
rhodecode/lib/dbmigrate/versions/004_version_1_3_0.py
Show inline comments
 
@@ -4,25 +4,71 @@ import datetime
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper
 
from sqlalchemy.orm.session import Session
 

	
 
from rhodecode.lib.dbmigrate.migrate import *
 
from rhodecode.lib.dbmigrate.migrate.changeset import *
 

	
 
from rhodecode.model.meta import Base
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """ Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 
    #==========================================================================
 
    # Add table `users_group_repo_group_to_perm`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UsersGroupRepoGroupToPerm
 
    UsersGroupRepoGroupToPerm().__table__.create()
 

	
 
    #==========================================================================
 
    # Add table `changeset_comments`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import  ChangesetComment
 
    ChangesetComment().__table__.create()
 

	
 
    #==========================================================================
 
    # Add table `notifications`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import  Notification
 
    Notification().__table__.create()
 

	
 
    #==========================================================================
 
    # Add table `user_to_notification`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import  UserNotification
 
    UserNotification().__table__.create()
 

	
 
    #==========================================================================
 
    # Add unique to table `users_group_to_perm`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UsersGroupToPerm
 
    tbl = UsersGroupToPerm().__table__
 
    cons = UniqueConstraint('users_group_id', 'permission_id', table=tbl)
 
    cons.create()
 

	
 
    #==========================================================================
 
    # Fix unique constrain on table `user_logs`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserLog
 
    tbl = UserLog().__table__
 
    col = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'),
 
                 nullable=False, unique=None, default=None)
 
    col.alter(nullable=True, table=tbl)
 

	
 
    #==========================================================================
 
    # Rename table `group_to_perm` to `user_repo_group_to_perm`
 
    #==========================================================================
 
    tbl = Table('group_to_perm', MetaData(bind=migrate_engine), autoload=True,
 
                    autoload_with=migrate_engine)
 
    tbl.rename('user_repo_group_to_perm')
 

	
 
    return
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
rhodecode/lib/dbmigrate/versions/005_version_1_3_0.py
Show inline comments
 
new file 100644
 
import logging
 
import datetime
 

	
 
from sqlalchemy import *
 
from sqlalchemy.exc import DatabaseError
 
from sqlalchemy.orm import relation, backref, class_mapper
 
from sqlalchemy.orm.session import Session
 

	
 
from rhodecode.lib.dbmigrate.migrate import *
 
from rhodecode.lib.dbmigrate.migrate.changeset import *
 

	
 
from rhodecode.model.meta import Base
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def upgrade(migrate_engine):
 
    """ Upgrade operations go here.
 
    Don't create your own engine; bind migrate_engine to your metadata
 
    """
 

	
 
    #==========================================================================
 
    # Change unique constraints of table `repo_to_perm`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserRepoToPerm
 
    tbl = UserRepoToPerm().__table__
 
    new_cons = UniqueConstraint('user_id', 'repository_id', 'permission_id', table=tbl)
 
    new_cons.create()
 

	
 
    if migrate_engine.name in ['mysql']:
 
        old_cons = UniqueConstraint('user_id', 'repository_id', table=tbl, name="user_id")
 
        old_cons.drop()
 
    elif migrate_engine.name in ['postgresql']:
 
        old_cons = UniqueConstraint('user_id', 'repository_id', table=tbl)
 
        old_cons.drop()
 
    else:
 
        # sqlite doesn't support dropping constraints...
 
        print """Please manually drop UniqueConstraint('user_id', 'repository_id')"""
 

	
 
    #==========================================================================
 
    # fix uniques of table `user_repo_group_to_perm`
 
    #==========================================================================
 
    from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserRepoGroupToPerm
 
    tbl = UserRepoGroupToPerm().__table__
 
    new_cons = UniqueConstraint('group_id', 'permission_id', 'user_id', table=tbl)
 
    new_cons.create()
 

	
 
    # fix uniqueConstraints
 
    if migrate_engine.name in ['mysql']:
 
        #mysql is givinig troubles here...
 
        old_cons = UniqueConstraint('group_id', 'permission_id', table=tbl, name="group_id")
 
        old_cons.drop()
 
    elif migrate_engine.name in ['postgresql']:
 
        old_cons = UniqueConstraint('group_id', 'permission_id', table=tbl, name='group_to_perm_group_id_permission_id_key')
 
        old_cons.drop()
 
    else:
 
        # sqlite doesn't support dropping constraints...
 
        print """Please manually drop UniqueConstraint('group_id', 'permission_id')"""
 

	
 
    return
 

	
 

	
 
def downgrade(migrate_engine):
 
    meta = MetaData()
 
    meta.bind = migrate_engine
rhodecode/model/db.py
Show inline comments
 
@@ -31,30 +31,30 @@ from collections import defaultdict
 

	
 
from sqlalchemy import *
 
from sqlalchemy.ext.hybrid import hybrid_property
 
from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
 
from beaker.cache import cache_region, region_invalidate
 

	
 
from vcs import get_backend
 
from vcs.utils.helpers import get_scm
 
from vcs.exceptions import VCSError
 
from vcs.utils.lazy import LazyProperty
 

	
 
from rhodecode.lib import str2bool, safe_str, get_changeset_safe, safe_unicode
 
from rhodecode.lib.exceptions import UsersGroupsAssignedException
 
from rhodecode.lib.compat import json
 
from rhodecode.lib.caching_query import FromCache
 

	
 
from rhodecode.model.meta import Base, Session
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
#==============================================================================
 
# BASE CLASSES
 
#==============================================================================
 

	
 

	
 
class ModelSerializer(json.JSONEncoder):
 
    """
 
    Simple Serializer for JSON,
 

	
 
    usage::
 
@@ -673,24 +673,25 @@ class Repository(Base, BaseModel):
 
        try:
 
            alias = get_scm(repo_full_path)[0]
 
            log.debug('Creating instance of %s repository' % alias)
 
            backend = get_backend(alias)
 
        except VCSError:
 
            log.error(traceback.format_exc())
 
            log.error('Perhaps this repository is in db and not in '
 
                      'filesystem run rescan repositories with '
 
                      '"destroy old data " option from admin panel')
 
            return
 

	
 
        if alias == 'hg':
 

	
 
            repo = backend(safe_str(repo_full_path), create=False,
 
                           baseui=self._ui)
 
            # skip hidden web repository
 
            if repo._get_hidden():
 
                return
 
        else:
 
            repo = backend(repo_full_path, create=False)
 

	
 
        return repo
 

	
 

	
 
class RepoGroup(Base, BaseModel):
 
@@ -847,35 +848,35 @@ class Permission(Base, BaseModel):
 
    def get_default_group_perms(cls, default_user_id):
 
        q = Session.query(UserRepoGroupToPerm, RepoGroup, cls)\
 
         .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
 
         .join((cls, UserRepoGroupToPerm.permission_id == cls.permission_id))\
 
         .filter(UserRepoGroupToPerm.user_id == default_user_id)
 

	
 
        return q.all()
 

	
 

	
 
class UserRepoToPerm(Base, BaseModel):
 
    __tablename__ = 'repo_to_perm'
 
    __table_args__ = (
 
        UniqueConstraint('user_id', 'repository_id'),
 
        UniqueConstraint('user_id', 'repository_id', 'permission_id'),
 
        {'extend_existing': True}
 
    )
 
    repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relationship('User')
 
    repository = relationship('Repository')
 
    permission = relationship('Permission')
 
    repository = relationship('Repository')
 

	
 
    @classmethod
 
    def create(cls, user, repository, permission):
 
        n = cls()
 
        n.user = user
 
        n.repository = repository
 
        n.permission = permission
 
        Session.add(n)
 
        return n
 

	
 
    def __repr__(self):
 
        return '<user:%s => %s >' % (self.user, self.repository)
 
@@ -889,25 +890,25 @@ class UserToPerm(Base, BaseModel):
 
    )
 
    user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relationship('User')
 
    permission = relationship('Permission', lazy='joined')
 

	
 

	
 
class UsersGroupRepoToPerm(Base, BaseModel):
 
    __tablename__ = 'users_group_repo_to_perm'
 
    __table_args__ = (
 
        UniqueConstraint('repository_id', 'users_group_id',),
 
        UniqueConstraint('repository_id', 'users_group_id', 'permission_id'),
 
        {'extend_existing': True}
 
    )
 
    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    users_group = relationship('UsersGroup')
 
    permission = relationship('Permission')
 
    repository = relationship('Repository')
 

	
 
    @classmethod
 
@@ -931,36 +932,36 @@ class UsersGroupToPerm(Base, BaseModel):
 
    )
 
    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    users_group = relationship('UsersGroup')
 
    permission = relationship('Permission')
 

	
 

	
 
class UserRepoGroupToPerm(Base, BaseModel):
 
    __tablename__ = 'user_repo_group_to_perm'
 
    __table_args__ = (
 
        UniqueConstraint('user_id', 'group_id'),
 
        UniqueConstraint('user_id', 'group_id', 'permission_id'),
 
        {'extend_existing': True}
 
    )
 

	
 
    group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relationship('User')
 
    group = relationship('RepoGroup')
 
    permission = relationship('Permission')
 
    group = relationship('RepoGroup')
 

	
 

	
 
class UsersGroupRepoGroupToPerm(Base, BaseModel):
 
    __tablename__ = 'users_group_repo_group_to_perm'
 
    __table_args__ = (
 
        UniqueConstraint('users_group_id', 'group_id'),
 
        {'extend_existing': True}
 
    )
 

	
 
    users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
0 comments (0 inline, 0 general)